@@ -2,9 +2,10 @@ use sea_orm::{ActiveValue::Set, ConnectionTrait, DbErr, EntityTrait};
22use sea_query:: OnConflict ;
33use spdx_expression:: SpdxExpression ;
44use std:: collections:: BTreeMap ;
5+ // use test_context::futures::StreamExt;
56use tracing:: instrument;
67use trustify_common:: db:: chunk:: EntityChunkedIter ;
7- use trustify_entity:: license;
8+ use trustify_entity:: { license, licensing_infos } ;
89use uuid:: Uuid ;
910
1011const NAMESPACE : Uuid = Uuid :: from_bytes ( [
@@ -22,7 +23,7 @@ impl LicenseInfo {
2223 Uuid :: new_v5 ( & NAMESPACE , self . license . to_lowercase ( ) . as_bytes ( ) )
2324 }
2425
25- pub fn spdx_info ( & self ) -> ( Vec < String > , Vec < String > ) {
26+ pub fn spdx_info ( & self ) -> ( Vec < String > , Vec < String > , Vec < String > ) {
2627 SpdxExpression :: parse ( & self . license )
2728 . map ( |parsed| {
2829 let spdx_licenses = parsed
@@ -38,9 +39,16 @@ impl LicenseInfo {
3839 . map ( |e| e. to_string ( ) )
3940 . collect :: < Vec < _ > > ( ) ;
4041
41- ( spdx_licenses, spdx_license_exceptions)
42+ let custom_license_refs = parsed
43+ . licenses ( )
44+ . iter ( )
45+ . filter ( |e| e. license_ref )
46+ . map ( |e| format ! ( "LicenseRef-{}" , e. identifier) )
47+ . collect :: < Vec < _ > > ( ) ;
48+
49+ ( spdx_licenses, spdx_license_exceptions, custom_license_refs)
4250 } )
43- . unwrap_or ( ( vec ! [ ] , vec ! [ ] ) )
51+ . unwrap_or ( ( vec ! [ ] , vec ! [ ] , vec ! [ ] ) )
4452 }
4553}
4654
@@ -51,19 +59,50 @@ pub struct LicenseCreator {
5159 /// Uses a [`BTreeMap`] to ensure we have a stable insertion order, avoiding deadlocks on the
5260 /// database.
5361 pub licenses : BTreeMap < Uuid , license:: ActiveModel > ,
62+
63+ pub custom_license_list : Vec < licensing_infos:: ActiveModel > ,
5464}
5565
5666impl LicenseCreator {
5767 pub fn new ( ) -> Self {
5868 Self {
5969 licenses : Default :: default ( ) ,
70+ custom_license_list : vec ! [ ] ,
6071 }
6172 }
6273
74+ pub fn put_custom_license_list (
75+ & mut self ,
76+ custom_license_list : Vec < licensing_infos:: ActiveModel > ,
77+ ) {
78+ self . custom_license_list = custom_license_list;
79+ }
80+
6381 pub fn add ( & mut self , info : & LicenseInfo ) {
6482 let uuid = info. uuid ( ) ;
6583
66- let ( spdx_licenses, spdx_exceptions) = info. spdx_info ( ) ;
84+ let ( spdx_licenses, spdx_exceptions, custom_license_refs) = info. spdx_info ( ) ;
85+ let missing_custom_refs: Vec < _ > = custom_license_refs
86+ . iter ( )
87+ . filter ( |ref_id| {
88+ !self
89+ . custom_license_list
90+ . iter ( )
91+ . any ( |c| c. license_id == Set ( ( * ref_id) . to_string ( ) ) )
92+ } )
93+ . cloned ( )
94+ . collect ( ) ;
95+ if !missing_custom_refs. is_empty ( ) {
96+ log:: warn!(
97+ "The following custom license refs are missing from custom_license_list: {:?}" ,
98+ missing_custom_refs
99+ ) ;
100+ }
101+ let custom_license_refs_value = if custom_license_refs. is_empty ( ) {
102+ None
103+ } else {
104+ Some ( self . construct_custom_license ( custom_license_refs. clone ( ) ) )
105+ } ;
67106
68107 self . licenses . entry ( uuid) . or_insert ( license:: ActiveModel {
69108 id : Set ( uuid) ,
@@ -78,9 +117,30 @@ impl LicenseCreator {
78117 } else {
79118 Set ( Some ( spdx_exceptions) )
80119 } ,
120+ custom_license_refs : Set ( custom_license_refs_value) ,
81121 } ) ;
82122 }
83123
124+ fn construct_custom_license ( & self , custom_license_ids : Vec < String > ) -> Vec < String > {
125+ use std:: collections:: HashMap ;
126+ // Build a HashMap from license_id to name for fast lookup
127+ let license_map: HashMap < & String , & String > = self
128+ . custom_license_list
129+ . iter ( )
130+ . filter_map ( |c| {
131+ if let ( Set ( license_id) , Set ( name) ) = ( & c. license_id , & c. name ) {
132+ Some ( ( license_id, name) )
133+ } else {
134+ None
135+ }
136+ } )
137+ . collect ( ) ;
138+ custom_license_ids
139+ . into_iter ( )
140+ . filter_map ( |id| license_map. get ( & id) . map ( |name| format ! ( "{}:{}" , id, name) ) )
141+ . collect ( )
142+ }
143+
84144 #[ instrument( skip_all, fields( num = self . licenses. len( ) ) , err( level=tracing:: Level :: INFO ) ) ]
85145 pub async fn create < C > ( self , db : & C ) -> Result < ( ) , DbErr >
86146 where
0 commit comments