1111import pandas as pd
1212import yaml
1313import copy
14+ import requests
15+ from npm .bindings import npm_run
16+ from lastversion import latest
1417import fosslight_util .constant as constant
1518from fosslight_util .parsing_yaml import parsing_yml
1619from fosslight_util .write_yaml import create_yaml_with_ossitem
@@ -90,61 +93,92 @@ def call_analysis_api(path_to_run, str_run_start, return_idx, func, *args):
9093 return success , result
9194
9295
93- def extract_name_from_link (link ):
96+ def extract_name_version_from_link (link ):
9497 # Github : https://github.com/(owner)/(repo)
95- # npm : www.npmjs.com/package/(package)
96- # npm : https://www.npmjs.com/package/@(group)/(package)
97- # pypi : https://pypi.org/project/(oss_name)
98+ # npm : https:// www.npmjs.com/package/(package)/v/(version )
99+ # npm2 : https://www.npmjs.com/package/@(group)/(package)/v/(version )
100+ # pypi : https://pypi.org/project/(oss_name)/(version)
98101 # pypi2 : https://files.pythonhosted.org/packages/source/(alphabet)/(oss_name)/(oss_name)-(version).tar.gz
99- # Maven: https://mvnrepository.com/artifact/(group)/(artifact)
100- # pub: https://pub.dev/packages/(package)
102+ # Maven: https://mvnrepository.com/artifact/(group)/(artifact)/(version)
103+ # pub: https://pub.dev/packages/(package)/versions/(version)
101104 # Cocoapods: https://cocoapods.org/(package)
102105 pkg_pattern = {
103106 "github" : r'https?:\/\/github.com\/([^\/]+)\/([^\/\.]+)(\.git)?' ,
104- "pypi" : r'https?:\/\/pypi\.org\/project\/([^\/]+)' ,
105- "pypi2" : r'https?:\/\/files\.pythonhosted\.org\/packages\/source\/[\w]\/([^\/]+)\/([^\/]+)' ,
106- "maven" : r'https?:\/\/mvnrepository\.com\/artifact\/([^\/]+)\/([^\/]+)' ,
107- "npm" : r'https?:\/\/www\.npmjs\.com\/package\/([^\/]+)(\/[^\/]+)?' ,
108- "pub" : r'https?:\/\/pub\.dev\/packages\/([^\/]+)' ,
107+ "pypi" : r'https?:\/\/pypi\.org\/project\/([^\/]+)[\/]?([^\/]*)' ,
108+ "pypi2" : r'https?:\/\/files\.pythonhosted\.org\/packages\/source\/[\w]\/([^\/]+)\/[\S]+-([^\-]+)\.tar\.gz' ,
109+ "maven" : r'https?:\/\/mvnrepository\.com\/artifact\/([^\/]+)\/([^\/]+)\/?([^\/]*)' ,
110+ "npm" : r'https?:\/\/www\.npmjs\.com\/package\/([^\/\@]+)(?:\/v\/)?([^\/]*)' ,
111+ "npm2" : r'https?:\/\/www\.npmjs\.com\/package\/(\@[^\/]+\/[^\/]+)(?:\/v\/)?([^\/]*)' ,
112+ "pub" : r'https?:\/\/pub\.dev\/packages\/([^\/]+)(?:\/versions\/)?([^\/]*)' ,
109113 "pods" : r'https?:\/\/cocoapods\.org\/pods\/([^\/]+)'
110114 }
111115 oss_name = ""
116+ oss_version = ""
112117 if link .startswith ("www." ):
113118 link = link .replace ("www." , "https://www." , 1 )
114119 for key , value in pkg_pattern .items ():
115- try :
116- p = re . compile ( value )
117- match = p . match ( link )
118- if match :
119- group = match .group (1 )
120+ p = re . compile ( value )
121+ match = p . match ( link )
122+ if match :
123+ try :
124+ origin_name = match .group (1 )
120125 if key == "github" :
121126 repo = match .group (2 )
122- oss_name = f"{ group } -{ repo } "
123- break
127+ oss_name = f"{ origin_name } -{ repo } "
124128 elif (key == "pypi" ) or (key == "pypi2" ):
125- oss_name = f"pypi:{ group } "
129+ oss_name = f"pypi:{ origin_name } "
126130 oss_name = re .sub (r"[-_.]+" , "-" , oss_name ).lower ()
127- break
131+ oss_version = match . group ( 2 )
128132 elif key == "maven" :
129133 artifact = match .group (2 )
130- oss_name = f"{ group } :{ artifact } "
131- break
132- elif key == "npm" :
133- if group .startswith ("@" ):
134- pkg = match .group (2 )
135- oss_name = f"npm:{ group } { pkg } "
136- else :
137- oss_name = f"npm:{ group } "
138- break
134+ oss_name = f"{ origin_name } :{ artifact } "
135+ origin_name = oss_name
136+ oss_version = match .group (3 )
137+ elif key == "npm" or key == "npm2" :
138+ oss_name = f"npm:{ origin_name } "
139+ oss_version = match .group (2 )
139140 elif key == "pub" :
140- oss_name = f"pub:{ group } "
141- break
141+ oss_name = f"pub:{ origin_name } "
142+ oss_version = match . group ( 2 )
142143 elif key == "pods" :
143- oss_name = f"cocoapods:{ group } "
144- break
145- except Exception as ex :
146- logger .debug (f"extract_name_from_link_{ key } :{ ex } " )
147- return oss_name
144+ oss_name = f"cocoapods:{ origin_name } "
145+ except Exception as ex :
146+ logger .info (f"extract_name_version_from_link { key } :{ ex } " )
147+ if oss_name and (not oss_version ):
148+ if key in ["pypi" , "maven" , "npm" , "npm2" , "pub" ]:
149+ oss_version , link = get_latest_package_version (link , key , origin_name )
150+ logger .debug (f'Try to download with the latest version:{ link } ' )
151+ break
152+ return oss_name , oss_version , link
153+
154+
155+ def get_latest_package_version (link , pkg_type , oss_name ):
156+ find_version = ''
157+ link_with_version = link
158+
159+ try :
160+ if pkg_type in ['npm' , 'npm2' ]:
161+ stderr , stdout = npm_run ('view' , oss_name , 'version' )
162+ if stdout :
163+ find_version = stdout .strip ()
164+ link_with_version = f'https://www.npmjs.com/package/{ oss_name } /v/{ find_version } '
165+ elif pkg_type == 'pypi' :
166+ find_version = str (latest (oss_name , at = 'pip' , output_format = 'version' , pre_ok = True ))
167+ link_with_version = f'https://pypi.org/project/{ oss_name } /{ find_version } '
168+ elif pkg_type == 'maven' :
169+ maven_response = requests .get (f'https://api.deps.dev/v3alpha/systems/maven/packages/{ oss_name } ' )
170+ if maven_response .status_code == 200 :
171+ find_version = maven_response .json ().get ('versions' )[- 1 ].get ('versionKey' ).get ('version' )
172+ oss_name = oss_name .replace (':' , '/' )
173+ link_with_version = f'https://mvnrepository.com/artifact/{ oss_name } /{ find_version } '
174+ elif pkg_type == 'pub' :
175+ pub_response = requests .get (f'https://pub.dev/api/packages/{ oss_name } ' )
176+ if pub_response .status_code == 200 :
177+ find_version = pub_response .json ().get ('latest' ).get ('version' )
178+ link_with_version = f'https://pub.dev/packages/{ oss_name } /versions/{ find_version } '
179+ except Exception as e :
180+ logger .debug (f'Fail to get latest package version({ link } :{ e } )' )
181+ return find_version , link_with_version
148182
149183
150184def overwrite_excel (excel_file_path , oss_name , column_name = 'OSS Name' ):
@@ -169,7 +203,8 @@ def overwrite_excel(excel_file_path, oss_name, column_name='OSS Name'):
169203 logger .debug (f"overwrite_excel:{ ex } " )
170204
171205
172- def merge_yamls (_output_dir , merge_yaml_files , final_report , remove_src_data = False , default_oss_name = '' , url = '' ):
206+ def merge_yamls (_output_dir , merge_yaml_files , final_report , remove_src_data = False ,
207+ default_oss_name = '' , default_oss_version = '' , url = '' ):
173208 success = True
174209 err_msg = ''
175210
@@ -183,7 +218,8 @@ def merge_yamls(_output_dir, merge_yaml_files, final_report, remove_src_data=Fal
183218 if remove_src_data :
184219 existed_yaml = {}
185220 for oi in oss_list :
186- oi .name = default_oss_name if oi .name == '-' else oi .name
221+ oi .name = default_oss_name if oi .name == '' else oi .name
222+ oi .version = default_oss_version if oi .version == '' else oi .version
187223 oi .download_location = url if oi .download_location == '' else oi .download_location
188224 create_yaml_with_ossitem (oi , existed_yaml )
189225 with open (os .path .join (_output_dir , mf ), 'w' ) as f :
0 commit comments