@@ -399,6 +399,34 @@ impl SbomGenerator {
399
399
e
400
400
) ,
401
401
}
402
+ } else {
403
+ if let Some ( source) = & package. source {
404
+ if !source. is_crates_io ( ) {
405
+ match source. repr . split_once ( '+' ) {
406
+ Some ( ( "git" , git_path) ) => {
407
+ let repo_url = git_path
408
+ . split_once ( '#' )
409
+ . map_or ( git_path, |( first, _) | first) ;
410
+ match Uri :: try_from ( repo_url. to_string ( ) ) {
411
+ Ok ( uri) => references
412
+ . push ( ExternalReference :: new ( ExternalReferenceType :: Vcs , uri) ) ,
413
+ Err ( e) => log:: warn!(
414
+ "Package {} has an invalid repository URI ({}): {} " ,
415
+ package. name,
416
+ source,
417
+ e
418
+ ) ,
419
+ }
420
+ }
421
+ Some ( ( source, _path) ) => log:: warn!( "Unknown source kind {}" , source) ,
422
+ None => {
423
+ log:: warn!(
424
+ "No '+' separator found in source field from `cargo metadata`"
425
+ )
426
+ }
427
+ }
428
+ }
429
+ }
402
430
}
403
431
404
432
if !references. is_empty ( ) {
@@ -1041,6 +1069,8 @@ impl From<std::io::Error> for SbomWriterError {
1041
1069
mod test {
1042
1070
use super :: * ;
1043
1071
1072
+ const GIT_PACKAGE_JSON : & str = include_str ! ( "../tests/fixtures/git_package.json" ) ;
1073
+
1044
1074
#[ test]
1045
1075
fn it_should_parse_author_and_email ( ) {
1046
1076
let actual =
SbomGenerator :: parse_author ( "First Last <[email protected] >" )
@@ -1079,4 +1109,72 @@ mod test {
1079
1109
1080
1110
assert_eq ! ( actual, expected) ;
1081
1111
}
1112
+
1113
+ #[ test]
1114
+ fn it_should_get_external_references_from_source ( ) {
1115
+ let mut git_package: Package = serde_json:: from_str ( GIT_PACKAGE_JSON ) . unwrap ( ) ;
1116
+ git_package. repository = None ;
1117
+
1118
+ let actual = SbomGenerator :: get_external_references ( & git_package)
1119
+ . expect ( "Failed to parse external reference" ) ;
1120
+
1121
+ let mut expected = Vec :: new ( ) ;
1122
+ expected. push ( ExternalReference :: new (
1123
+ ExternalReferenceType :: Vcs ,
1124
+ Uri :: new ( "https://github.com/rust-secure-code/cargo-auditable.git" ) ,
1125
+ ) ) ;
1126
+
1127
+ assert_eq ! ( actual, ExternalReferences ( expected) ) ;
1128
+ }
1129
+
1130
+ #[ test]
1131
+ fn it_should_get_external_references_from_source_without_digest ( ) {
1132
+ let mut git_package: Package = serde_json:: from_str ( GIT_PACKAGE_JSON ) . unwrap ( ) ;
1133
+ git_package. repository = None ;
1134
+ git_package. source = Some ( cargo_metadata:: Source {
1135
+ repr : "git+https://github.com/rust-secure-code/cargo-auditable.git" . to_string ( ) ,
1136
+ } ) ;
1137
+
1138
+ let actual = SbomGenerator :: get_external_references ( & git_package)
1139
+ . expect ( "Failed to parse external reference" ) ;
1140
+
1141
+ let mut expected = Vec :: new ( ) ;
1142
+ expected. push ( ExternalReference :: new (
1143
+ ExternalReferenceType :: Vcs ,
1144
+ Uri :: new ( "https://github.com/rust-secure-code/cargo-auditable.git" ) ,
1145
+ ) ) ;
1146
+
1147
+ assert_eq ! ( actual, ExternalReferences ( expected) ) ;
1148
+ }
1149
+
1150
+ #[ test]
1151
+ fn it_should_not_get_external_references_from_unidentifiable_source ( ) {
1152
+ let mut git_package: Package = serde_json:: from_str ( GIT_PACKAGE_JSON ) . unwrap ( ) ;
1153
+ git_package. repository = None ;
1154
+ git_package. source = Some ( cargo_metadata:: Source {
1155
+ repr : "https://github.com/rust-secure-code/cargo-auditable.git" . to_string ( ) ,
1156
+ } ) ;
1157
+
1158
+ assert_eq ! ( SbomGenerator :: get_external_references( & git_package) , None ) ;
1159
+ }
1160
+
1161
+ #[ test]
1162
+ fn it_should_not_get_external_references_from_non_uri_source ( ) {
1163
+ let mut git_package: Package = serde_json:: from_str ( GIT_PACKAGE_JSON ) . unwrap ( ) ;
1164
+ git_package. repository = None ;
1165
+ git_package. source = Some ( cargo_metadata:: Source {
1166
+ repr : "not a uri" . to_string ( ) ,
1167
+ } ) ;
1168
+
1169
+ assert_eq ! ( SbomGenerator :: get_external_references( & git_package) , None ) ;
1170
+ }
1171
+
1172
+ #[ test]
1173
+ fn it_should_not_get_external_reference_from_invalid_source_uri ( ) {
1174
+ let mut git_package: Package = serde_json:: from_str ( GIT_PACKAGE_JSON ) . unwrap ( ) ;
1175
+ git_package. repository = None ;
1176
+ git_package. source = None ;
1177
+
1178
+ assert_eq ! ( SbomGenerator :: get_external_references( & git_package) , None ) ;
1179
+ }
1082
1180
}
0 commit comments