11
11
parser = argparse .ArgumentParser ("Retreive BOM component license information for the given project and version" )
12
12
parser .add_argument ("project_name" )
13
13
parser .add_argument ("version" )
14
+ parser .add_argument ("-l" , "--deep_license_info" , action = "store_true" )
15
+ parser .add_argument ("-c" , "--copyright_info" , action = "store_true" )
16
+ parser .add_argument ("-m" , "--matched_files" , action = "store_true" )
17
+ parser .add_argument ("-u" , "--un_matched_files" , action = "store_true" )
18
+
14
19
15
20
args = parser .parse_args ()
16
21
20
25
project = hub .get_project_by_name (args .project_name )
21
26
version = hub .get_version_by_name (project , args .version )
22
27
23
- bom_components = hub .get_version_components (version )
28
+ bom_components = hub .get_version_components (version ). get ( 'items' , [])
24
29
25
30
all_origins = dict ()
26
31
30
35
31
36
all_origin_info = {}
32
37
33
- for bom_component in bom_components ['items' ]:
34
- component_url = bom_component ['component' ]
35
- response = hub .execute_get (component_url )
38
+ scan_cache = {}
39
+
40
+ for bom_component in bom_components :
41
+ if 'componentVersionName' in bom_component :
42
+ bom_component_name = f"{ bom_component ['componentName' ]} :{ bom_component ['componentVersionName' ]} "
43
+ else :
44
+ bom_component_name = f"{ bom_component ['componentName' ]} "
36
45
37
46
# Component details include the home page url and additional home pages
38
- logging .debug ("Retrieving component home page info for {}:{}" .format (
39
- bom_component ['componentName' ], bom_component ['componentVersionName' ]))
40
- component_details = None
41
- if response .status_code == 200 :
42
- component_details = response .json ()
47
+ component_url = bom_component ['component' ]
48
+ component_details = hub .execute_get (component_url ).json ()
43
49
50
+ #
51
+ # Grab origin info, file-level license info, and file-level copyright info
52
+ #
53
+ all_origin_details = list ()
44
54
for origin in bom_component .get ('origins' , []):
45
- logging .debug ("Retrieving origin details for origin {}" . format ( origin ['name' ]) )
55
+ logging .debug (f "Retrieving origin details for { bom_component_name } and origin { origin ['name' ]} " )
46
56
origin_url = hub .get_link (origin , 'origin' )
47
- response = hub .execute_get (origin_url )
48
- origin_details = None
49
- if response .status_code == 200 :
50
- origin_details = response .json ()
51
-
52
- all_origin_info .update ({
53
- "{}:{}" .format (bom_component ['componentName' ], bom_component ['componentVersionName' ]): {
54
- "component_details" : component_details ,
55
- "component_home_page" : component_details .get ("url" ),
56
- "additional_home_pages" : component_details .get ("additionalHomepages" ),
57
- "origin_details" : origin_details ,
58
- }
57
+ origin_details = hub .execute_get (origin_url ).json ()
58
+
59
+ #
60
+ # Add deep license info and copyright info, as appropriate
61
+ #
62
+ info_to_get = []
63
+ if args .deep_license_info :
64
+ info_to_get .extend ([
65
+ ("file-licenses" , "file_licenses" ),
66
+ ("file-licenses-fuzzy" , "file_licenses_fuzzy" )
67
+ ])
68
+
69
+ if args .copyright_info :
70
+ info_to_get .extend ([
71
+ ("file-copyrights" , "file_copyrights" ),
72
+ ("component-origin-copyrights" , "component_origin_copyrights" )
73
+ ])
74
+ for link_t in info_to_get :
75
+ link_name = link_t [0 ]
76
+ k = link_t [1 ]
77
+ logging .debug (f"Retrieving { link_name } for { bom_component_name } " )
78
+ url = hub .get_link (origin_details , link_name )
79
+ info = hub .execute_get (url ).json ().get ('items' , [])
80
+ origin_details [k ] = info
81
+
82
+ all_origin_details .append (origin_details )
83
+
84
+ all_origin_info .update ({
85
+ bom_component_name : {
86
+ "bom_component_info" : bom_component ,
87
+ "component_details" : component_details ,
88
+ "component_home_page" : component_details .get ("url" ),
89
+ "additional_home_pages" : component_details .get ("additionalHomepages" ),
90
+ "all_origin_details" : all_origin_details ,
91
+ }
92
+ })
93
+
94
+ if args .matched_files :
95
+ logging .debug (f"Retrieving matched files for { bom_component_name } " )
96
+ matched_files_url = hub .get_link (bom_component , "matched-files" ) + "?limit=99999"
97
+ matched_files = hub .execute_get (matched_files_url ).json ().get ('items' , [])
98
+ # Get scan info
99
+ for matched_file in matched_files :
100
+ scan_url = hub .get_link (matched_file , "codelocations" )
101
+ if scan_url in scan_cache :
102
+ scan = scan_cache [scan_url ]
103
+ else :
104
+ scan = hub .execute_get (scan_url ).json ()
105
+ scan_cache [scan_url ] = scan
106
+ matched_file ['scan' ] = scan
107
+ all_origin_info [bom_component_name ].update ({
108
+ 'matched_files' : matched_files
59
109
})
60
110
111
+ if args .un_matched_files :
112
+ # TODO: Probably need to loop on this with smaller page sizes to handle very large
113
+ # project-versions with many (signature) scans mapped to it
114
+ #
115
+ logging .debug (f"Retrieving un-matched files for project { project ['name' ]} , version { version ['versionName' ]} " )
116
+ un_matched_files_url = f"{ version ['_meta' ]['href' ]} /matched-files?limit=99999&filter=bomMatchType:unmatched"
117
+ un_matched_files = hub .execute_get (un_matched_files_url ).json ().get ('items' , [])
118
+ logging .debug (f"Adding { len (un_matched_files )} un-matched files to the output" )
119
+ all_origin_info .update ({
120
+ 'un_matched_files' : un_matched_files
121
+ })
122
+
61
123
print (json .dumps (all_origin_info ))
0 commit comments