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.
Files changed (46) hide show
  1. fosslight_dependency/LICENSES/LICENSE +201 -0
  2. fosslight_dependency/LICENSES/LicenseRef-3rd_party_licenses.txt +1254 -0
  3. fosslight_dependency/__init__.py +0 -1
  4. fosslight_dependency/_analyze_dependency.py +130 -0
  5. fosslight_dependency/_graph_convertor.py +67 -0
  6. fosslight_dependency/_help.py +79 -0
  7. fosslight_dependency/_package_manager.py +397 -0
  8. fosslight_dependency/cli.py +127 -0
  9. fosslight_dependency/constant.py +57 -0
  10. fosslight_dependency/dependency_item.py +103 -0
  11. fosslight_dependency/package_manager/Android.py +90 -0
  12. fosslight_dependency/package_manager/Cargo.py +144 -0
  13. fosslight_dependency/package_manager/Carthage.py +130 -0
  14. fosslight_dependency/package_manager/Cocoapods.py +194 -0
  15. fosslight_dependency/package_manager/Go.py +179 -0
  16. fosslight_dependency/package_manager/Gradle.py +123 -0
  17. fosslight_dependency/package_manager/Helm.py +106 -0
  18. fosslight_dependency/package_manager/Maven.py +274 -0
  19. fosslight_dependency/package_manager/Npm.py +296 -0
  20. fosslight_dependency/package_manager/Nuget.py +368 -0
  21. fosslight_dependency/package_manager/Pnpm.py +155 -0
  22. fosslight_dependency/package_manager/Pub.py +241 -0
  23. fosslight_dependency/package_manager/Pypi.py +395 -0
  24. fosslight_dependency/package_manager/Swift.py +159 -0
  25. fosslight_dependency/package_manager/Unity.py +118 -0
  26. fosslight_dependency/package_manager/Yarn.py +231 -0
  27. fosslight_dependency/package_manager/__init__.py +0 -0
  28. fosslight_dependency/run_dependency_scanner.py +393 -0
  29. fosslight_dependency-4.1.30.dist-info/METADATA +213 -0
  30. fosslight_dependency-4.1.30.dist-info/RECORD +37 -0
  31. {fosslight_dependency-3.0.7.dist-info → fosslight_dependency-4.1.30.dist-info}/WHEEL +1 -1
  32. fosslight_dependency-4.1.30.dist-info/entry_points.txt +2 -0
  33. fosslight_dependency-4.1.30.dist-info/licenses/LICENSES/Apache-2.0.txt +201 -0
  34. fosslight_dependency-4.1.30.dist-info/licenses/LICENSES/LicenseRef-3rd_party_licenses.txt +1254 -0
  35. fosslight_dependency-4.1.30.dist-info/licenses/LICENSES/MIT.txt +21 -0
  36. fosslight_dependency/_version.py +0 -1
  37. fosslight_dependency/analyze_dependency.py +0 -1090
  38. fosslight_dependency/third_party/askalono/askalono.exe +0 -0
  39. fosslight_dependency/third_party/askalono/askalono_macos +0 -0
  40. fosslight_dependency/third_party/nomos/nomossa +0 -0
  41. fosslight_dependency-3.0.7.dist-info/3rd_party_licenses.txt +0 -726
  42. fosslight_dependency-3.0.7.dist-info/METADATA +0 -51
  43. fosslight_dependency-3.0.7.dist-info/RECORD +0 -13
  44. fosslight_dependency-3.0.7.dist-info/entry_points.txt +0 -3
  45. {fosslight_dependency-3.0.7.dist-info → fosslight_dependency-4.1.30.dist-info/licenses}/LICENSE +0 -0
  46. {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