Skip to content

Commit 8f61441

Browse files
committed
Download the latest version of package url
Signed-off-by: Jiyeong Seok <[email protected]>
1 parent 6f269b8 commit 8f61441

File tree

3 files changed

+83
-43
lines changed

3 files changed

+83
-43
lines changed

requirements.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,5 @@ fosslight_source>=1.7.3
99
fosslight_dependency>=3.7.4
1010
fosslight_binary>=4.1.24
1111
fosslight_prechecker>=3.0.1
12+
npm
13+
requests

src/fosslight_scanner/common.py

Lines changed: 74 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@
1111
import pandas as pd
1212
import yaml
1313
import copy
14+
import requests
15+
from npm.bindings import npm_run
16+
from lastversion import latest
1417
import fosslight_util.constant as constant
1518
from fosslight_util.parsing_yaml import parsing_yml
1619
from 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

150184
def 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:

src/fosslight_scanner/fosslight_scanner.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
from fosslight_util.output_format import check_output_format
2424
from fosslight_prechecker._precheck import run_lint as prechecker_lint
2525
from .common import (copy_file, call_analysis_api,
26-
overwrite_excel, extract_name_from_link,
26+
overwrite_excel, extract_name_version_from_link,
2727
merge_yamls, correct_scanner_result,
2828
create_scancodejson)
2929
from fosslight_util.write_excel import merge_excels
@@ -104,7 +104,7 @@ def run_scanner(src_path, dep_arguments, output_path, keep_raw_data=False,
104104
run_src=True, run_bin=True, run_dep=True, run_prechecker=True,
105105
remove_src_data=True, result_log={}, output_file="",
106106
output_extension="", num_cores=-1, db_url="",
107-
default_oss_name="", url="",
107+
default_oss_name="", default_oss_version="", url="",
108108
correct_mode=True, correct_fpath="", ui_mode=False):
109109
final_excel_dir = output_path
110110
success = True
@@ -206,6 +206,7 @@ def run_scanner(src_path, dep_arguments, output_path, keep_raw_data=False,
206206

207207
if remove_src_data:
208208
overwrite_excel(_output_dir, default_oss_name, "OSS Name")
209+
overwrite_excel(_output_dir, default_oss_version, "OSS Version")
209210
overwrite_excel(_output_dir, url, "Download Location")
210211
success, err_msg = merge_excels(_output_dir, final_report, merge_files)
211212

@@ -219,7 +220,7 @@ def run_scanner(src_path, dep_arguments, output_path, keep_raw_data=False,
219220
shutil.rmtree(os.path.join(_output_dir, tmp_dir), ignore_errors=True)
220221
elif output_extension == ".yaml":
221222
success, err_msg = merge_yamls(_output_dir, merge_files, final_report,
222-
remove_src_data, default_oss_name, url)
223+
remove_src_data, default_oss_name, default_oss_version, url)
223224
if success:
224225
if os.path.isfile(final_report):
225226
logger.info(f'Generated the result file: {final_report}')
@@ -305,6 +306,7 @@ def run_main(mode, path_arg, dep_arguments, output_file_or_dir, file_format, url
305306

306307
output_file = ""
307308
default_oss_name = ""
309+
default_oss_version = ""
308310
src_path = ""
309311
_executed_path = os.getcwd()
310312

@@ -392,7 +394,7 @@ def run_main(mode, path_arg, dep_arguments, output_file_or_dir, file_format, url
392394

393395
if url_to_analyze != "":
394396
remove_downloaded_source = True
395-
default_oss_name = extract_name_from_link(url_to_analyze)
397+
default_oss_name, default_oss_version, url_to_analyze = extract_name_version_from_link(url_to_analyze)
396398
success, src_path = download_source(url_to_analyze, output_path)
397399

398400
if output_extension == ".yaml":
@@ -407,7 +409,7 @@ def run_main(mode, path_arg, dep_arguments, output_file_or_dir, file_format, url
407409
run_src, run_bin, run_dep, run_prechecker,
408410
remove_downloaded_source, {}, output_file,
409411
output_extension, num_cores, db_url,
410-
default_oss_name, url_to_analyze,
412+
default_oss_name, default_oss_version, url_to_analyze,
411413
correct_mode, correct_fpath, ui_mode)
412414
else:
413415
logger.error("No mode has been selected for analysis.")

0 commit comments

Comments
 (0)