@@ -9,9 +9,10 @@ import 'dart:io';
9
9
import 'package:archive/archive.dart' ;
10
10
import 'package:path/path.dart' as path;
11
11
12
- import '../../service/domain/item_id .dart' ;
12
+ import '../../service/domain/bom_item .dart' ;
13
13
import '../../service/domain/scan_result.dart' ;
14
14
import '../../service/domain/spdx_mapper.dart' ;
15
+ import '../../service/purl.dart' ;
15
16
import '../persistence_exception.dart' ;
16
17
import '../result_parser.dart' ;
17
18
import 'csv_parser.dart' ;
@@ -103,17 +104,18 @@ class BlackDuckResultParser implements ResultParser {
103
104
stream.transform (utf8.decoder).transform (LineSplitter ());
104
105
}
105
106
106
- /// Dictionary to lookup licenses per [ItemId ] .
107
+ /// Dictionary to lookup licenses per [BomItem ] .
107
108
class _LicenseDictionary {
108
- final _dict = < ItemId , Set <String >> {};
109
+ /// Version id -> Licenses
110
+ final _dict = < String , Set <String >> {};
109
111
110
- void addLicenses (ItemId id , Iterable <String > values) {
111
- final licenses = _dict[id ] ?? {};
112
+ void addLicenses (String versionId , Iterable <String > values) {
113
+ final licenses = _dict[versionId ] ?? {};
112
114
licenses.addAll (values);
113
- _dict[id ] = licenses;
115
+ _dict[versionId ] = licenses;
114
116
}
115
117
116
- Set <String >? operator [](ItemId id ) => _dict[id ];
118
+ Set <String >? operator [](String versionId ) => _dict[versionId ];
117
119
}
118
120
119
121
/// Extracts license info per component from the Black Duck components CSV file.
@@ -122,40 +124,37 @@ class _BlackDuckComponentsCsvParser extends CsvParser {
122
124
final _LicenseDictionary _dictionary;
123
125
final SpdxMapper mapper;
124
126
125
- var _componentNameIndex = - 1 ;
126
- var _componentVersionIndex = - 1 ;
127
- var _licensesIndex = - 1 ;
127
+ late final int _licensesIndex;
128
+ late final int _componentVersionIdIndex;
128
129
129
130
_BlackDuckComponentsCsvParser (this ._dictionary, this .mapper);
130
131
131
132
@override
132
133
void headerRow (List <String > columns) {
133
- _componentNameIndex = columnIndexOf ('Component name' , columns);
134
- _componentVersionIndex = columnIndexOf ('Component version name' , columns);
135
134
_licensesIndex = columnIndexOf ('License names' , columns);
135
+ _componentVersionIdIndex = columnIndexOf ('Version id' , columns);
136
136
}
137
137
138
138
@override
139
139
void dataRow (List <String > columns) {
140
- final component = columns[_componentNameIndex];
141
- final version = columns[_componentVersionIndex];
142
- final id = ItemId (component, version);
143
140
final license = columns[_licensesIndex];
144
- _dictionary.addLicenses (id, mapper[license]);
141
+ final versionId = columns[_componentVersionIdIndex];
142
+ _dictionary.addLicenses (versionId, mapper[license]);
145
143
}
146
144
}
147
145
148
146
/// Extracts dependencies from a Black Duck source CSV.
149
147
class _BlackDuckSourceCsvParser extends CsvParser {
150
148
final ScanResult result;
151
149
final _LicenseDictionary licenseDictionary;
152
- final assumed = < ItemId > {};
150
+ final assumed = < BomItem > {};
153
151
154
- var _versionIndex = - 1 ;
155
- var _originIndex = - 1 ;
156
- var _nameIndex = - 1 ;
157
- var _componentNameIndex = - 1 ;
158
- var _componentVersionIndex = - 1 ;
152
+ late final int _versionIndex;
153
+ late final int _originIndex;
154
+ late final int _nameIndex;
155
+ late final int _componentNameIndex;
156
+ late final int _componentVersionIndex;
157
+ late final int _componentVersionIdIndex;
159
158
160
159
_BlackDuckSourceCsvParser (this .result, this .licenseDictionary);
161
160
@@ -166,62 +165,68 @@ class _BlackDuckSourceCsvParser extends CsvParser {
166
165
_nameIndex = columnIndexOf ('Origin name id' , columns);
167
166
_componentNameIndex = columnIndexOf ('Component name' , columns);
168
167
_componentVersionIndex = columnIndexOf ('Component version name' , columns);
168
+ _componentVersionIdIndex = columnIndexOf ('Version id' , columns);
169
169
}
170
170
171
171
@override
172
172
void dataRow (List <String > columns) {
173
- final type = columns[_originIndex];
173
+ final origin = columns[_originIndex];
174
174
final nameColumn = columns[_nameIndex];
175
175
final versionColumn = columns[_versionIndex];
176
+ final versionId = columns[_componentVersionIdIndex];
177
+ final type = _purlType[origin] ?? origin;
176
178
177
- var itemId ;
178
- switch (type ) {
179
+ late BomItem item ;
180
+ switch (origin ) {
179
181
case '' : // Signature scan result
180
182
final component = columns[_componentNameIndex];
181
183
final componentVersion = columns[_componentVersionIndex];
182
- itemId = ItemId (component, componentVersion);
184
+ item = BomItem (Purl .of (
185
+ type: 'generic' , name: component, version: componentVersion));
183
186
break ;
184
187
case 'maven' :
185
188
case 'github' :
186
189
final name2 = _stripFromLast (nameColumn, ':' ).replaceAll (':' , '/' );
187
- itemId = ItemId (name2, versionColumn);
190
+ item =
191
+ BomItem (Purl .of (type: type, name: name2, version: versionColumn));
188
192
break ;
189
193
case 'npmjs' :
190
194
case 'nuget' :
191
195
final name2 = _stripFromLast (nameColumn, '/' );
192
- itemId = ItemId (name2, versionColumn);
196
+ item =
197
+ BomItem (Purl .of (type: type, name: name2, version: versionColumn));
193
198
break ;
194
199
case 'alpine' :
195
200
final name = _stripSeparatedPostFix (nameColumn, versionColumn);
196
201
final version = _stripFromLast (versionColumn, '/' );
197
- itemId = ItemId ( name, version);
202
+ item = BomItem ( Purl . of (type : type, name: name , version: version) );
198
203
break ;
199
204
case 'centos' :
200
205
final name = _stripFrom (nameColumn, '/' );
201
206
final temp = versionColumn.substring (versionColumn.indexOf (':' ) + 1 );
202
207
final version = _stripFrom (temp, '-' );
203
- itemId = ItemId ( name, version);
208
+ item = BomItem ( Purl . of (type : type, name: name , version: version) );
204
209
break ;
205
210
case 'debian' :
206
211
final version = _stripFrom (versionColumn, '/' );
207
212
final name = _stripSeparatedPostFix (nameColumn, version);
208
- itemId = ItemId ( name, version);
213
+ item = BomItem ( Purl . of (type : type, name: name , version: version) );
209
214
break ;
210
215
case 'long_tail' :
211
216
final name = _stripFromLast (nameColumn, '#' );
212
- itemId = ItemId ( name, versionColumn);
217
+ item = BomItem ( Purl . of (type : type, name: name, version : versionColumn) );
213
218
break ;
214
219
default :
215
220
final name = _stripFromLast (nameColumn, '/' );
216
- itemId = ItemId ( name, versionColumn);
217
- if (! assumed.contains (itemId )) {
221
+ item = BomItem ( Purl . of (type : type, name: name, version : versionColumn) );
222
+ if (! assumed.contains (item )) {
218
223
print (
219
- 'Warning: Assumed name=${ itemId . package }, version=${ itemId . version } for Black Duck type "$type "' );
220
- assumed.add (itemId );
224
+ 'Warning: Assumed ${ item . purl } for Black Duck type "$origin " -> "$ nameColumn "' );
225
+ assumed.add (item );
221
226
}
222
227
}
223
- _addLicenses (columns, itemId );
224
- result.addItem (itemId );
228
+ item. addLicenses (licenseDictionary[versionId] ?? {} );
229
+ result.addItem (item );
225
230
}
226
231
227
232
String _stripFrom (String string, Pattern pattern) {
@@ -238,11 +243,19 @@ class _BlackDuckSourceCsvParser extends CsvParser {
238
243
final index = string.lastIndexOf (postfix);
239
244
return (index < 0 ) ? string : string.substring (0 , index - 1 );
240
245
}
241
-
242
- void _addLicenses (List <String > columns, ItemId itemId) {
243
- final componentName = columns[_componentNameIndex];
244
- final componentVersion = columns[_componentVersionIndex];
245
- final component = ItemId (componentName, componentVersion);
246
- itemId.addLicenses (licenseDictionary[component] ?? {});
247
- }
248
246
}
247
+
248
+ const _purlType = {
249
+ 'arch_linux' : 'arch' ,
250
+ 'centos' : 'rpm' ,
251
+ 'fedora' : 'rpm' ,
252
+ 'redhat' : 'rpm' ,
253
+ 'opensuse' : 'rpm' ,
254
+ 'crates' : 'cargo' ,
255
+ 'dart' : 'pub' ,
256
+ 'debian' : 'deb' ,
257
+ 'ubuntu' : 'deb' ,
258
+ 'long_tail' : 'generic' ,
259
+ 'npmjs' : 'npm' ,
260
+ 'rubygems' : 'gem' ,
261
+ };
0 commit comments