Skip to content

Commit ed6b409

Browse files
committed
Fix: Modify the related issues based on the suggestions.
1 parent c2f7976 commit ed6b409

File tree

5 files changed

+102
-92
lines changed

5 files changed

+102
-92
lines changed

modules/fundamental/tests/sbom/license.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
use flate2::read::GzDecoder;
2-
use sea_orm::{ColumnTrait, QuerySelect, EntityTrait, QueryFilter};
2+
use sea_orm::{ColumnTrait, EntityTrait, QueryFilter, QuerySelect};
33

44
use sea_query::Cond;
55
use serde_json::{Value, json};
66
use std::io::Read;
77
use tar::Archive;
88
use test_context::test_context;
99
use test_log::test;
10-
use trustify_entity::{sbom_package_license::LicenseCategory, license, sbom_package, sbom_package_license};
10+
use trustify_entity::{
11+
license, sbom_package, sbom_package_license, sbom_package_license::LicenseCategory,
12+
};
1113
use trustify_module_fundamental::license::{
1214
model::sbom_license::SbomNameId,
1315
service::{LicenseService, license_export::LicenseExporter},

modules/ingestor/src/graph/sbom/common/license.rs

Lines changed: 93 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,15 @@ const NAMESPACE: Uuid = Uuid::from_bytes([
1111
0xde, 0xad, 0xbe, 0xef, 0xca, 0xfe, 0x41, 0x18, 0xa1, 0x38, 0xb8, 0x9f, 0x19, 0x35, 0xe0, 0xa7,
1212
]);
1313

14+
/// SPDX license information extracted from an SPDX expression
15+
#[derive(Debug, Clone, PartialEq, Eq)]
16+
pub struct SPDXInfo {
17+
pub spdx_licenses: Vec<String>,
18+
pub spdx_license_exceptions: Vec<String>,
19+
pub custom_license_refs: Vec<String>,
20+
pub custom_document_license_refs: Vec<String>,
21+
}
22+
1423
#[derive(Default, Debug, Clone, PartialEq, Eq)]
1524
pub struct LicenseInfo {
1625
pub license: String,
@@ -22,7 +31,7 @@ impl LicenseInfo {
2231
Uuid::new_v5(&NAMESPACE, self.license.to_lowercase().as_bytes())
2332
}
2433

25-
pub fn spdx_info(&self) -> (Vec<String>, Vec<String>, Vec<String>, Vec<String>) {
34+
pub fn spdx_info(&self) -> SPDXInfo {
2635
SpdxExpression::parse(&self.license)
2736
.map(|parsed| {
2837
let spdx_licenses = parsed
@@ -53,23 +62,65 @@ impl LicenseInfo {
5362
.licenses()
5463
.iter()
5564
.filter(|e| e.license_ref && e.document_ref.is_some())
56-
.map(|e| {
57-
if let Some(doc_ref) = &e.document_ref {
65+
.filter_map(|e| {
66+
e.document_ref.as_ref().map(|doc_ref| {
5867
format!("DocumentRef-{}:LicenseRef-{}", doc_ref, e.identifier)
59-
} else {
60-
String::default()
61-
}
68+
})
6269
})
6370
.collect::<Vec<_>>();
6471

65-
(
72+
SPDXInfo {
6673
spdx_licenses,
6774
spdx_license_exceptions,
6875
custom_license_refs,
6976
custom_document_license_refs,
70-
)
77+
}
78+
})
79+
.unwrap_or(SPDXInfo {
80+
spdx_licenses: vec![],
81+
spdx_license_exceptions: vec![],
82+
custom_license_refs: vec![],
83+
custom_document_license_refs: vec![],
7184
})
72-
.unwrap_or((vec![], vec![], vec![], vec![]))
85+
}
86+
}
87+
88+
pub struct LicenseBuilder {
89+
pub license_info: LicenseInfo,
90+
}
91+
92+
impl LicenseBuilder {
93+
pub fn new(license_info: LicenseInfo) -> Self {
94+
Self { license_info }
95+
}
96+
97+
pub fn to_active_model(&self) -> license::ActiveModel {
98+
let spdx_info = self.license_info.spdx_info();
99+
100+
license::ActiveModel {
101+
id: Set(self.license_info.uuid()),
102+
text: Set(self.license_info.license.clone()),
103+
spdx_licenses: if spdx_info.spdx_licenses.is_empty() {
104+
Set(None)
105+
} else {
106+
Set(Some(spdx_info.spdx_licenses))
107+
},
108+
spdx_license_exceptions: if spdx_info.spdx_license_exceptions.is_empty() {
109+
Set(None)
110+
} else {
111+
Set(Some(spdx_info.spdx_license_exceptions))
112+
},
113+
custom_license_refs: if spdx_info.custom_license_refs.is_empty() {
114+
Set(None)
115+
} else {
116+
Set(Some(spdx_info.custom_license_refs))
117+
},
118+
custom_document_license_refs: if spdx_info.custom_document_license_refs.is_empty() {
119+
Set(None)
120+
} else {
121+
Set(Some(spdx_info.custom_document_license_refs))
122+
},
123+
}
73124
}
74125
}
75126

@@ -81,37 +132,42 @@ pub struct LicenseCreator {
81132
/// database.
82133
pub licenses: BTreeMap<Uuid, license::ActiveModel>,
83134

84-
pub custom_license_list: Vec<licensing_infos::ActiveModel>,
135+
/// Custom license lookup map: license_id -> name
136+
custom_license_map: std::collections::HashMap<String, String>,
85137
}
86138

87139
impl LicenseCreator {
88140
pub fn new() -> Self {
89141
Self {
90142
licenses: Default::default(),
91-
custom_license_list: vec![],
143+
custom_license_map: std::collections::HashMap::new(),
92144
}
93145
}
94146

95147
pub fn put_custom_license_list(
96148
&mut self,
97-
custom_license_list: Vec<licensing_infos::ActiveModel>,
149+
custom_license_list: &[licensing_infos::ActiveModel],
98150
) {
99-
self.custom_license_list = custom_license_list;
151+
self.custom_license_map = custom_license_list
152+
.iter()
153+
.filter_map(|c| {
154+
if let (Set(license_id), Set(name)) = (&c.license_id, &c.name) {
155+
Some((license_id.clone(), name.clone()))
156+
} else {
157+
None
158+
}
159+
})
160+
.collect();
100161
}
101162

102163
pub fn add(&mut self, info: &LicenseInfo) {
103164
let uuid = info.uuid();
104165

105-
let (spdx_licenses, spdx_exceptions, custom_license_refs, custom_document_license_refs) =
106-
info.spdx_info();
107-
let missing_custom_refs: Vec<_> = custom_license_refs
166+
let spdx_info = info.spdx_info();
167+
let missing_custom_refs: Vec<_> = spdx_info
168+
.custom_license_refs
108169
.iter()
109-
.filter(|ref_id| {
110-
!self
111-
.custom_license_list
112-
.iter()
113-
.any(|c| c.license_id == Set((*ref_id).to_string()))
114-
})
170+
.filter(|ref_id| !self.custom_license_map.contains_key(*ref_id))
115171
.cloned()
116172
.collect();
117173
if !missing_custom_refs.is_empty() {
@@ -120,51 +176,30 @@ impl LicenseCreator {
120176
missing_custom_refs
121177
);
122178
}
123-
let custom_license_refs_value = if custom_license_refs.is_empty() {
179+
let custom_license_refs_value = if spdx_info.custom_license_refs.is_empty() {
124180
None
125181
} else {
126-
Some(self.construct_custom_license(custom_license_refs.clone()))
182+
Some(self.construct_custom_license(spdx_info.custom_license_refs.clone()))
127183
};
128184

129-
self.licenses.entry(uuid).or_insert(license::ActiveModel {
130-
id: Set(uuid),
131-
text: Set(info.license.clone()),
132-
spdx_licenses: if spdx_licenses.is_empty() {
133-
Set(None)
134-
} else {
135-
Set(Some(spdx_licenses))
136-
},
137-
spdx_license_exceptions: if spdx_exceptions.is_empty() {
138-
Set(None)
139-
} else {
140-
Set(Some(spdx_exceptions))
141-
},
142-
custom_license_refs: Set(custom_license_refs_value),
143-
custom_document_license_refs: if custom_document_license_refs.is_empty() {
144-
Set(None)
145-
} else {
146-
Set(Some(custom_document_license_refs))
147-
},
148-
});
185+
let mut active_model = LicenseBuilder::new(info.clone()).to_active_model();
186+
187+
// Update custom_license_refs with constructed value
188+
if let Some(refs) = custom_license_refs_value {
189+
active_model.custom_license_refs = Set(Some(refs));
190+
}
191+
192+
self.licenses.entry(uuid).or_insert(active_model);
149193
}
150194

151195
fn construct_custom_license(&self, custom_license_ids: Vec<String>) -> Vec<String> {
152-
use std::collections::HashMap;
153-
// Build a HashMap from license_id to name for fast lookup
154-
let license_map: HashMap<&String, &String> = self
155-
.custom_license_list
156-
.iter()
157-
.filter_map(|c| {
158-
if let (Set(license_id), Set(name)) = (&c.license_id, &c.name) {
159-
Some((license_id, name))
160-
} else {
161-
None
162-
}
163-
})
164-
.collect();
165196
custom_license_ids
166197
.into_iter()
167-
.filter_map(|id| license_map.get(&id).map(|name| format!("{}:{}", id, name)))
198+
.filter_map(|id| {
199+
self.custom_license_map
200+
.get(&id)
201+
.map(|name| format!("{}:{}", id, name))
202+
})
168203
.collect()
169204
}
170205

modules/ingestor/src/graph/sbom/common/licensing_info.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,8 @@ impl LicensingInfoCreator {
6363
});
6464
}
6565

66-
pub fn get_copy_license_refs(&self) -> Vec<licensing_infos::ActiveModel> {
67-
self.license_refs.clone()
66+
pub fn get_copy_license_refs(&self) -> &[licensing_infos::ActiveModel] {
67+
&self.license_refs
6868
}
6969

7070
#[instrument(skip_all, fields(num = self.license_refs.len()), err)]

modules/ingestor/src/graph/sbom/mod.rs

Lines changed: 2 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -424,8 +424,7 @@ impl SbomContext {
424424
license: license.to_string(),
425425
};
426426

427-
let (spdx_licenses, spdx_exceptions, custom_license_refs, custom_document_license_refs) =
428-
license_info.spdx_info();
427+
let active_model = LicenseBuilder::new(license_info.clone()).to_active_model();
429428

430429
let license = license::Entity::find_by_id(license_info.uuid())
431430
.one(connection)
@@ -434,33 +433,7 @@ impl SbomContext {
434433
let license = if let Some(license) = license {
435434
license
436435
} else {
437-
license::ActiveModel {
438-
id: Set(license_info.uuid()),
439-
text: Set(license_info.license.clone()),
440-
spdx_licenses: if spdx_licenses.is_empty() {
441-
Set(None)
442-
} else {
443-
Set(Some(spdx_licenses))
444-
},
445-
spdx_license_exceptions: if spdx_exceptions.is_empty() {
446-
Set(None)
447-
} else {
448-
Set(Some(spdx_exceptions))
449-
},
450-
custom_license_refs: if custom_license_refs.is_empty() {
451-
Set(None)
452-
} else {
453-
Set(Some(custom_license_refs))
454-
},
455-
456-
custom_document_license_refs: if custom_document_license_refs.is_empty() {
457-
Set(None)
458-
} else {
459-
Set(Some(custom_document_license_refs))
460-
},
461-
}
462-
.insert(connection)
463-
.await?
436+
active_model.insert(connection).await?
464437
};
465438

466439
sbom_package_license::ActiveModel {

modules/ingestor/src/graph/sbom/spdx.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ impl SbomContext {
198198
license_extracted_refs.add(extracted_licensing_info);
199199
}
200200

201-
licenses.put_custom_license_list(license_extracted_refs.get_copy_license_refs());
201+
licenses.put_custom_license_list(&license_extracted_refs.get_copy_license_refs());
202202

203203
let mut packages =
204204
PackageCreator::with_capacity(self.sbom.sbom_id, sbom_data.package_information.len());

0 commit comments

Comments
 (0)