fosslight-dependency 3.0.7__py3-none-any.whl → 4.1.30__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- fosslight_dependency/LICENSES/LICENSE +201 -0
- fosslight_dependency/LICENSES/LicenseRef-3rd_party_licenses.txt +1254 -0
- fosslight_dependency/__init__.py +0 -1
- fosslight_dependency/_analyze_dependency.py +130 -0
- fosslight_dependency/_graph_convertor.py +67 -0
- fosslight_dependency/_help.py +79 -0
- fosslight_dependency/_package_manager.py +397 -0
- fosslight_dependency/cli.py +127 -0
- fosslight_dependency/constant.py +57 -0
- fosslight_dependency/dependency_item.py +103 -0
- fosslight_dependency/package_manager/Android.py +90 -0
- fosslight_dependency/package_manager/Cargo.py +144 -0
- fosslight_dependency/package_manager/Carthage.py +130 -0
- fosslight_dependency/package_manager/Cocoapods.py +194 -0
- fosslight_dependency/package_manager/Go.py +179 -0
- fosslight_dependency/package_manager/Gradle.py +123 -0
- fosslight_dependency/package_manager/Helm.py +106 -0
- fosslight_dependency/package_manager/Maven.py +274 -0
- fosslight_dependency/package_manager/Npm.py +296 -0
- fosslight_dependency/package_manager/Nuget.py +368 -0
- fosslight_dependency/package_manager/Pnpm.py +155 -0
- fosslight_dependency/package_manager/Pub.py +241 -0
- fosslight_dependency/package_manager/Pypi.py +395 -0
- fosslight_dependency/package_manager/Swift.py +159 -0
- fosslight_dependency/package_manager/Unity.py +118 -0
- fosslight_dependency/package_manager/Yarn.py +231 -0
- fosslight_dependency/package_manager/__init__.py +0 -0
- fosslight_dependency/run_dependency_scanner.py +393 -0
- fosslight_dependency-4.1.30.dist-info/METADATA +213 -0
- fosslight_dependency-4.1.30.dist-info/RECORD +37 -0
- {fosslight_dependency-3.0.7.dist-info → fosslight_dependency-4.1.30.dist-info}/WHEEL +1 -1
- fosslight_dependency-4.1.30.dist-info/entry_points.txt +2 -0
- fosslight_dependency-4.1.30.dist-info/licenses/LICENSES/Apache-2.0.txt +201 -0
- fosslight_dependency-4.1.30.dist-info/licenses/LICENSES/LicenseRef-3rd_party_licenses.txt +1254 -0
- fosslight_dependency-4.1.30.dist-info/licenses/LICENSES/MIT.txt +21 -0
- fosslight_dependency/_version.py +0 -1
- fosslight_dependency/analyze_dependency.py +0 -1090
- fosslight_dependency/third_party/askalono/askalono.exe +0 -0
- fosslight_dependency/third_party/askalono/askalono_macos +0 -0
- fosslight_dependency/third_party/nomos/nomossa +0 -0
- fosslight_dependency-3.0.7.dist-info/3rd_party_licenses.txt +0 -726
- fosslight_dependency-3.0.7.dist-info/METADATA +0 -51
- fosslight_dependency-3.0.7.dist-info/RECORD +0 -13
- fosslight_dependency-3.0.7.dist-info/entry_points.txt +0 -3
- {fosslight_dependency-3.0.7.dist-info → fosslight_dependency-4.1.30.dist-info/licenses}/LICENSE +0 -0
- {fosslight_dependency-3.0.7.dist-info → fosslight_dependency-4.1.30.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
# Copyright (c) 2021 LG Electronics Inc.
|
|
4
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
|
|
6
|
+
import os
|
|
7
|
+
import logging
|
|
8
|
+
import json
|
|
9
|
+
import yaml
|
|
10
|
+
import re
|
|
11
|
+
import fosslight_util.constant as constant
|
|
12
|
+
import fosslight_dependency.constant as const
|
|
13
|
+
from fosslight_dependency._package_manager import PackageManager, get_url_to_purl
|
|
14
|
+
from fosslight_dependency.dependency_item import DependencyItem, change_dependson_to_purl
|
|
15
|
+
from fosslight_util.oss_item import OssItem
|
|
16
|
+
|
|
17
|
+
logger = logging.getLogger(constant.LOGGER_NAME)
|
|
18
|
+
|
|
19
|
+
_spec_repos = 'SPEC REPOS'
|
|
20
|
+
_external_sources = 'EXTERNAL SOURCES'
|
|
21
|
+
_dependencies = 'DEPENDENCIES'
|
|
22
|
+
_source_type = ['git', 'http', 'svn', 'hg']
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class Cocoapods(PackageManager):
|
|
26
|
+
package_manager_name = const.COCOAPODS
|
|
27
|
+
|
|
28
|
+
dn_url = 'https://cocoapods.org/'
|
|
29
|
+
input_file_name = const.SUPPORT_PACKAE.get(package_manager_name)
|
|
30
|
+
|
|
31
|
+
def __init__(self, input_dir, output_dir):
|
|
32
|
+
super().__init__(self.package_manager_name, self.dn_url, input_dir, output_dir)
|
|
33
|
+
self.append_input_package_list_file(self.input_file_name)
|
|
34
|
+
|
|
35
|
+
def parse_oss_information(self, f_name):
|
|
36
|
+
with open(f_name, 'r', encoding='utf8') as input_fp:
|
|
37
|
+
podfile_yaml = yaml.load(input_fp, Loader=yaml.FullLoader)
|
|
38
|
+
|
|
39
|
+
spec_repo_list = []
|
|
40
|
+
external_source_list = []
|
|
41
|
+
|
|
42
|
+
if _spec_repos in podfile_yaml:
|
|
43
|
+
for spec_item_key in podfile_yaml[_spec_repos]:
|
|
44
|
+
for spec_item in podfile_yaml[_spec_repos][spec_item_key]:
|
|
45
|
+
spec_repo_list.append(spec_item)
|
|
46
|
+
if _external_sources in podfile_yaml:
|
|
47
|
+
for external_sources_key in podfile_yaml[_external_sources]:
|
|
48
|
+
external_source_list.append(external_sources_key)
|
|
49
|
+
spec_repo_list.append(external_sources_key)
|
|
50
|
+
if len(spec_repo_list) == 0:
|
|
51
|
+
logger.error("Cannot find SPEC REPOS or EXTERNAL SOURCES in Podfile.lock.")
|
|
52
|
+
return ''
|
|
53
|
+
|
|
54
|
+
for dep_key in podfile_yaml[_dependencies]:
|
|
55
|
+
dep_key_re = re.findall(r'(^\S*)', dep_key)
|
|
56
|
+
self.direct_dep_list.append(dep_key_re[0])
|
|
57
|
+
|
|
58
|
+
pod_item_list = {}
|
|
59
|
+
for pods_i in podfile_yaml['PODS']:
|
|
60
|
+
if not isinstance(pods_i, str):
|
|
61
|
+
for key, items in pods_i.items():
|
|
62
|
+
k_name, k_ver = get_pods_info(key)
|
|
63
|
+
pod_item_list[k_name] = k_ver
|
|
64
|
+
self.relation_tree[f'{k_name}({k_ver})'] = []
|
|
65
|
+
for item in items:
|
|
66
|
+
i_name, _ = get_pods_info(item)
|
|
67
|
+
self.relation_tree[f'{k_name}({k_ver})'].append(i_name)
|
|
68
|
+
else:
|
|
69
|
+
oss_name, oss_version = get_pods_info(pods_i)
|
|
70
|
+
pod_item_list[oss_name] = oss_version
|
|
71
|
+
|
|
72
|
+
for rel_key in self.relation_tree:
|
|
73
|
+
try:
|
|
74
|
+
tmp_item_list = []
|
|
75
|
+
for ri in self.relation_tree[rel_key]:
|
|
76
|
+
ri_version = pod_item_list[ri]
|
|
77
|
+
tmp_item_list.append(f'{ri}({ri_version})')
|
|
78
|
+
self.relation_tree[rel_key] = []
|
|
79
|
+
self.relation_tree[rel_key].extend(tmp_item_list)
|
|
80
|
+
except Exception as e:
|
|
81
|
+
logger.warning(f'Fail to check packages of {rel_key}: {e}')
|
|
82
|
+
if rel_key in self.relation_tree:
|
|
83
|
+
self.relation_tree[rel_key] = []
|
|
84
|
+
|
|
85
|
+
purl_dict = {}
|
|
86
|
+
for pod_oss_name_origin, pod_oss_version in pod_item_list.items():
|
|
87
|
+
dep_item = DependencyItem()
|
|
88
|
+
oss_item = OssItem()
|
|
89
|
+
try:
|
|
90
|
+
if self.direct_dep and (len(self.direct_dep_list) > 0):
|
|
91
|
+
if pod_oss_name_origin in self.direct_dep_list:
|
|
92
|
+
oss_item.comment = 'direct'
|
|
93
|
+
else:
|
|
94
|
+
oss_item.comment = 'transitive'
|
|
95
|
+
if f'{pod_oss_name_origin}({pod_oss_version})' in self.relation_tree:
|
|
96
|
+
dep_item.depends_on_raw = self.relation_tree[f'{pod_oss_name_origin}({pod_oss_version})']
|
|
97
|
+
|
|
98
|
+
oss_item.name = f'{self.package_manager_name}:{pod_oss_name_origin}'
|
|
99
|
+
pod_oss_name = pod_oss_name_origin
|
|
100
|
+
oss_item.version = pod_oss_version
|
|
101
|
+
if '/' in pod_oss_name_origin:
|
|
102
|
+
pod_oss_name = pod_oss_name_origin.split('/')[0]
|
|
103
|
+
if pod_oss_name in external_source_list:
|
|
104
|
+
oss_item.name = pod_oss_name_origin
|
|
105
|
+
podspec_filename = pod_oss_name + '.podspec.json'
|
|
106
|
+
spec_file_path = os.path.join("Pods", "Local Podspecs", podspec_filename)
|
|
107
|
+
else:
|
|
108
|
+
search_oss_name = ""
|
|
109
|
+
for alphabet_oss in pod_oss_name:
|
|
110
|
+
if not alphabet_oss.isalnum():
|
|
111
|
+
search_oss_name += f"\\\\{alphabet_oss}"
|
|
112
|
+
else:
|
|
113
|
+
search_oss_name += alphabet_oss
|
|
114
|
+
|
|
115
|
+
command = f"pod spec which --regex ^{search_oss_name}$"
|
|
116
|
+
spec_which = os.popen(command).readline()
|
|
117
|
+
if spec_which.startswith('[!]'):
|
|
118
|
+
logger.warning(f"This command({command}) returns an error")
|
|
119
|
+
continue
|
|
120
|
+
|
|
121
|
+
file_path = spec_which.rstrip().split(os.path.sep)
|
|
122
|
+
if file_path[0] == '':
|
|
123
|
+
file_path_without_version = os.path.join(os.sep, *file_path[:-2])
|
|
124
|
+
else:
|
|
125
|
+
file_path_without_version = os.path.join(*file_path[:-2])
|
|
126
|
+
spec_file_path = os.path.join(file_path_without_version, oss_item.version, file_path[-1])
|
|
127
|
+
|
|
128
|
+
oss_name, oss_version, oss_item.license, oss_item.download_location, \
|
|
129
|
+
oss_item.homepage = self.get_oss_in_podspec(spec_file_path)
|
|
130
|
+
dep_item.purl = get_url_to_purl(oss_item.homepage, self.package_manager_name, pod_oss_name_origin, oss_version)
|
|
131
|
+
purl_dict[f'{pod_oss_name_origin}({oss_version})'] = dep_item.purl
|
|
132
|
+
if pod_oss_name in external_source_list:
|
|
133
|
+
oss_item.homepage = ''
|
|
134
|
+
if oss_name == '':
|
|
135
|
+
continue
|
|
136
|
+
if oss_item.version != oss_version:
|
|
137
|
+
logger.warning(f'{pod_oss_name_origin} has different version({oss_item.version})\
|
|
138
|
+
with spec version({oss_version})')
|
|
139
|
+
dep_item.oss_items.append(oss_item)
|
|
140
|
+
self.dep_items.append(dep_item)
|
|
141
|
+
except Exception as e:
|
|
142
|
+
logger.warning(f"Fail to get {pod_oss_name_origin}:{e}")
|
|
143
|
+
if self.direct_dep:
|
|
144
|
+
self.dep_items = change_dependson_to_purl(purl_dict, self.dep_items)
|
|
145
|
+
|
|
146
|
+
return
|
|
147
|
+
|
|
148
|
+
def get_oss_in_podspec(self, spec_file_path):
|
|
149
|
+
oss_name = ''
|
|
150
|
+
oss_version = ''
|
|
151
|
+
license_name = ''
|
|
152
|
+
dn_loc = ''
|
|
153
|
+
homepage = ''
|
|
154
|
+
try:
|
|
155
|
+
with open(spec_file_path, 'r', encoding='utf8') as json_file:
|
|
156
|
+
json_data = json.load(json_file)
|
|
157
|
+
|
|
158
|
+
oss_origin_name = json_data['name']
|
|
159
|
+
oss_name = f"{self.package_manager_name}:{oss_origin_name}"
|
|
160
|
+
oss_version = json_data['version']
|
|
161
|
+
homepage = f"{self.dn_url}pods/{oss_origin_name}"
|
|
162
|
+
|
|
163
|
+
if 'license' in json_data:
|
|
164
|
+
if not isinstance(json_data['license'], str):
|
|
165
|
+
if 'type' in json_data['license']:
|
|
166
|
+
license_name = json_data['license']['type']
|
|
167
|
+
else:
|
|
168
|
+
license_name = json_data['license']
|
|
169
|
+
else:
|
|
170
|
+
license_name = ''
|
|
171
|
+
license_name = license_name.replace(",", "")
|
|
172
|
+
|
|
173
|
+
source_keys = [key for key in json_data['source']]
|
|
174
|
+
for src_type_i in _source_type:
|
|
175
|
+
if src_type_i in source_keys:
|
|
176
|
+
dn_loc = json_data['source'][src_type_i]
|
|
177
|
+
if dn_loc.endswith('.git'):
|
|
178
|
+
dn_loc = dn_loc[:-4]
|
|
179
|
+
except Exception as e:
|
|
180
|
+
logger.warning(f"Fail to get oss info in podspec:{e}")
|
|
181
|
+
|
|
182
|
+
return oss_name, oss_version, license_name, dn_loc, homepage
|
|
183
|
+
|
|
184
|
+
def parse_direct_dependencies(self):
|
|
185
|
+
self.direct_dep = True
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
def get_pods_info(pods_item):
|
|
189
|
+
pods_item_re = re.findall(r'(\S*)(?:\s{1}\((.*)\))?', pods_item)
|
|
190
|
+
|
|
191
|
+
oss_name = pods_item_re[0][0]
|
|
192
|
+
oss_version = pods_item_re[0][1]
|
|
193
|
+
|
|
194
|
+
return oss_name, oss_version
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
# Copyright (c) 2021 LG Electronics Inc.
|
|
4
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
|
|
6
|
+
import os
|
|
7
|
+
import logging
|
|
8
|
+
import subprocess
|
|
9
|
+
import json
|
|
10
|
+
from bs4 import BeautifulSoup
|
|
11
|
+
import urllib.request
|
|
12
|
+
import re
|
|
13
|
+
import shutil
|
|
14
|
+
import time
|
|
15
|
+
import fosslight_util.constant as constant
|
|
16
|
+
import fosslight_dependency.constant as const
|
|
17
|
+
from fosslight_dependency._package_manager import PackageManager, get_url_to_purl
|
|
18
|
+
from fosslight_dependency.dependency_item import DependencyItem, change_dependson_to_purl
|
|
19
|
+
from fosslight_util.oss_item import OssItem
|
|
20
|
+
|
|
21
|
+
logger = logging.getLogger(constant.LOGGER_NAME)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class Go(PackageManager):
|
|
25
|
+
package_manager_name = const.GO
|
|
26
|
+
|
|
27
|
+
input_file_name = ''
|
|
28
|
+
is_run_plugin = False
|
|
29
|
+
dn_url = 'https://pkg.go.dev/'
|
|
30
|
+
tmp_file_name = 'tmp_go_list.json'
|
|
31
|
+
go_work = 'go.work'
|
|
32
|
+
tmp_go_work = 'go.work.tmp'
|
|
33
|
+
|
|
34
|
+
def __init__(self, input_dir, output_dir):
|
|
35
|
+
super().__init__(self.package_manager_name, self.dn_url, input_dir, output_dir)
|
|
36
|
+
self.input_file_name = ''
|
|
37
|
+
self.is_run_plugin = False
|
|
38
|
+
|
|
39
|
+
def __del__(self):
|
|
40
|
+
if os.path.isfile(self.tmp_file_name):
|
|
41
|
+
os.remove(self.tmp_file_name)
|
|
42
|
+
if os.path.isfile(self.tmp_go_work):
|
|
43
|
+
shutil.move(self.tmp_go_work, self.go_work)
|
|
44
|
+
|
|
45
|
+
def parse_dependency_tree(self, go_deptree_txt):
|
|
46
|
+
for line in go_deptree_txt.split('\n'):
|
|
47
|
+
re_result = re.findall(r'(\S+)@v(\S+)\s(\S+)@v(\S+)', line)
|
|
48
|
+
if len(re_result) > 0 and len(re_result[0]) >= 4:
|
|
49
|
+
oss_name = re_result[0][0]
|
|
50
|
+
oss_ver = re_result[0][1]
|
|
51
|
+
pkg_name = re_result[0][2]
|
|
52
|
+
pkg_ver = re_result[0][3]
|
|
53
|
+
if f'{oss_name}({oss_ver})' not in self.relation_tree:
|
|
54
|
+
self.relation_tree[f'{oss_name}({oss_ver})'] = []
|
|
55
|
+
self.relation_tree[f'{oss_name}({oss_ver})'].append(f'{pkg_name}({pkg_ver})')
|
|
56
|
+
|
|
57
|
+
def run_plugin(self):
|
|
58
|
+
ret = True
|
|
59
|
+
|
|
60
|
+
if os.path.isfile(self.go_work):
|
|
61
|
+
shutil.move(self.go_work, self.tmp_go_work)
|
|
62
|
+
|
|
63
|
+
logger.info("Execute 'go list -m -mod=mod -json all' to obtain package info.")
|
|
64
|
+
cmd = f"go list -m -mod=mod -json all > {self.tmp_file_name}"
|
|
65
|
+
|
|
66
|
+
ret_cmd = subprocess.call(cmd, shell=True)
|
|
67
|
+
if ret_cmd != 0:
|
|
68
|
+
logger.error(f"Failed to make the result: {cmd}")
|
|
69
|
+
ret = False
|
|
70
|
+
|
|
71
|
+
self.append_input_package_list_file(self.tmp_file_name)
|
|
72
|
+
|
|
73
|
+
cmd_tree = "go mod graph"
|
|
74
|
+
ret_cmd_tree = subprocess.check_output(cmd_tree, shell=True, text=True, encoding='utf-8')
|
|
75
|
+
if ret_cmd_tree != 0:
|
|
76
|
+
self.parse_dependency_tree(ret_cmd_tree)
|
|
77
|
+
|
|
78
|
+
if os.path.isfile(self.tmp_go_work):
|
|
79
|
+
shutil.move(self.tmp_go_work, self.go_work)
|
|
80
|
+
return ret
|
|
81
|
+
|
|
82
|
+
def parse_oss_information(self, f_name):
|
|
83
|
+
indirect = 'Indirect'
|
|
84
|
+
purl_dict = {}
|
|
85
|
+
json_list = []
|
|
86
|
+
with open(f_name, 'r', encoding='utf8') as input_fp:
|
|
87
|
+
json_data_raw = ''
|
|
88
|
+
for line in input_fp.readlines():
|
|
89
|
+
json_data_raw += line
|
|
90
|
+
if line.startswith('}'):
|
|
91
|
+
json_list.append(json.loads(json_data_raw))
|
|
92
|
+
json_data_raw = ''
|
|
93
|
+
|
|
94
|
+
for dep_i in json_list:
|
|
95
|
+
dep_item = DependencyItem()
|
|
96
|
+
oss_item = OssItem()
|
|
97
|
+
try:
|
|
98
|
+
if 'Main' in dep_i:
|
|
99
|
+
if dep_i['Main']:
|
|
100
|
+
continue
|
|
101
|
+
package_path = dep_i['Path']
|
|
102
|
+
oss_item.name = f"{self.package_manager_name}:{package_path}"
|
|
103
|
+
oss_origin_version = dep_i['Version']
|
|
104
|
+
if oss_origin_version.startswith('v'):
|
|
105
|
+
oss_item.version = oss_origin_version[1:]
|
|
106
|
+
else:
|
|
107
|
+
oss_item.version = oss_origin_version
|
|
108
|
+
|
|
109
|
+
if self.direct_dep:
|
|
110
|
+
if indirect in dep_i:
|
|
111
|
+
if dep_i[indirect]:
|
|
112
|
+
oss_item.comment = 'transitive'
|
|
113
|
+
else:
|
|
114
|
+
oss_item.comment = 'direct'
|
|
115
|
+
else:
|
|
116
|
+
oss_item.comment = 'direct'
|
|
117
|
+
|
|
118
|
+
if f'{package_path}({oss_item.version})' in self.relation_tree:
|
|
119
|
+
dep_item.depends_on_raw = self.relation_tree[f'{package_path}({oss_item.version})']
|
|
120
|
+
|
|
121
|
+
dn_loc_set = []
|
|
122
|
+
tmp_dn_loc = self.dn_url + package_path
|
|
123
|
+
dep_item.purl = get_url_to_purl(f"{tmp_dn_loc}@{oss_item.version}", self.package_manager_name)
|
|
124
|
+
purl_dict[f'{package_path}({oss_item.version})'] = dep_item.purl
|
|
125
|
+
|
|
126
|
+
if oss_origin_version:
|
|
127
|
+
oss_item.download_location = f"{tmp_dn_loc}@{oss_origin_version}"
|
|
128
|
+
dn_loc_set.append(oss_item.download_location)
|
|
129
|
+
dn_loc_set.append(tmp_dn_loc)
|
|
130
|
+
|
|
131
|
+
for dn_loc_i in dn_loc_set:
|
|
132
|
+
urlopen_success = False
|
|
133
|
+
while True:
|
|
134
|
+
try:
|
|
135
|
+
res = urllib.request.urlopen(dn_loc_i)
|
|
136
|
+
if res.getcode() == 200:
|
|
137
|
+
urlopen_success = True
|
|
138
|
+
if dn_loc_i == tmp_dn_loc:
|
|
139
|
+
if oss_item.version:
|
|
140
|
+
oss_item.comment = (f'Not found {oss_item.download_location}, '
|
|
141
|
+
'get info from latest version.')
|
|
142
|
+
oss_item.download_location = tmp_dn_loc
|
|
143
|
+
break
|
|
144
|
+
except urllib.error.HTTPError as e:
|
|
145
|
+
if e.code == 429:
|
|
146
|
+
logger.info(f"{e} ({dn_loc_i}), Retrying to connect after 20 seconds")
|
|
147
|
+
time.sleep(20)
|
|
148
|
+
continue
|
|
149
|
+
else:
|
|
150
|
+
logger.info(f"{e} ({dn_loc_i})")
|
|
151
|
+
break
|
|
152
|
+
except Exception as e:
|
|
153
|
+
logger.warning(f"{e} ({dn_loc_i})")
|
|
154
|
+
break
|
|
155
|
+
if urlopen_success:
|
|
156
|
+
break
|
|
157
|
+
|
|
158
|
+
if urlopen_success:
|
|
159
|
+
content = res.read().decode('utf8')
|
|
160
|
+
bs_obj = BeautifulSoup(content, 'html.parser')
|
|
161
|
+
|
|
162
|
+
license_data = bs_obj.find('a', {'data-test-id': 'UnitHeader-license'})
|
|
163
|
+
if license_data:
|
|
164
|
+
oss_item.license = license_data.text
|
|
165
|
+
|
|
166
|
+
repository_data = bs_obj.find('div', {'class': 'UnitMeta-repo'})
|
|
167
|
+
if repository_data:
|
|
168
|
+
oss_item.homepage = repository_data.find('a')['href']
|
|
169
|
+
else:
|
|
170
|
+
oss_item.homepage = oss_item.download_location
|
|
171
|
+
|
|
172
|
+
except Exception as e:
|
|
173
|
+
logging.warning(f"Fail to parse {package_path} in go mod : {e}")
|
|
174
|
+
continue
|
|
175
|
+
dep_item.oss_items.append(oss_item)
|
|
176
|
+
self.dep_items.append(dep_item)
|
|
177
|
+
if self.direct_dep:
|
|
178
|
+
self.dep_items = change_dependson_to_purl(purl_dict, self.dep_items)
|
|
179
|
+
return
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
# Copyright (c) 2021 LG Electronics Inc.
|
|
4
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
|
|
6
|
+
import os
|
|
7
|
+
import logging
|
|
8
|
+
import json
|
|
9
|
+
import fosslight_util.constant as constant
|
|
10
|
+
import fosslight_dependency.constant as const
|
|
11
|
+
from fosslight_dependency._package_manager import PackageManager
|
|
12
|
+
from fosslight_dependency._package_manager import version_refine, get_url_to_purl
|
|
13
|
+
from fosslight_dependency.dependency_item import DependencyItem, change_dependson_to_purl
|
|
14
|
+
from fosslight_util.get_pom_license import get_license_from_pom
|
|
15
|
+
from fosslight_util.oss_item import OssItem
|
|
16
|
+
|
|
17
|
+
logger = logging.getLogger(constant.LOGGER_NAME)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class Gradle(PackageManager):
|
|
21
|
+
package_manager_name = const.GRADLE
|
|
22
|
+
|
|
23
|
+
dn_url = 'https://mvnrepository.com/artifact/'
|
|
24
|
+
input_file_name = os.path.join('build', 'reports', 'license', 'dependency-license.json')
|
|
25
|
+
|
|
26
|
+
def __init__(self, input_dir, output_dir, output_custom_dir):
|
|
27
|
+
super().__init__(self.package_manager_name, self.dn_url, input_dir, output_dir)
|
|
28
|
+
|
|
29
|
+
if output_custom_dir:
|
|
30
|
+
self.output_custom_dir = output_custom_dir
|
|
31
|
+
self.input_file_name = os.path.join(output_custom_dir, os.sep.join(self.input_file_name.split(os.sep)[1:]))
|
|
32
|
+
|
|
33
|
+
self.append_input_package_list_file(self.input_file_name)
|
|
34
|
+
|
|
35
|
+
def parse_oss_information(self, f_name):
|
|
36
|
+
with open(f_name, 'r', encoding='utf8') as json_file:
|
|
37
|
+
json_data = json.load(json_file)
|
|
38
|
+
|
|
39
|
+
purl_dict = {}
|
|
40
|
+
|
|
41
|
+
for d in json_data['dependencies']:
|
|
42
|
+
dep_item = DependencyItem()
|
|
43
|
+
oss_item = OssItem()
|
|
44
|
+
used_filename = False
|
|
45
|
+
group_id = ""
|
|
46
|
+
artifact_id = ""
|
|
47
|
+
|
|
48
|
+
name = d['name']
|
|
49
|
+
filename = d['file']
|
|
50
|
+
|
|
51
|
+
if name != filename:
|
|
52
|
+
group_id, artifact_id, oss_ini_version = parse_oss_name_version_in_artifactid(name)
|
|
53
|
+
oss_name = f"{group_id}:{artifact_id}"
|
|
54
|
+
else:
|
|
55
|
+
oss_name, oss_ini_version = parse_oss_name_version_in_filename(filename)
|
|
56
|
+
used_filename = True
|
|
57
|
+
oss_item.name = oss_name
|
|
58
|
+
dep_key = f"{oss_item.name}({oss_ini_version})"
|
|
59
|
+
if self.total_dep_list:
|
|
60
|
+
if dep_key not in self.total_dep_list:
|
|
61
|
+
continue
|
|
62
|
+
|
|
63
|
+
oss_item.version = version_refine(oss_ini_version)
|
|
64
|
+
|
|
65
|
+
try:
|
|
66
|
+
license_names = []
|
|
67
|
+
for licenses in d['licenses']:
|
|
68
|
+
if licenses['name'] != '':
|
|
69
|
+
license_names.append(licenses['name'].replace(",", ""))
|
|
70
|
+
oss_item.license = ', '.join(license_names)
|
|
71
|
+
except Exception:
|
|
72
|
+
logger.info("Cannot find the license name")
|
|
73
|
+
if not oss_item.license:
|
|
74
|
+
license_names = get_license_from_pom(group_id, artifact_id, oss_ini_version)
|
|
75
|
+
if license_names:
|
|
76
|
+
oss_item.license = license_names
|
|
77
|
+
|
|
78
|
+
if used_filename or group_id == "":
|
|
79
|
+
oss_item.download_location = 'Unknown'
|
|
80
|
+
else:
|
|
81
|
+
oss_item.download_location = f"{self.dn_url}{group_id}/{artifact_id}/{oss_ini_version}"
|
|
82
|
+
oss_item.homepage = f"{self.dn_url}{group_id}/{artifact_id}"
|
|
83
|
+
dep_item.purl = get_url_to_purl(oss_item.download_location, 'maven')
|
|
84
|
+
purl_dict[f'{oss_item.name}({oss_ini_version})'] = dep_item.purl
|
|
85
|
+
|
|
86
|
+
if self.direct_dep:
|
|
87
|
+
if len(self.direct_dep_list) > 0:
|
|
88
|
+
if dep_key in self.direct_dep_list:
|
|
89
|
+
oss_item.comment = 'direct'
|
|
90
|
+
else:
|
|
91
|
+
oss_item.comment = 'transitive'
|
|
92
|
+
try:
|
|
93
|
+
if dep_key in self.relation_tree:
|
|
94
|
+
dep_item.depends_on_raw = self.relation_tree[dep_key]
|
|
95
|
+
except Exception as e:
|
|
96
|
+
logger.error(f"Fail to find oss scope in dependency tree: {e}")
|
|
97
|
+
|
|
98
|
+
dep_item.oss_items.append(oss_item)
|
|
99
|
+
self.dep_items.append(dep_item)
|
|
100
|
+
|
|
101
|
+
if self.direct_dep:
|
|
102
|
+
self.dep_items = change_dependson_to_purl(purl_dict, self.dep_items)
|
|
103
|
+
return
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
def parse_oss_name_version_in_filename(name):
|
|
107
|
+
filename = name.rstrip('.jar')
|
|
108
|
+
split_name = filename.rpartition('-')
|
|
109
|
+
|
|
110
|
+
oss_name = split_name[0]
|
|
111
|
+
oss_version = split_name[2]
|
|
112
|
+
|
|
113
|
+
return oss_name, oss_version
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
def parse_oss_name_version_in_artifactid(name):
|
|
117
|
+
artifact_comp = name.split(':')
|
|
118
|
+
|
|
119
|
+
group_id = artifact_comp[0]
|
|
120
|
+
artifact_id = artifact_comp[1]
|
|
121
|
+
oss_version = artifact_comp[2]
|
|
122
|
+
|
|
123
|
+
return group_id, artifact_id, oss_version
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
# Copyright (c) 2023 LG Electronics Inc.
|
|
4
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
|
|
6
|
+
import os
|
|
7
|
+
import logging
|
|
8
|
+
import subprocess
|
|
9
|
+
import yaml
|
|
10
|
+
import shutil
|
|
11
|
+
import fosslight_util.constant as constant
|
|
12
|
+
import fosslight_dependency.constant as const
|
|
13
|
+
from fosslight_dependency._package_manager import PackageManager, get_url_to_purl
|
|
14
|
+
from fosslight_util.download import extract_compressed_dir
|
|
15
|
+
from fosslight_dependency.dependency_item import DependencyItem
|
|
16
|
+
from fosslight_util.oss_item import OssItem
|
|
17
|
+
|
|
18
|
+
logger = logging.getLogger(constant.LOGGER_NAME)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class Helm(PackageManager):
|
|
22
|
+
package_manager_name = const.HELM
|
|
23
|
+
tmp_charts_dir = 'tmp_charts'
|
|
24
|
+
|
|
25
|
+
input_file_name = const.SUPPORT_PACKAE.get(package_manager_name)
|
|
26
|
+
|
|
27
|
+
def __init__(self, input_dir, output_dir):
|
|
28
|
+
super().__init__(self.package_manager_name, '', input_dir, output_dir)
|
|
29
|
+
self.append_input_package_list_file(self.input_file_name)
|
|
30
|
+
|
|
31
|
+
def __del__(self):
|
|
32
|
+
if os.path.exists(self.tmp_charts_dir):
|
|
33
|
+
shutil.rmtree(self.tmp_charts_dir, ignore_errors=True)
|
|
34
|
+
|
|
35
|
+
def run_plugin(self):
|
|
36
|
+
ret = True
|
|
37
|
+
charts_dir = 'charts'
|
|
38
|
+
if os.path.isdir(charts_dir):
|
|
39
|
+
shutil.copytree(charts_dir, self.tmp_charts_dir)
|
|
40
|
+
else:
|
|
41
|
+
logger.info("Execute 'helm dependency build' to obtain package info.")
|
|
42
|
+
cmd = "helm dependency build"
|
|
43
|
+
|
|
44
|
+
ret_cmd = subprocess.call(cmd, shell=True)
|
|
45
|
+
if ret_cmd != 0:
|
|
46
|
+
logger.error(f"Failed to build helm dependency: {cmd}")
|
|
47
|
+
ret = False
|
|
48
|
+
else:
|
|
49
|
+
if not os.path.isdir(charts_dir):
|
|
50
|
+
logger.warning(f"Cannot create {charts_dir} because of no dependencies in Chart.yaml. "
|
|
51
|
+
f"So you don't need to analyze dependency.")
|
|
52
|
+
return True
|
|
53
|
+
else:
|
|
54
|
+
shutil.copytree(charts_dir, self.tmp_charts_dir)
|
|
55
|
+
shutil.rmtree(charts_dir, ignore_errors=True)
|
|
56
|
+
if ret:
|
|
57
|
+
ret = extract_compressed_dir(self.tmp_charts_dir, self.tmp_charts_dir, False)
|
|
58
|
+
if not ret:
|
|
59
|
+
logger.error(f'Fail to extract compressed dir: {self.tmp_charts_dir}')
|
|
60
|
+
else:
|
|
61
|
+
logger.warning('Success to extract compressed dir')
|
|
62
|
+
|
|
63
|
+
return ret
|
|
64
|
+
|
|
65
|
+
def parse_oss_information(self, f_name):
|
|
66
|
+
dep_item_list = []
|
|
67
|
+
_dependencies = 'dependencies'
|
|
68
|
+
|
|
69
|
+
with open(f_name, 'r', encoding='utf8') as yaml_fp:
|
|
70
|
+
yaml_f = yaml.safe_load(yaml_fp)
|
|
71
|
+
if _dependencies in yaml_f:
|
|
72
|
+
for dep in yaml_f[_dependencies]:
|
|
73
|
+
dep_item_list.append(dep['name'])
|
|
74
|
+
for dep in dep_item_list:
|
|
75
|
+
try:
|
|
76
|
+
f_path = os.path.join(self.tmp_charts_dir, dep, f_name)
|
|
77
|
+
dep_item = DependencyItem()
|
|
78
|
+
oss_item = OssItem()
|
|
79
|
+
with open(f_path, 'r', encoding='utf8') as yaml_fp:
|
|
80
|
+
yaml_f = yaml.safe_load(yaml_fp)
|
|
81
|
+
oss_item.name = f'{self.package_manager_name}:{yaml_f["name"]}'
|
|
82
|
+
oss_item.version = yaml_f.get('version', '')
|
|
83
|
+
if oss_item.version.startswith('v'):
|
|
84
|
+
oss_item.version = oss_item.version[1:]
|
|
85
|
+
|
|
86
|
+
oss_item.homepage = yaml_f.get('home', '')
|
|
87
|
+
if yaml_f.get('sources', '') != '':
|
|
88
|
+
oss_item.download_location = yaml_f.get('sources', '')[0]
|
|
89
|
+
|
|
90
|
+
dep_item.purl = get_url_to_purl(
|
|
91
|
+
oss_item.download_location if oss_item.download_location else oss_item.homepage,
|
|
92
|
+
self.package_manager_name
|
|
93
|
+
)
|
|
94
|
+
|
|
95
|
+
if yaml_f.get('annotations', '') != '':
|
|
96
|
+
oss_item.license = yaml_f['annotations'].get('licenses', '')
|
|
97
|
+
|
|
98
|
+
if self.direct_dep:
|
|
99
|
+
oss_item.comment = 'direct'
|
|
100
|
+
|
|
101
|
+
except Exception as e:
|
|
102
|
+
logging.warning(f"Fail to parse chart info {dep}: {e}")
|
|
103
|
+
continue
|
|
104
|
+
dep_item.oss_items.append(oss_item)
|
|
105
|
+
self.dep_items.append(dep_item)
|
|
106
|
+
return
|