fosslight-dependency 4.1.21__tar.gz → 4.1.22__tar.gz
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-4.1.21 → fosslight_dependency-4.1.22}/PKG-INFO +1 -1
- {fosslight_dependency-4.1.21 → fosslight_dependency-4.1.22}/setup.py +1 -1
- {fosslight_dependency-4.1.21 → fosslight_dependency-4.1.22}/src/fosslight_dependency/_analyze_dependency.py +26 -3
- {fosslight_dependency-4.1.21 → fosslight_dependency-4.1.22}/src/fosslight_dependency/constant.py +1 -0
- {fosslight_dependency-4.1.21 → fosslight_dependency-4.1.22}/src/fosslight_dependency/package_manager/Maven.py +18 -13
- {fosslight_dependency-4.1.21 → fosslight_dependency-4.1.22}/src/fosslight_dependency/package_manager/Npm.py +8 -12
- {fosslight_dependency-4.1.21 → fosslight_dependency-4.1.22}/src/fosslight_dependency/package_manager/Pypi.py +1 -1
- fosslight_dependency-4.1.22/src/fosslight_dependency/package_manager/Yarn.py +222 -0
- {fosslight_dependency-4.1.21 → fosslight_dependency-4.1.22}/src/fosslight_dependency/run_dependency_scanner.py +31 -16
- {fosslight_dependency-4.1.21 → fosslight_dependency-4.1.22}/src/fosslight_dependency.egg-info/PKG-INFO +1 -1
- {fosslight_dependency-4.1.21 → fosslight_dependency-4.1.22}/src/fosslight_dependency.egg-info/SOURCES.txt +1 -0
- {fosslight_dependency-4.1.21 → fosslight_dependency-4.1.22}/LICENSE +0 -0
- {fosslight_dependency-4.1.21 → fosslight_dependency-4.1.22}/LICENSES/Apache-2.0.txt +0 -0
- {fosslight_dependency-4.1.21 → fosslight_dependency-4.1.22}/LICENSES/LicenseRef-3rd_party_licenses.txt +0 -0
- {fosslight_dependency-4.1.21 → fosslight_dependency-4.1.22}/LICENSES/MIT.txt +0 -0
- {fosslight_dependency-4.1.21 → fosslight_dependency-4.1.22}/MANIFEST.in +0 -0
- {fosslight_dependency-4.1.21 → fosslight_dependency-4.1.22}/README.md +0 -0
- {fosslight_dependency-4.1.21 → fosslight_dependency-4.1.22}/requirements.txt +0 -0
- {fosslight_dependency-4.1.21 → fosslight_dependency-4.1.22}/setup.cfg +0 -0
- {fosslight_dependency-4.1.21 → fosslight_dependency-4.1.22}/src/fosslight_dependency/LICENSES/LICENSE +0 -0
- {fosslight_dependency-4.1.21 → fosslight_dependency-4.1.22}/src/fosslight_dependency/LICENSES/LicenseRef-3rd_party_licenses.txt +0 -0
- {fosslight_dependency-4.1.21 → fosslight_dependency-4.1.22}/src/fosslight_dependency/__init__.py +0 -0
- {fosslight_dependency-4.1.21 → fosslight_dependency-4.1.22}/src/fosslight_dependency/_graph_convertor.py +0 -0
- {fosslight_dependency-4.1.21 → fosslight_dependency-4.1.22}/src/fosslight_dependency/_help.py +0 -0
- {fosslight_dependency-4.1.21 → fosslight_dependency-4.1.22}/src/fosslight_dependency/_package_manager.py +0 -0
- {fosslight_dependency-4.1.21 → fosslight_dependency-4.1.22}/src/fosslight_dependency/dependency_item.py +0 -0
- {fosslight_dependency-4.1.21 → fosslight_dependency-4.1.22}/src/fosslight_dependency/package_manager/Android.py +0 -0
- {fosslight_dependency-4.1.21 → fosslight_dependency-4.1.22}/src/fosslight_dependency/package_manager/Cargo.py +0 -0
- {fosslight_dependency-4.1.21 → fosslight_dependency-4.1.22}/src/fosslight_dependency/package_manager/Carthage.py +0 -0
- {fosslight_dependency-4.1.21 → fosslight_dependency-4.1.22}/src/fosslight_dependency/package_manager/Cocoapods.py +0 -0
- {fosslight_dependency-4.1.21 → fosslight_dependency-4.1.22}/src/fosslight_dependency/package_manager/Go.py +0 -0
- {fosslight_dependency-4.1.21 → fosslight_dependency-4.1.22}/src/fosslight_dependency/package_manager/Gradle.py +0 -0
- {fosslight_dependency-4.1.21 → fosslight_dependency-4.1.22}/src/fosslight_dependency/package_manager/Helm.py +0 -0
- {fosslight_dependency-4.1.21 → fosslight_dependency-4.1.22}/src/fosslight_dependency/package_manager/Nuget.py +0 -0
- {fosslight_dependency-4.1.21 → fosslight_dependency-4.1.22}/src/fosslight_dependency/package_manager/Pnpm.py +0 -0
- {fosslight_dependency-4.1.21 → fosslight_dependency-4.1.22}/src/fosslight_dependency/package_manager/Pub.py +0 -0
- {fosslight_dependency-4.1.21 → fosslight_dependency-4.1.22}/src/fosslight_dependency/package_manager/Swift.py +0 -0
- {fosslight_dependency-4.1.21 → fosslight_dependency-4.1.22}/src/fosslight_dependency/package_manager/Unity.py +0 -0
- {fosslight_dependency-4.1.21 → fosslight_dependency-4.1.22}/src/fosslight_dependency/package_manager/__init__.py +0 -0
- {fosslight_dependency-4.1.21 → fosslight_dependency-4.1.22}/src/fosslight_dependency.egg-info/dependency_links.txt +0 -0
- {fosslight_dependency-4.1.21 → fosslight_dependency-4.1.22}/src/fosslight_dependency.egg-info/entry_points.txt +0 -0
- {fosslight_dependency-4.1.21 → fosslight_dependency-4.1.22}/src/fosslight_dependency.egg-info/requires.txt +0 -0
- {fosslight_dependency-4.1.21 → fosslight_dependency-4.1.22}/src/fosslight_dependency.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: fosslight_dependency
|
|
3
|
-
Version: 4.1.
|
|
3
|
+
Version: 4.1.22
|
|
4
4
|
Summary: FOSSLight Dependency Scanner
|
|
5
5
|
Home-page: https://github.com/fosslight/fosslight_dependency_scanner
|
|
6
6
|
Download-URL: https://github.com/fosslight/fosslight_dependency_scanner
|
|
@@ -8,6 +8,7 @@ import logging
|
|
|
8
8
|
import fosslight_dependency.constant as const
|
|
9
9
|
from fosslight_dependency.package_manager.Pypi import Pypi
|
|
10
10
|
from fosslight_dependency.package_manager.Npm import Npm
|
|
11
|
+
from fosslight_dependency.package_manager.Yarn import Yarn
|
|
11
12
|
from fosslight_dependency.package_manager.Maven import Maven
|
|
12
13
|
from fosslight_dependency.package_manager.Gradle import Gradle
|
|
13
14
|
from fosslight_dependency.package_manager.Pub import Pub
|
|
@@ -32,11 +33,15 @@ def analyze_dependency(package_manager_name, input_dir, output_dir, pip_activate
|
|
|
32
33
|
ret = True
|
|
33
34
|
package_dep_item_list = []
|
|
34
35
|
cover_comment = ''
|
|
36
|
+
npm_fallback_to_yarn = False
|
|
35
37
|
|
|
36
38
|
if package_manager_name == const.PYPI:
|
|
37
39
|
package_manager = Pypi(input_dir, output_dir, pip_activate_cmd, pip_deactivate_cmd)
|
|
38
|
-
elif package_manager_name == const.NPM
|
|
40
|
+
elif package_manager_name == const.NPM:
|
|
39
41
|
package_manager = Npm(input_dir, output_dir)
|
|
42
|
+
npm_fallback_to_yarn = True
|
|
43
|
+
elif package_manager_name == const.YARN:
|
|
44
|
+
package_manager = Yarn(input_dir, output_dir)
|
|
40
45
|
elif package_manager_name == const.MAVEN:
|
|
41
46
|
package_manager = Maven(input_dir, output_dir, output_custom_dir)
|
|
42
47
|
elif package_manager_name == const.GRADLE:
|
|
@@ -66,7 +71,7 @@ def analyze_dependency(package_manager_name, input_dir, output_dir, pip_activate
|
|
|
66
71
|
else:
|
|
67
72
|
logger.error(f"Not supported package manager name: {package_manager_name}")
|
|
68
73
|
ret = False
|
|
69
|
-
return ret, package_dep_item_list
|
|
74
|
+
return ret, package_dep_item_list, cover_comment, package_manager_name
|
|
70
75
|
|
|
71
76
|
if manifest_file_name:
|
|
72
77
|
package_manager.set_manifest_file(manifest_file_name)
|
|
@@ -74,6 +79,24 @@ def analyze_dependency(package_manager_name, input_dir, output_dir, pip_activate
|
|
|
74
79
|
if direct:
|
|
75
80
|
package_manager.set_direct_dependencies(direct)
|
|
76
81
|
ret = package_manager.run_plugin()
|
|
82
|
+
|
|
83
|
+
if not ret and npm_fallback_to_yarn:
|
|
84
|
+
logger.warning("Npm analysis failed. Attempting to use Yarn as fallback...")
|
|
85
|
+
del package_manager
|
|
86
|
+
package_manager = Yarn(input_dir, output_dir)
|
|
87
|
+
package_manager_name = const.YARN
|
|
88
|
+
|
|
89
|
+
if manifest_file_name:
|
|
90
|
+
package_manager.set_manifest_file(manifest_file_name)
|
|
91
|
+
if direct:
|
|
92
|
+
package_manager.set_direct_dependencies(direct)
|
|
93
|
+
|
|
94
|
+
ret = package_manager.run_plugin()
|
|
95
|
+
if ret:
|
|
96
|
+
logger.info("Successfully switched to Yarn")
|
|
97
|
+
else:
|
|
98
|
+
logger.error("Yarn also failed")
|
|
99
|
+
|
|
77
100
|
if ret:
|
|
78
101
|
if direct:
|
|
79
102
|
package_manager.parse_direct_dependencies()
|
|
@@ -100,4 +123,4 @@ def analyze_dependency(package_manager_name, input_dir, output_dir, pip_activate
|
|
|
100
123
|
|
|
101
124
|
del package_manager
|
|
102
125
|
|
|
103
|
-
return ret, package_dep_item_list, cover_comment
|
|
126
|
+
return ret, package_dep_item_list, cover_comment, package_manager_name
|
|
@@ -46,12 +46,13 @@ class Maven(PackageManager):
|
|
|
46
46
|
ret = True
|
|
47
47
|
|
|
48
48
|
if not os.path.isfile(self.input_file_name):
|
|
49
|
-
self.is_run_plugin = True
|
|
50
49
|
pom_backup = 'pom.xml_backup'
|
|
51
50
|
|
|
52
51
|
ret = self.add_plugin_in_pom(pom_backup)
|
|
53
52
|
if ret:
|
|
54
|
-
self.run_maven_plugin()
|
|
53
|
+
ret_plugin = self.run_maven_plugin()
|
|
54
|
+
if ret_plugin:
|
|
55
|
+
self.is_run_plugin = True
|
|
55
56
|
|
|
56
57
|
if os.path.isfile(pom_backup):
|
|
57
58
|
shutil.move(pom_backup, const.SUPPORT_PACKAE.get(self.package_manager_name))
|
|
@@ -133,6 +134,7 @@ class Maven(PackageManager):
|
|
|
133
134
|
shutil.rmtree(top_path)
|
|
134
135
|
|
|
135
136
|
def run_maven_plugin(self):
|
|
137
|
+
ret_plugin = True
|
|
136
138
|
logger.info('Run maven license scanning plugin with temporary pom.xml')
|
|
137
139
|
current_mode = ''
|
|
138
140
|
if os.path.isfile('mvnw') or os.path.isfile('mvnw.cmd'):
|
|
@@ -148,21 +150,24 @@ class Maven(PackageManager):
|
|
|
148
150
|
ret = subprocess.call(cmd, shell=True)
|
|
149
151
|
if ret != 0:
|
|
150
152
|
logger.error(f"Failed to run maven plugin: {cmd}")
|
|
153
|
+
ret_plugin = False
|
|
151
154
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
155
|
+
if ret_plugin:
|
|
156
|
+
cmd = f"{cmd_mvn} dependency:tree"
|
|
157
|
+
try:
|
|
158
|
+
ret_txt = subprocess.check_output(cmd, text=True, shell=True)
|
|
159
|
+
if ret_txt is not None:
|
|
160
|
+
self.parse_dependency_tree(ret_txt)
|
|
161
|
+
self.set_direct_dependencies(True)
|
|
162
|
+
else:
|
|
163
|
+
logger.error(f"Failed to run: {cmd}")
|
|
164
|
+
self.set_direct_dependencies(False)
|
|
165
|
+
except Exception as e:
|
|
166
|
+
logger.error(f"Failed to run '{cmd}': {e}")
|
|
160
167
|
self.set_direct_dependencies(False)
|
|
161
|
-
except Exception as e:
|
|
162
|
-
logger.error(f"Failed to run '{cmd}': {e}")
|
|
163
|
-
self.set_direct_dependencies(False)
|
|
164
168
|
if current_mode:
|
|
165
169
|
change_file_mode(cmd_mvn, current_mode)
|
|
170
|
+
return ret_plugin
|
|
166
171
|
|
|
167
172
|
def create_dep_stack(self, dep_line):
|
|
168
173
|
dep_stack = []
|
|
@@ -53,14 +53,8 @@ class Npm(PackageManager):
|
|
|
53
53
|
self.flag_tmp_node_modules = True
|
|
54
54
|
cmd_ret = subprocess.call(npm_install_cmd, shell=True)
|
|
55
55
|
if cmd_ret != 0:
|
|
56
|
-
logger.
|
|
57
|
-
|
|
58
|
-
cmd_ret = subprocess.call(yarn_install_cmd, shell=True)
|
|
59
|
-
if cmd_ret != 0:
|
|
60
|
-
logger.error(f"Both {npm_install_cmd} and {yarn_install_cmd} failed")
|
|
61
|
-
return False
|
|
62
|
-
else:
|
|
63
|
-
logger.info(f"Successfully executed {yarn_install_cmd}")
|
|
56
|
+
logger.error(f"{npm_install_cmd} failed")
|
|
57
|
+
return False
|
|
64
58
|
|
|
65
59
|
# customized json file for obtaining specific items with license-checker
|
|
66
60
|
self.make_custom_json(self.tmp_custom_json)
|
|
@@ -115,13 +109,15 @@ class Npm(PackageManager):
|
|
|
115
109
|
cmd = 'npm ls -a --omit=dev --json -s'
|
|
116
110
|
result = subprocess.run(cmd, shell=True, capture_output=True, text=True, encoding='utf-8')
|
|
117
111
|
rel_tree = result.stdout
|
|
118
|
-
if rel_tree
|
|
119
|
-
logger.error(f"
|
|
120
|
-
|
|
112
|
+
if not rel_tree or rel_tree.strip() == '':
|
|
113
|
+
logger.error(f"No output for {cmd}, stderr: {result.stderr}")
|
|
114
|
+
ret = False
|
|
115
|
+
elif result.returncode > 1:
|
|
116
|
+
logger.error(f"'{cmd}' failed with exit code({result.returncode}), stderr: {result.stderr}")
|
|
121
117
|
ret = False
|
|
122
118
|
if ret:
|
|
123
119
|
if result.returncode == 1:
|
|
124
|
-
logger.
|
|
120
|
+
logger.debug(f"'{cmd}' has warnings: {result.stderr}")
|
|
125
121
|
|
|
126
122
|
try:
|
|
127
123
|
rel_json = json.loads(rel_tree)
|
|
@@ -239,7 +239,7 @@ class Pypi(PackageManager):
|
|
|
239
239
|
metadata = package.get('metadata', {})
|
|
240
240
|
package_name = metadata.get('name', '')
|
|
241
241
|
if package_name:
|
|
242
|
-
if package_name in ['pip', 'setuptools']:
|
|
242
|
+
if package_name in ['pip', 'setuptools', 'wheel']:
|
|
243
243
|
continue
|
|
244
244
|
self.total_dep_list.append(re.sub(r"[-_.]+", "-", package_name).lower())
|
|
245
245
|
else:
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
# Copyright (c) 2025 LG Electronics Inc.
|
|
4
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
|
|
6
|
+
import os
|
|
7
|
+
import logging
|
|
8
|
+
import subprocess
|
|
9
|
+
import json
|
|
10
|
+
import fosslight_util.constant as constant
|
|
11
|
+
import fosslight_dependency.constant as const
|
|
12
|
+
from fosslight_dependency.package_manager.Npm import Npm
|
|
13
|
+
from fosslight_dependency.dependency_item import DependencyItem, change_dependson_to_purl
|
|
14
|
+
from fosslight_util.oss_item import OssItem
|
|
15
|
+
from fosslight_dependency._package_manager import get_url_to_purl
|
|
16
|
+
from fosslight_dependency.package_manager.Npm import check_multi_license, check_unknown_license
|
|
17
|
+
|
|
18
|
+
logger = logging.getLogger(constant.LOGGER_NAME)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class Yarn(Npm):
|
|
22
|
+
|
|
23
|
+
def __init__(self, input_dir, output_dir):
|
|
24
|
+
super().__init__(input_dir, output_dir)
|
|
25
|
+
self.package_manager_name = const.YARN
|
|
26
|
+
self.yarn_version = None
|
|
27
|
+
|
|
28
|
+
def detect_yarn_version(self):
|
|
29
|
+
"""Detect Yarn version (1.x = Classic, 2+ = Berry)"""
|
|
30
|
+
if self.yarn_version is not None:
|
|
31
|
+
return self.yarn_version
|
|
32
|
+
|
|
33
|
+
try:
|
|
34
|
+
result = subprocess.run('yarn -v', shell=True, capture_output=True, text=True, encoding='utf-8')
|
|
35
|
+
if result.returncode == 0:
|
|
36
|
+
version_str = result.stdout.strip()
|
|
37
|
+
major_version = int(version_str.split('.')[0])
|
|
38
|
+
self.yarn_version = major_version
|
|
39
|
+
logger.info(f"Detected Yarn version: {version_str} (major: {major_version})")
|
|
40
|
+
return major_version
|
|
41
|
+
except Exception as e:
|
|
42
|
+
logger.warning(f"Failed to detect Yarn version: {e}")
|
|
43
|
+
return None
|
|
44
|
+
|
|
45
|
+
def start_license_checker(self):
|
|
46
|
+
ret = True
|
|
47
|
+
license_checker_cmd = f'license-checker --production --json --out {self.input_file_name}'
|
|
48
|
+
custom_path_option = ' --customPath '
|
|
49
|
+
node_modules = 'node_modules'
|
|
50
|
+
|
|
51
|
+
self.detect_yarn_version()
|
|
52
|
+
|
|
53
|
+
# For Yarn Berry (2+), check if using PnP mode
|
|
54
|
+
is_pnp_mode = False
|
|
55
|
+
if self.yarn_version and self.yarn_version >= 2:
|
|
56
|
+
# Check if .pnp.cjs exists (PnP mode indicator)
|
|
57
|
+
if os.path.exists('.pnp.cjs') or os.path.exists('.pnp.js'):
|
|
58
|
+
is_pnp_mode = True
|
|
59
|
+
logger.info("Detected Yarn Berry with PnP mode")
|
|
60
|
+
|
|
61
|
+
if not os.path.isdir(node_modules):
|
|
62
|
+
logger.info("node_modules directory does not exist.")
|
|
63
|
+
self.flag_tmp_node_modules = True
|
|
64
|
+
|
|
65
|
+
# For PnP mode, try to force node_modules creation
|
|
66
|
+
if is_pnp_mode:
|
|
67
|
+
logger.info("Attempting to create node_modules for PnP project...")
|
|
68
|
+
yarn_install_cmd = 'YARN_NODE_LINKER=node-modules yarn install --production --ignore-scripts'
|
|
69
|
+
logger.info(f"Executing: {yarn_install_cmd}")
|
|
70
|
+
else:
|
|
71
|
+
yarn_install_cmd = 'yarn install --production --ignore-scripts'
|
|
72
|
+
logger.info(f"Executing: {yarn_install_cmd}")
|
|
73
|
+
|
|
74
|
+
cmd_ret = subprocess.call(yarn_install_cmd, shell=True)
|
|
75
|
+
if cmd_ret != 0:
|
|
76
|
+
logger.error(f"{yarn_install_cmd} failed")
|
|
77
|
+
if is_pnp_mode:
|
|
78
|
+
logger.error("Yarn Berry PnP mode detected. Consider setting 'nodeLinker: node-modules' in .yarnrc.yml")
|
|
79
|
+
return False
|
|
80
|
+
else:
|
|
81
|
+
logger.info(f"Successfully executed {yarn_install_cmd}")
|
|
82
|
+
|
|
83
|
+
self.make_custom_json(self.tmp_custom_json)
|
|
84
|
+
|
|
85
|
+
cmd = license_checker_cmd + custom_path_option + self.tmp_custom_json
|
|
86
|
+
cmd_ret = subprocess.call(cmd, shell=True)
|
|
87
|
+
if cmd_ret != 0:
|
|
88
|
+
logger.error(f"It returns the error: {cmd}")
|
|
89
|
+
logger.error("Please check if the license-checker is installed.(sudo npm install -g license-checker)")
|
|
90
|
+
ret = False
|
|
91
|
+
else:
|
|
92
|
+
self.append_input_package_list_file(self.input_file_name)
|
|
93
|
+
if os.path.exists(self.tmp_custom_json):
|
|
94
|
+
os.remove(self.tmp_custom_json)
|
|
95
|
+
|
|
96
|
+
return ret
|
|
97
|
+
|
|
98
|
+
def parse_oss_information(self, f_name):
|
|
99
|
+
with open(f_name, 'r', encoding='utf8') as json_file:
|
|
100
|
+
json_data = json.load(json_file)
|
|
101
|
+
|
|
102
|
+
_licenses = 'licenses'
|
|
103
|
+
_repository = 'repository'
|
|
104
|
+
_private = 'private'
|
|
105
|
+
|
|
106
|
+
keys = [key for key in json_data]
|
|
107
|
+
purl_dict = {}
|
|
108
|
+
for i in range(0, len(keys)):
|
|
109
|
+
dep_item = DependencyItem()
|
|
110
|
+
oss_item = OssItem()
|
|
111
|
+
d = json_data.get(keys[i - 1])
|
|
112
|
+
oss_init_name = d['name']
|
|
113
|
+
oss_item.name = f'{const.NPM}:{oss_init_name}'
|
|
114
|
+
|
|
115
|
+
if d[_licenses]:
|
|
116
|
+
license_name = d[_licenses]
|
|
117
|
+
else:
|
|
118
|
+
license_name = ''
|
|
119
|
+
|
|
120
|
+
oss_item.version = d['version']
|
|
121
|
+
package_path = d['path']
|
|
122
|
+
|
|
123
|
+
private_pkg = False
|
|
124
|
+
if _private in d:
|
|
125
|
+
if d[_private]:
|
|
126
|
+
private_pkg = True
|
|
127
|
+
|
|
128
|
+
oss_item.download_location = f"{self.dn_url}{oss_init_name}/v/{oss_item.version}"
|
|
129
|
+
dn_loc = f"{self.dn_url}{oss_init_name}"
|
|
130
|
+
dep_item.purl = get_url_to_purl(oss_item.download_location, self.package_manager_name)
|
|
131
|
+
purl_dict[f'{oss_init_name}({oss_item.version})'] = dep_item.purl
|
|
132
|
+
if d[_repository]:
|
|
133
|
+
dn_loc = d[_repository]
|
|
134
|
+
elif private_pkg:
|
|
135
|
+
dn_loc = ''
|
|
136
|
+
|
|
137
|
+
oss_item.homepage = dn_loc
|
|
138
|
+
|
|
139
|
+
if private_pkg:
|
|
140
|
+
oss_item.download_location = oss_item.homepage
|
|
141
|
+
oss_item.comment = 'private'
|
|
142
|
+
if self.package_name == f'{oss_init_name}({oss_item.version})':
|
|
143
|
+
oss_item.comment = 'root package'
|
|
144
|
+
elif self.direct_dep and len(self.relation_tree) > 0:
|
|
145
|
+
if f'{oss_init_name}({oss_item.version})' in self.relation_tree[self.package_name]:
|
|
146
|
+
oss_item.comment = 'direct'
|
|
147
|
+
else:
|
|
148
|
+
oss_item.comment = 'transitive'
|
|
149
|
+
|
|
150
|
+
if f'{oss_init_name}({oss_item.version})' in self.relation_tree:
|
|
151
|
+
dep_item.depends_on_raw = self.relation_tree[f'{oss_init_name}({oss_item.version})']
|
|
152
|
+
|
|
153
|
+
# For Yarn, use 'package.json' instead of yarn.lock for license info
|
|
154
|
+
manifest_file_path = os.path.join(package_path, 'package.json')
|
|
155
|
+
multi_license, license_comment, multi_flag = check_multi_license(license_name, manifest_file_path)
|
|
156
|
+
|
|
157
|
+
if multi_flag:
|
|
158
|
+
oss_item.comment = license_comment
|
|
159
|
+
license_name = multi_license
|
|
160
|
+
else:
|
|
161
|
+
license_name = license_name.replace(",", "")
|
|
162
|
+
license_name = check_unknown_license(license_name, manifest_file_path)
|
|
163
|
+
oss_item.license = license_name
|
|
164
|
+
|
|
165
|
+
dep_item.oss_items.append(oss_item)
|
|
166
|
+
self.dep_items.append(dep_item)
|
|
167
|
+
|
|
168
|
+
if self.direct_dep:
|
|
169
|
+
self.dep_items = change_dependson_to_purl(purl_dict, self.dep_items)
|
|
170
|
+
return
|
|
171
|
+
|
|
172
|
+
def parse_rel_dependencies(self, rel_name, rel_ver, rel_dependencies):
|
|
173
|
+
"""Override to handle missing packages and packages without version"""
|
|
174
|
+
_dependencies = 'dependencies'
|
|
175
|
+
_version = 'version'
|
|
176
|
+
_peer = 'peerMissing'
|
|
177
|
+
_missing = 'missing'
|
|
178
|
+
|
|
179
|
+
for rel_dep_name in rel_dependencies.keys():
|
|
180
|
+
# Optional, non-installed dependencies are listed as empty objects
|
|
181
|
+
if rel_dependencies[rel_dep_name] == {}:
|
|
182
|
+
continue
|
|
183
|
+
if _peer in rel_dependencies[rel_dep_name]:
|
|
184
|
+
if rel_dependencies[rel_dep_name][_peer]:
|
|
185
|
+
continue
|
|
186
|
+
# Skip missing packages (not installed)
|
|
187
|
+
if _missing in rel_dependencies[rel_dep_name]:
|
|
188
|
+
if rel_dependencies[rel_dep_name][_missing]:
|
|
189
|
+
continue
|
|
190
|
+
# Skip if version key doesn't exist
|
|
191
|
+
if _version not in rel_dependencies[rel_dep_name]:
|
|
192
|
+
continue
|
|
193
|
+
|
|
194
|
+
if f'{rel_name}({rel_ver})' not in self.relation_tree:
|
|
195
|
+
self.relation_tree[f'{rel_name}({rel_ver})'] = []
|
|
196
|
+
elif f'{rel_dep_name}({rel_dependencies[rel_dep_name][_version]})' in self.relation_tree[f'{rel_name}({rel_ver})']:
|
|
197
|
+
continue
|
|
198
|
+
self.relation_tree[f'{rel_name}({rel_ver})'].append(f'{rel_dep_name}({rel_dependencies[rel_dep_name][_version]})')
|
|
199
|
+
if _dependencies in rel_dependencies[rel_dep_name]:
|
|
200
|
+
self.parse_rel_dependencies(rel_dep_name, rel_dependencies[rel_dep_name][_version],
|
|
201
|
+
rel_dependencies[rel_dep_name][_dependencies])
|
|
202
|
+
|
|
203
|
+
def parse_direct_dependencies(self):
|
|
204
|
+
if not self.direct_dep:
|
|
205
|
+
return
|
|
206
|
+
try:
|
|
207
|
+
# For Yarn, check if package.json exists (not yarn.lock)
|
|
208
|
+
# input_package_list_file[0] is the license-checker output file path
|
|
209
|
+
manifest_dir = os.path.dirname(self.input_package_list_file[0])
|
|
210
|
+
package_json_path = os.path.join(manifest_dir, 'package.json')
|
|
211
|
+
|
|
212
|
+
if os.path.isfile(package_json_path):
|
|
213
|
+
ret, err_msg = self.parse_transitive_relationship()
|
|
214
|
+
if not ret:
|
|
215
|
+
self.direct_dep = False
|
|
216
|
+
logger.warning(f'It cannot print direct/transitive dependency: {err_msg}')
|
|
217
|
+
else:
|
|
218
|
+
logger.info('Direct/transitive support is not possible because the package.json file does not exist.')
|
|
219
|
+
self.direct_dep = False
|
|
220
|
+
except Exception as e:
|
|
221
|
+
logger.warning(f'Cannot print direct/transitive dependency: {e}')
|
|
222
|
+
self.direct_dep = False
|
|
@@ -106,6 +106,22 @@ def find_package_manager(input_dir, abs_path_to_exclude=[], manifest_file_name=[
|
|
|
106
106
|
# both npm and pnpm are detected, remove npm.
|
|
107
107
|
if 'npm' in found_package_manager.keys() and 'pnpm' in found_package_manager.keys():
|
|
108
108
|
del found_package_manager['npm']
|
|
109
|
+
|
|
110
|
+
# both npm and yarn are detected, check which one to use based on lock file
|
|
111
|
+
if 'npm' in found_package_manager.keys() and 'yarn' in found_package_manager.keys():
|
|
112
|
+
# Remove npm from directories where yarn.lock exists
|
|
113
|
+
dirs_to_remove_from_npm = []
|
|
114
|
+
for yarn_dir in found_package_manager['yarn'].keys():
|
|
115
|
+
if yarn_dir in found_package_manager['npm']:
|
|
116
|
+
dirs_to_remove_from_npm.append(yarn_dir)
|
|
117
|
+
|
|
118
|
+
for dir_to_remove in dirs_to_remove_from_npm:
|
|
119
|
+
del found_package_manager['npm'][dir_to_remove]
|
|
120
|
+
|
|
121
|
+
# If npm has no directories left, remove it entirely
|
|
122
|
+
if not found_package_manager['npm']:
|
|
123
|
+
del found_package_manager['npm']
|
|
124
|
+
|
|
109
125
|
if len(found_package_manager) >= 1:
|
|
110
126
|
log_lines = ["\nDetected Manifest Files automatically"]
|
|
111
127
|
log_lines = print_package_info(found_package_manager, log_lines)
|
|
@@ -208,8 +224,6 @@ def run_dependency_scanner(package_manager='', input_dir='', output_dir_file='',
|
|
|
208
224
|
found_package_manager = {}
|
|
209
225
|
if package_manager:
|
|
210
226
|
scan_item.set_cover_comment(f"Manual detect mode (-m {package_manager})")
|
|
211
|
-
if package_manager == const.YARN:
|
|
212
|
-
package_manager = const.NPM
|
|
213
227
|
autodetect = False
|
|
214
228
|
support_packagemanager = list(const.SUPPORT_PACKAE.keys())
|
|
215
229
|
|
|
@@ -261,33 +275,34 @@ def run_dependency_scanner(package_manager='', input_dir='', output_dir_file='',
|
|
|
261
275
|
cover_comment = ''
|
|
262
276
|
for pm, manifest_file_name_list in found_package_manager.items():
|
|
263
277
|
if not manifest_file_name_list and not autodetect:
|
|
264
|
-
ret, package_dep_item_list, cover_comment = analyze_dependency(pm, input_dir, output_path,
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
278
|
+
ret, package_dep_item_list, cover_comment, actual_pm = analyze_dependency(pm, input_dir, output_path,
|
|
279
|
+
pip_activate_cmd, pip_deactivate_cmd,
|
|
280
|
+
output_custom_dir, app_name, github_token,
|
|
281
|
+
[], direct)
|
|
268
282
|
if ret:
|
|
269
|
-
success_pm[
|
|
283
|
+
success_pm[actual_pm][input_dir].extend(['manual mode (-m option)'])
|
|
270
284
|
scan_item.append_file_items(package_dep_item_list)
|
|
271
285
|
else:
|
|
272
|
-
fail_pm[
|
|
286
|
+
fail_pm[actual_pm][input_dir].extend(['manual mode (-m option)'])
|
|
273
287
|
else:
|
|
274
288
|
for manifest_dir, manifest_file_name in manifest_file_name_list.items():
|
|
275
289
|
input_dir = manifest_dir
|
|
276
290
|
if manifest_file_name == pass_key:
|
|
277
291
|
continue
|
|
278
292
|
os.chdir(input_dir)
|
|
279
|
-
ret, package_dep_item_list, cover_comment = analyze_dependency(pm, input_dir, output_path,
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
293
|
+
ret, package_dep_item_list, cover_comment, actual_pm = analyze_dependency(pm, input_dir, output_path,
|
|
294
|
+
pip_activate_cmd, pip_deactivate_cmd,
|
|
295
|
+
output_custom_dir, app_name,
|
|
296
|
+
github_token,
|
|
297
|
+
manifest_file_name, direct)
|
|
283
298
|
if ret:
|
|
284
|
-
success_pm[
|
|
299
|
+
success_pm[actual_pm][input_dir].extend(manifest_file_name)
|
|
285
300
|
scan_item.append_file_items(package_dep_item_list)
|
|
286
301
|
|
|
287
302
|
dup_pm = None
|
|
288
|
-
if
|
|
303
|
+
if actual_pm == const.GRADLE and const.ANDROID in found_package_manager:
|
|
289
304
|
dup_pm = const.ANDROID
|
|
290
|
-
elif
|
|
305
|
+
elif actual_pm == const.ANDROID and const.GRADLE in found_package_manager:
|
|
291
306
|
dup_pm = const.GRADLE
|
|
292
307
|
|
|
293
308
|
if dup_pm:
|
|
@@ -298,7 +313,7 @@ def run_dependency_scanner(package_manager='', input_dir='', output_dir_file='',
|
|
|
298
313
|
else:
|
|
299
314
|
found_package_manager[dup_pm][manifest_dir] = pass_key
|
|
300
315
|
else:
|
|
301
|
-
fail_pm[
|
|
316
|
+
fail_pm[actual_pm][input_dir].extend(manifest_file_name)
|
|
302
317
|
|
|
303
318
|
success_pm = {k: dict(v) for k, v in success_pm.items()}
|
|
304
319
|
fail_pm = {k: dict(v) for k, v in fail_pm.items()}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: fosslight-dependency
|
|
3
|
-
Version: 4.1.
|
|
3
|
+
Version: 4.1.22
|
|
4
4
|
Summary: FOSSLight Dependency Scanner
|
|
5
5
|
Home-page: https://github.com/fosslight/fosslight_dependency_scanner
|
|
6
6
|
Download-URL: https://github.com/fosslight/fosslight_dependency_scanner
|
|
@@ -38,4 +38,5 @@ src/fosslight_dependency/package_manager/Pub.py
|
|
|
38
38
|
src/fosslight_dependency/package_manager/Pypi.py
|
|
39
39
|
src/fosslight_dependency/package_manager/Swift.py
|
|
40
40
|
src/fosslight_dependency/package_manager/Unity.py
|
|
41
|
+
src/fosslight_dependency/package_manager/Yarn.py
|
|
41
42
|
src/fosslight_dependency/package_manager/__init__.py
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fosslight_dependency-4.1.21 → fosslight_dependency-4.1.22}/src/fosslight_dependency/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{fosslight_dependency-4.1.21 → fosslight_dependency-4.1.22}/src/fosslight_dependency/_help.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|