fosslight-dependency 4.1.7__tar.gz → 4.1.9__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.7 → fosslight_dependency-4.1.9}/PKG-INFO +3 -3
- {fosslight_dependency-4.1.7 → fosslight_dependency-4.1.9}/setup.py +5 -8
- {fosslight_dependency-4.1.7 → fosslight_dependency-4.1.9}/src/fosslight_dependency/_analyze_dependency.py +7 -1
- {fosslight_dependency-4.1.7 → fosslight_dependency-4.1.9}/src/fosslight_dependency/_help.py +2 -1
- {fosslight_dependency-4.1.7 → fosslight_dependency-4.1.9}/src/fosslight_dependency/_package_manager.py +21 -95
- {fosslight_dependency-4.1.7 → fosslight_dependency-4.1.9}/src/fosslight_dependency/constant.py +2 -0
- {fosslight_dependency-4.1.7 → fosslight_dependency-4.1.9}/src/fosslight_dependency/package_manager/Carthage.py +4 -6
- {fosslight_dependency-4.1.7 → fosslight_dependency-4.1.9}/src/fosslight_dependency/package_manager/Npm.py +1 -1
- {fosslight_dependency-4.1.7 → fosslight_dependency-4.1.9}/src/fosslight_dependency/package_manager/Nuget.py +6 -10
- fosslight_dependency-4.1.9/src/fosslight_dependency/package_manager/Pnpm.py +155 -0
- {fosslight_dependency-4.1.7 → fosslight_dependency-4.1.9}/src/fosslight_dependency/package_manager/Pub.py +2 -5
- {fosslight_dependency-4.1.7 → fosslight_dependency-4.1.9}/src/fosslight_dependency/package_manager/Pypi.py +3 -8
- {fosslight_dependency-4.1.7 → fosslight_dependency-4.1.9}/src/fosslight_dependency/package_manager/Swift.py +1 -1
- {fosslight_dependency-4.1.7 → fosslight_dependency-4.1.9}/src/fosslight_dependency/package_manager/Unity.py +3 -6
- {fosslight_dependency-4.1.7 → fosslight_dependency-4.1.9}/src/fosslight_dependency/run_dependency_scanner.py +55 -31
- {fosslight_dependency-4.1.7 → fosslight_dependency-4.1.9}/src/fosslight_dependency.egg-info/PKG-INFO +3 -3
- {fosslight_dependency-4.1.7 → fosslight_dependency-4.1.9}/src/fosslight_dependency.egg-info/SOURCES.txt +1 -0
- {fosslight_dependency-4.1.7 → fosslight_dependency-4.1.9}/LICENSE +0 -0
- {fosslight_dependency-4.1.7 → fosslight_dependency-4.1.9}/LICENSES/Apache-2.0.txt +0 -0
- {fosslight_dependency-4.1.7 → fosslight_dependency-4.1.9}/LICENSES/LicenseRef-3rd_party_licenses.txt +0 -0
- {fosslight_dependency-4.1.7 → fosslight_dependency-4.1.9}/LICENSES/MIT.txt +0 -0
- {fosslight_dependency-4.1.7 → fosslight_dependency-4.1.9}/MANIFEST.in +0 -0
- {fosslight_dependency-4.1.7 → fosslight_dependency-4.1.9}/README.md +0 -0
- {fosslight_dependency-4.1.7 → fosslight_dependency-4.1.9}/requirements.txt +0 -0
- {fosslight_dependency-4.1.7 → fosslight_dependency-4.1.9}/setup.cfg +0 -0
- {fosslight_dependency-4.1.7 → fosslight_dependency-4.1.9}/src/fosslight_dependency/__init__.py +0 -0
- {fosslight_dependency-4.1.7 → fosslight_dependency-4.1.9}/src/fosslight_dependency/_graph_convertor.py +0 -0
- {fosslight_dependency-4.1.7 → fosslight_dependency-4.1.9}/src/fosslight_dependency/dependency_item.py +0 -0
- {fosslight_dependency-4.1.7 → fosslight_dependency-4.1.9}/src/fosslight_dependency/package_manager/Android.py +0 -0
- {fosslight_dependency-4.1.7 → fosslight_dependency-4.1.9}/src/fosslight_dependency/package_manager/Cargo.py +0 -0
- {fosslight_dependency-4.1.7 → fosslight_dependency-4.1.9}/src/fosslight_dependency/package_manager/Cocoapods.py +0 -0
- {fosslight_dependency-4.1.7 → fosslight_dependency-4.1.9}/src/fosslight_dependency/package_manager/Go.py +0 -0
- {fosslight_dependency-4.1.7 → fosslight_dependency-4.1.9}/src/fosslight_dependency/package_manager/Gradle.py +0 -0
- {fosslight_dependency-4.1.7 → fosslight_dependency-4.1.9}/src/fosslight_dependency/package_manager/Helm.py +0 -0
- {fosslight_dependency-4.1.7 → fosslight_dependency-4.1.9}/src/fosslight_dependency/package_manager/Maven.py +0 -0
- {fosslight_dependency-4.1.7 → fosslight_dependency-4.1.9}/src/fosslight_dependency/package_manager/__init__.py +0 -0
- {fosslight_dependency-4.1.7 → fosslight_dependency-4.1.9}/src/fosslight_dependency.egg-info/dependency_links.txt +0 -0
- {fosslight_dependency-4.1.7 → fosslight_dependency-4.1.9}/src/fosslight_dependency.egg-info/entry_points.txt +0 -0
- {fosslight_dependency-4.1.7 → fosslight_dependency-4.1.9}/src/fosslight_dependency.egg-info/requires.txt +0 -0
- {fosslight_dependency-4.1.7 → fosslight_dependency-4.1.9}/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.9
|
4
4
|
Summary: FOSSLight Dependency Scanner
|
5
5
|
Home-page: https://github.com/fosslight/fosslight_dependency_scanner
|
6
6
|
Author: LG Electronics
|
@@ -164,8 +164,8 @@ Description: <!--
|
|
164
164
|
Platform: UNKNOWN
|
165
165
|
Classifier: License :: OSI Approved :: Apache Software License
|
166
166
|
Classifier: Programming Language :: Python :: 3
|
167
|
-
Classifier: Programming Language :: Python :: 3.6
|
168
|
-
Classifier: Programming Language :: Python :: 3.7
|
169
167
|
Classifier: Programming Language :: Python :: 3.8
|
170
168
|
Classifier: Programming Language :: Python :: 3.9
|
169
|
+
Classifier: Programming Language :: Python :: 3.10
|
170
|
+
Classifier: Programming Language :: Python :: 3.11
|
171
171
|
Description-Content-Type: text/markdown
|
@@ -35,7 +35,7 @@ if __name__ == "__main__":
|
|
35
35
|
|
36
36
|
setup(
|
37
37
|
name=_PACKAEG_NAME,
|
38
|
-
version='4.1.
|
38
|
+
version='4.1.9',
|
39
39
|
package_dir={"": "src"},
|
40
40
|
packages=find_namespace_packages(where='src'),
|
41
41
|
description='FOSSLight Dependency Scanner',
|
@@ -47,15 +47,12 @@ if __name__ == "__main__":
|
|
47
47
|
download_url='https://github.com/fosslight/fosslight_dependency_scanner',
|
48
48
|
classifiers=['License :: OSI Approved :: Apache Software License',
|
49
49
|
"Programming Language :: Python :: 3",
|
50
|
-
"Programming Language :: Python :: 3.6",
|
51
|
-
"Programming Language :: Python :: 3.7",
|
52
50
|
"Programming Language :: Python :: 3.8",
|
53
|
-
"Programming Language :: Python :: 3.9",
|
51
|
+
"Programming Language :: Python :: 3.9",
|
52
|
+
"Programming Language :: Python :: 3.10",
|
53
|
+
"Programming Language :: Python :: 3.11", ],
|
54
54
|
install_requires=required,
|
55
|
-
package_data={_PACKAEG_NAME: [os.path.join(
|
56
|
-
os.path.join('third_party', 'askalono', 'askalono.exe'),
|
57
|
-
os.path.join('third_party', 'askalono', 'askalono_macos'),
|
58
|
-
os.path.join(_LICENSE_DIR, '*')]},
|
55
|
+
package_data={_PACKAEG_NAME: [os.path.join(_LICENSE_DIR, '*')]},
|
59
56
|
include_package_data=True,
|
60
57
|
entry_points={
|
61
58
|
"console_scripts": [
|
@@ -20,6 +20,7 @@ from fosslight_dependency.package_manager.Nuget import Nuget
|
|
20
20
|
from fosslight_dependency.package_manager.Helm import Helm
|
21
21
|
from fosslight_dependency.package_manager.Unity import Unity
|
22
22
|
from fosslight_dependency.package_manager.Cargo import Cargo
|
23
|
+
from fosslight_dependency.package_manager.Pnpm import Pnpm
|
23
24
|
import fosslight_util.constant as constant
|
24
25
|
|
25
26
|
logger = logging.getLogger(constant.LOGGER_NAME)
|
@@ -60,6 +61,8 @@ def analyze_dependency(package_manager_name, input_dir, output_dir, pip_activate
|
|
60
61
|
package_manager = Unity(input_dir, output_dir)
|
61
62
|
elif package_manager_name == const.CARGO:
|
62
63
|
package_manager = Cargo(input_dir, output_dir)
|
64
|
+
elif package_manager_name == const.PNPM:
|
65
|
+
package_manager = Pnpm(input_dir, output_dir)
|
63
66
|
else:
|
64
67
|
logger.error(f"Not supported package manager name: {package_manager_name}")
|
65
68
|
ret = False
|
@@ -84,7 +87,10 @@ def analyze_dependency(package_manager_name, input_dir, output_dir, pip_activate
|
|
84
87
|
else:
|
85
88
|
logger.error(f"Failed to open input file: {f_name}")
|
86
89
|
ret = False
|
87
|
-
|
90
|
+
if package_manager_name == const.PNPM:
|
91
|
+
logger.info("Parse oss information for pnpm")
|
92
|
+
package_manager.parse_oss_information_for_pnpm()
|
93
|
+
package_dep_item_list.extend(package_manager.dep_items)
|
88
94
|
if ret:
|
89
95
|
logger.warning(f"### Complete to analyze: {package_manager_name}")
|
90
96
|
if package_manager.cover_comment:
|
@@ -15,6 +15,7 @@ _HELP_MESSAGE_DEPENDENCY = """
|
|
15
15
|
Gradle (Java)
|
16
16
|
Maven (Java)
|
17
17
|
NPM (Node.js)
|
18
|
+
PNPM (Node.js)
|
18
19
|
PIP (Python)
|
19
20
|
Pub (Dart with flutter)
|
20
21
|
Cocoapods (Swift/Obj-C)
|
@@ -32,7 +33,7 @@ _HELP_MESSAGE_DEPENDENCY = """
|
|
32
33
|
-v\t\t\t\t Print the version of the script.
|
33
34
|
-m <package_manager>\t Enter the package manager.
|
34
35
|
\t(npm, maven, gradle, pypi, pub, cocoapods, android, swift, carthage,
|
35
|
-
\t go, nuget, helm, unity, cargo)
|
36
|
+
\t go, nuget, helm, unity, cargo, pnpm)
|
36
37
|
-p <input_path>\t\t Enter the path where the script will be run.
|
37
38
|
-e <exclude_path>\t\t Enter the path where the analysis will not be performed.
|
38
39
|
-o <output_path>\t\t Output path
|
@@ -4,7 +4,6 @@
|
|
4
4
|
# SPDX-License-Identifier: Apache-2.0
|
5
5
|
|
6
6
|
import os
|
7
|
-
import sys
|
8
7
|
import logging
|
9
8
|
import platform
|
10
9
|
import re
|
@@ -12,9 +11,10 @@ import base64
|
|
12
11
|
import subprocess
|
13
12
|
import shutil
|
14
13
|
import stat
|
14
|
+
from packageurl.contrib import url2purl
|
15
|
+
from askalono import identify
|
15
16
|
import fosslight_util.constant as constant
|
16
17
|
import fosslight_dependency.constant as const
|
17
|
-
from packageurl.contrib import url2purl
|
18
18
|
|
19
19
|
try:
|
20
20
|
from github import Github
|
@@ -23,13 +23,9 @@ except Exception:
|
|
23
23
|
|
24
24
|
logger = logging.getLogger(constant.LOGGER_NAME)
|
25
25
|
|
26
|
-
# binary url to check license text
|
27
|
-
_license_scanner_linux = os.path.join('third_party', 'nomos', 'nomossa')
|
28
|
-
_license_scanner_macos = os.path.join('third_party', 'askalono', 'askalono_macos')
|
29
|
-
_license_scanner_windows = os.path.join('third_party', 'askalono', 'askalono.exe')
|
30
|
-
|
31
26
|
gradle_config = ['runtimeClasspath', 'runtime']
|
32
27
|
android_config = ['releaseRuntimeClasspath']
|
28
|
+
ASKALONO_THRESHOLD = 0.7
|
33
29
|
|
34
30
|
|
35
31
|
class PackageManager:
|
@@ -54,7 +50,6 @@ class PackageManager:
|
|
54
50
|
self.dep_items = []
|
55
51
|
|
56
52
|
self.platform = platform.system()
|
57
|
-
self.license_scanner_bin = check_license_scanner(self.platform)
|
58
53
|
|
59
54
|
def __del__(self):
|
60
55
|
self.input_package_list_file = []
|
@@ -113,7 +108,7 @@ class PackageManager:
|
|
113
108
|
cmd_gradle = "./gradlew"
|
114
109
|
else:
|
115
110
|
ret_task = False
|
116
|
-
logger.warning('No gradlew file exists
|
111
|
+
logger.warning('No gradlew file exists (Skip to find dependencies relationship.).')
|
117
112
|
if ret_plugin:
|
118
113
|
logger.warning('Also it cannot run android-dependency-scanning plugin.')
|
119
114
|
if ret_task:
|
@@ -126,11 +121,10 @@ class PackageManager:
|
|
126
121
|
self.parse_dependency_tree(ret)
|
127
122
|
else:
|
128
123
|
self.set_direct_dependencies(False)
|
129
|
-
logger.warning("
|
124
|
+
logger.warning(f"Fail to run {cmd}")
|
130
125
|
except Exception as e:
|
131
126
|
self.set_direct_dependencies(False)
|
132
|
-
logger.
|
133
|
-
logger.warning('It cannot print the direct/transitive dependencies relationship.')
|
127
|
+
logger.warning(f"Cannot print 'depends on' information. (fail {cmd}: {e})")
|
134
128
|
|
135
129
|
if ret_plugin:
|
136
130
|
cmd = f"{cmd_gradle} generateLicenseTxt"
|
@@ -157,6 +151,9 @@ class PackageManager:
|
|
157
151
|
if os.path.isfile(module_gradle_backup):
|
158
152
|
os.remove(module_build_gradle)
|
159
153
|
shutil.move(module_gradle_backup, module_build_gradle)
|
154
|
+
if os.path.isfile(self.input_file_name):
|
155
|
+
logger.info(f'Found {self.input_file_name}, skip to run plugin.')
|
156
|
+
ret_task = True
|
160
157
|
return ret_task
|
161
158
|
|
162
159
|
def add_android_plugin_in_gradle(self, module_build_gradle):
|
@@ -316,9 +313,8 @@ def connect_github(github_token):
|
|
316
313
|
return g
|
317
314
|
|
318
315
|
|
319
|
-
def get_github_license(g, github_repo
|
316
|
+
def get_github_license(g, github_repo):
|
320
317
|
license_name = ''
|
321
|
-
tmp_license_txt_file_name = 'tmp_license.txt'
|
322
318
|
|
323
319
|
try:
|
324
320
|
repository = g.get_repo(github_repo)
|
@@ -334,96 +330,26 @@ def get_github_license(g, github_repo, platform, license_scanner_bin):
|
|
334
330
|
if license_name == "" or license_name == "NOASSERTION":
|
335
331
|
try:
|
336
332
|
license_txt_data = base64.b64decode(repository.get_license().content).decode('utf-8')
|
337
|
-
|
338
|
-
tmp_license_txt.write(license_txt_data)
|
339
|
-
tmp_license_txt.close()
|
340
|
-
license_name = check_and_run_license_scanner(platform, license_scanner_bin, tmp_license_txt_file_name)
|
333
|
+
license_name = check_license_name(license_txt_data)
|
341
334
|
except Exception:
|
342
|
-
logger.info("Cannot find the license name with
|
343
|
-
|
344
|
-
if os.path.isfile(tmp_license_txt_file_name):
|
345
|
-
os.remove(tmp_license_txt_file_name)
|
335
|
+
logger.info("Cannot find the license name with askalono.")
|
346
336
|
except Exception:
|
347
337
|
logger.info("Cannot find the license name with github api.")
|
348
338
|
|
349
339
|
return license_name
|
350
340
|
|
351
341
|
|
352
|
-
def
|
353
|
-
license_scanner_bin = ''
|
354
|
-
|
355
|
-
if platform == const.LINUX:
|
356
|
-
license_scanner = _license_scanner_linux
|
357
|
-
elif platform == const.MACOS:
|
358
|
-
license_scanner = _license_scanner_macos
|
359
|
-
elif platform == const.WINDOWS:
|
360
|
-
license_scanner = _license_scanner_windows
|
361
|
-
else:
|
362
|
-
logger.debug("Not supported OS to analyze license text with binary.")
|
363
|
-
|
364
|
-
if license_scanner:
|
365
|
-
try:
|
366
|
-
base_path = sys._MEIPASS
|
367
|
-
except Exception:
|
368
|
-
base_path = os.path.dirname(__file__)
|
369
|
-
|
370
|
-
data_path = os.path.join(base_path, license_scanner)
|
371
|
-
license_scanner_bin = data_path
|
372
|
-
|
373
|
-
return license_scanner_bin
|
374
|
-
|
375
|
-
|
376
|
-
def check_and_run_license_scanner(platform, license_scanner_bin, file_dir):
|
342
|
+
def check_license_name(license_txt, is_filepath=False):
|
377
343
|
license_name = ''
|
344
|
+
if is_filepath:
|
345
|
+
with open(license_txt, 'r', encoding='utf-8') as f:
|
346
|
+
license_content = f.read()
|
347
|
+
else:
|
348
|
+
license_content = license_txt
|
378
349
|
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
try:
|
383
|
-
tmp_output_file_name = "tmp_license_scanner_output.txt"
|
384
|
-
|
385
|
-
if file_dir == "UNKNOWN":
|
386
|
-
license_name = ""
|
387
|
-
else:
|
388
|
-
if platform == const.LINUX:
|
389
|
-
run_license_scanner = f"{license_scanner_bin} {file_dir} > {tmp_output_file_name}"
|
390
|
-
elif platform == const.MACOS:
|
391
|
-
run_license_scanner = f"{license_scanner_bin} identify {file_dir} > {tmp_output_file_name}"
|
392
|
-
elif platform == const.WINDOWS:
|
393
|
-
run_license_scanner = f"{license_scanner_bin} identify {file_dir} > {tmp_output_file_name}"
|
394
|
-
else:
|
395
|
-
run_license_scanner = ''
|
396
|
-
|
397
|
-
if run_license_scanner is None:
|
398
|
-
license_name = ""
|
399
|
-
return license_name
|
400
|
-
else:
|
401
|
-
ret = subprocess.run(run_license_scanner, shell=True, stderr=subprocess.PIPE)
|
402
|
-
if ret.returncode != 0 or ret.stderr:
|
403
|
-
os.remove(tmp_output_file_name)
|
404
|
-
return ""
|
405
|
-
|
406
|
-
fp = open(tmp_output_file_name, "r", encoding='utf8')
|
407
|
-
license_output = fp.read()
|
408
|
-
fp.close()
|
409
|
-
|
410
|
-
if platform == const.LINUX:
|
411
|
-
license_output_re = re.findall(r'.*contains license\(s\)\s(.*)', license_output)
|
412
|
-
else:
|
413
|
-
license_output_re = re.findall(r"License:\s{1}(\S*)\s{1}", license_output)
|
414
|
-
|
415
|
-
if len(license_output_re) == 1:
|
416
|
-
license_name = license_output_re[0]
|
417
|
-
if license_name == "No_license_found":
|
418
|
-
license_name = ""
|
419
|
-
else:
|
420
|
-
license_name = ""
|
421
|
-
os.remove(tmp_output_file_name)
|
422
|
-
|
423
|
-
except Exception as ex:
|
424
|
-
logger.error(f"Failed to run license scan binary. {ex}")
|
425
|
-
license_name = ""
|
426
|
-
|
350
|
+
detect_askalono = identify(license_content)
|
351
|
+
if detect_askalono.score > ASKALONO_THRESHOLD:
|
352
|
+
license_name = detect_askalono.name
|
427
353
|
return license_name
|
428
354
|
|
429
355
|
|
{fosslight_dependency-4.1.7 → fosslight_dependency-4.1.9}/src/fosslight_dependency/constant.py
RENAMED
@@ -24,10 +24,12 @@ NUGET = 'nuget'
|
|
24
24
|
HELM = 'helm'
|
25
25
|
UNITY = 'unity'
|
26
26
|
CARGO = 'cargo'
|
27
|
+
PNPM = 'pnpm'
|
27
28
|
|
28
29
|
# Supported package name and manifest file
|
29
30
|
SUPPORT_PACKAE = {
|
30
31
|
PYPI: ['requirements.txt', 'setup.py', 'pyproject.toml'],
|
32
|
+
PNPM: 'pnpm-lock.yaml',
|
31
33
|
NPM: 'package.json',
|
32
34
|
MAVEN: 'pom.xml',
|
33
35
|
GRADLE: 'build.gradle',
|
@@ -9,8 +9,8 @@ import os
|
|
9
9
|
import fosslight_util.constant as constant
|
10
10
|
import fosslight_dependency.constant as const
|
11
11
|
from fosslight_dependency._package_manager import PackageManager
|
12
|
-
from fosslight_dependency._package_manager import connect_github, get_github_license
|
13
|
-
from fosslight_dependency._package_manager import get_url_to_purl
|
12
|
+
from fosslight_dependency._package_manager import connect_github, get_github_license
|
13
|
+
from fosslight_dependency._package_manager import get_url_to_purl, check_license_name
|
14
14
|
from fosslight_dependency.dependency_item import DependencyItem
|
15
15
|
from fosslight_util.oss_item import OssItem
|
16
16
|
|
@@ -79,9 +79,7 @@ class Carthage(PackageManager):
|
|
79
79
|
for license_file_reg in license_file_regs:
|
80
80
|
match_result = re.match(license_file_reg, filename_in_dir.lower())
|
81
81
|
if match_result is not None:
|
82
|
-
license_name =
|
83
|
-
self.license_scanner_bin,
|
84
|
-
filename_with_checkout_path)
|
82
|
+
license_name = check_license_name(filename_with_checkout_path, True)
|
85
83
|
find_license = True
|
86
84
|
break
|
87
85
|
if license_name == '':
|
@@ -89,7 +87,7 @@ class Carthage(PackageManager):
|
|
89
87
|
try:
|
90
88
|
if not g:
|
91
89
|
g = connect_github(self.github_token)
|
92
|
-
license_name = get_github_license(g, oss_path
|
90
|
+
license_name = get_github_license(g, oss_path)
|
93
91
|
except Exception as e:
|
94
92
|
logger.warning(f"Failed to get license with github api: {e}")
|
95
93
|
license_name == ''
|
@@ -46,7 +46,7 @@ class Npm(PackageManager):
|
|
46
46
|
ret = True
|
47
47
|
license_checker_cmd = f'license-checker --production --json --out {self.input_file_name}'
|
48
48
|
custom_path_option = ' --customPath '
|
49
|
-
npm_install_cmd = 'npm install --production'
|
49
|
+
npm_install_cmd = 'npm install --production --ignore-scripts'
|
50
50
|
|
51
51
|
if os.path.isdir(node_modules) != 1:
|
52
52
|
logger.info(f"node_modules directory is not existed. So it executes '{npm_install_cmd}'.")
|
@@ -12,7 +12,7 @@ import requests
|
|
12
12
|
import fosslight_util.constant as constant
|
13
13
|
import fosslight_dependency.constant as const
|
14
14
|
from fosslight_dependency._package_manager import PackageManager
|
15
|
-
from fosslight_dependency._package_manager import
|
15
|
+
from fosslight_dependency._package_manager import check_license_name, get_url_to_purl
|
16
16
|
from fosslight_dependency.dependency_item import DependencyItem, change_dependson_to_purl
|
17
17
|
from fosslight_util.oss_item import OssItem
|
18
18
|
|
@@ -54,7 +54,8 @@ class Nuget(PackageManager):
|
|
54
54
|
oss_item.version = oss_version
|
55
55
|
|
56
56
|
license_name = ''
|
57
|
-
response = requests.get(f'{self.nuget_api_url}{oss_origin_name
|
57
|
+
response = requests.get(f'{self.nuget_api_url.lower()}{oss_origin_name.lower()}/ \
|
58
|
+
{oss_item.version.lower()}/{oss_origin_name.lower()}.nuspec')
|
58
59
|
if response.status_code == 200:
|
59
60
|
root = fromstring(response.text)
|
60
61
|
xmlns = ''
|
@@ -73,14 +74,9 @@ class Nuget(PackageManager):
|
|
73
74
|
if license_url is not None:
|
74
75
|
url_res = requests.get(license_url.text)
|
75
76
|
if url_res.status_code == 200:
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
license_name_with_license_scanner = check_and_run_license_scanner(self.platform,
|
80
|
-
self.license_scanner_bin,
|
81
|
-
tmp_license_txt_file_name)
|
82
|
-
if license_name_with_license_scanner != "":
|
83
|
-
license_name = license_name_with_license_scanner
|
77
|
+
license_name_with_scanner = check_license_name(url_res.text)
|
78
|
+
if license_name_with_scanner != "":
|
79
|
+
license_name = license_name_with_scanner
|
84
80
|
else:
|
85
81
|
license_name = license_url.text
|
86
82
|
oss_item.license = license_name
|
@@ -0,0 +1,155 @@
|
|
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 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_dependency.dependency_item import DependencyItem, change_dependson_to_purl
|
15
|
+
from fosslight_dependency.package_manager.Npm import check_multi_license
|
16
|
+
from fosslight_util.oss_item import OssItem
|
17
|
+
|
18
|
+
logger = logging.getLogger(constant.LOGGER_NAME)
|
19
|
+
node_modules = 'node_modules'
|
20
|
+
|
21
|
+
|
22
|
+
class Pnpm(PackageManager):
|
23
|
+
package_manager_name = const.PNPM
|
24
|
+
|
25
|
+
dn_url = 'https://www.npmjs.com/package/'
|
26
|
+
input_file_name = 'tmp_pnpm_license_output.json'
|
27
|
+
flag_tmp_node_modules = False
|
28
|
+
project_name_list = []
|
29
|
+
pkg_list = {}
|
30
|
+
|
31
|
+
def __init__(self, input_dir, output_dir):
|
32
|
+
super().__init__(self.package_manager_name, self.dn_url, input_dir, output_dir)
|
33
|
+
|
34
|
+
def __del__(self):
|
35
|
+
if os.path.isfile(self.input_file_name):
|
36
|
+
os.remove(self.input_file_name)
|
37
|
+
if self.flag_tmp_node_modules:
|
38
|
+
shutil.rmtree(node_modules, ignore_errors=True)
|
39
|
+
|
40
|
+
def run_plugin(self):
|
41
|
+
ret = True
|
42
|
+
|
43
|
+
pnpm_install_cmd = 'pnpm install --prod --ignore-scripts --ignore-pnpmfile'
|
44
|
+
if os.path.isdir(node_modules) != 1:
|
45
|
+
logger.info(f"node_modules directory is not existed. So it executes '{pnpm_install_cmd}'.")
|
46
|
+
self.flag_tmp_node_modules = True
|
47
|
+
cmd_ret = subprocess.call(pnpm_install_cmd, shell=True)
|
48
|
+
if cmd_ret != 0:
|
49
|
+
logger.error(f"{pnpm_install_cmd} returns an error")
|
50
|
+
ret = False
|
51
|
+
if ret:
|
52
|
+
project_cmd = 'pnpm ls -r --depth -1 -P --json'
|
53
|
+
ret_txt = subprocess.check_output(project_cmd, text=True, shell=True)
|
54
|
+
if ret_txt is not None:
|
55
|
+
deps_l = json.loads(ret_txt)
|
56
|
+
for items in deps_l:
|
57
|
+
self.project_name_list.append(items["name"])
|
58
|
+
return ret
|
59
|
+
|
60
|
+
def parse_direct_dependencies(self):
|
61
|
+
if not self.direct_dep:
|
62
|
+
return
|
63
|
+
try:
|
64
|
+
direct_cmd = 'pnpm ls -r --depth 0 -P --json'
|
65
|
+
ret_txt = subprocess.check_output(direct_cmd, text=True, shell=True)
|
66
|
+
if ret_txt is not None:
|
67
|
+
deps_l = json.loads(ret_txt)
|
68
|
+
for item in deps_l:
|
69
|
+
if 'dependencies' in item and isinstance(item['dependencies'], dict):
|
70
|
+
self.direct_dep_list.extend(item['dependencies'].keys())
|
71
|
+
else:
|
72
|
+
self.direct_dep = False
|
73
|
+
logger.warning('Cannot print direct/transitive dependency')
|
74
|
+
except Exception as e:
|
75
|
+
logger.warning(f'Fail to print direct/transitive dependency: {e}')
|
76
|
+
self.direct_dep = False
|
77
|
+
if self.direct_dep:
|
78
|
+
self.direct_dep_list = list(filter(lambda dep: dep not in self.project_name_list, self.direct_dep_list))
|
79
|
+
|
80
|
+
def extract_dependencies(self, dependencies, purl_dict):
|
81
|
+
dep_item_list = []
|
82
|
+
for dep_name, dep_info in dependencies.items():
|
83
|
+
if dep_name not in self.project_name_list:
|
84
|
+
if dep_name in self.pkg_list.keys():
|
85
|
+
if dep_info.get('version') in self.pkg_list[dep_name]:
|
86
|
+
continue
|
87
|
+
self.pkg_list.setdefault(dep_name, []).append(dep_info.get('version'))
|
88
|
+
dep_item = DependencyItem()
|
89
|
+
oss_item = OssItem()
|
90
|
+
oss_item.name = f'npm:{dep_name}'
|
91
|
+
oss_item.version = dep_info.get('version')
|
92
|
+
|
93
|
+
license_name = dep_info.get('license')
|
94
|
+
if license_name:
|
95
|
+
multi_license, license_comment, multi_flag = check_multi_license(license_name, '')
|
96
|
+
if multi_flag:
|
97
|
+
oss_item.comment = license_comment
|
98
|
+
license_name = multi_license
|
99
|
+
else:
|
100
|
+
license_name = license_name.replace(",", "")
|
101
|
+
oss_item.license = license_name
|
102
|
+
|
103
|
+
oss_item.homepage = f'{self.dn_url}{dep_name}'
|
104
|
+
oss_item.download_location = dep_info.get('repository')
|
105
|
+
if oss_item.download_location:
|
106
|
+
if oss_item.download_location.endswith('.git'):
|
107
|
+
oss_item.download_location = oss_item.download_location[:-4]
|
108
|
+
if oss_item.download_location.startswith('git://'):
|
109
|
+
oss_item.download_location = 'https://' + oss_item.download_location[6:]
|
110
|
+
elif oss_item.download_location.startswith('git+https://'):
|
111
|
+
oss_item.download_location = 'https://' + oss_item.download_location[12:]
|
112
|
+
elif oss_item.download_location.startswith('git+ssh://git@'):
|
113
|
+
oss_item.download_location = 'https://' + oss_item.download_location[14:]
|
114
|
+
else:
|
115
|
+
oss_item.download_location = f'{self.dn_url}{dep_name}/v/{oss_item.version}'
|
116
|
+
|
117
|
+
dn_loc = f'{oss_item.homepage}/v/{oss_item.version}'
|
118
|
+
dep_item.purl = get_url_to_purl(dn_loc, 'npm')
|
119
|
+
purl_dict[f'{dep_name}({oss_item.version})'] = dep_item.purl
|
120
|
+
|
121
|
+
if dep_name in self.direct_dep_list:
|
122
|
+
oss_item.comment = 'direct'
|
123
|
+
else:
|
124
|
+
oss_item.comment = 'transitive'
|
125
|
+
|
126
|
+
if 'dependencies' in dep_info:
|
127
|
+
for dn, di in dep_info.get('dependencies').items():
|
128
|
+
if dn not in self.project_name_list:
|
129
|
+
dep_item.depends_on_raw.append(f"{dn}({di['version']})")
|
130
|
+
|
131
|
+
dep_item.oss_items.append(oss_item)
|
132
|
+
dep_item_list.append(dep_item)
|
133
|
+
|
134
|
+
if 'dependencies' in dep_info:
|
135
|
+
dep_item_list_inner, purl_dict_inner = self.extract_dependencies(dep_info['dependencies'], purl_dict)
|
136
|
+
dep_item_list.extend(dep_item_list_inner)
|
137
|
+
purl_dict.update(purl_dict_inner)
|
138
|
+
|
139
|
+
return dep_item_list, purl_dict
|
140
|
+
|
141
|
+
def parse_oss_information_for_pnpm(self):
|
142
|
+
project_cmd = 'pnpm ls --json -r --depth Infinity -P --long'
|
143
|
+
ret_txt = subprocess.check_output(project_cmd, text=True, shell=True)
|
144
|
+
if ret_txt is not None:
|
145
|
+
deps_l = json.loads(ret_txt)
|
146
|
+
purl_dict = {}
|
147
|
+
for items in deps_l:
|
148
|
+
if 'dependencies' in items:
|
149
|
+
dep_item_list_inner, purl_dict_inner = self.extract_dependencies(items['dependencies'], purl_dict)
|
150
|
+
self.dep_items.extend(dep_item_list_inner)
|
151
|
+
purl_dict.update(purl_dict_inner)
|
152
|
+
if self.direct_dep:
|
153
|
+
self.dep_items = change_dependson_to_purl(purl_dict, self.dep_items)
|
154
|
+
else:
|
155
|
+
logger.warning(f'No output for {project_cmd}')
|
@@ -10,11 +10,10 @@ import re
|
|
10
10
|
import shutil
|
11
11
|
import yaml
|
12
12
|
import subprocess
|
13
|
-
from askalono import identify
|
14
13
|
import fosslight_util.constant as constant
|
15
14
|
import fosslight_dependency.constant as const
|
16
15
|
from fosslight_dependency._package_manager import PackageManager
|
17
|
-
from fosslight_dependency._package_manager import get_url_to_purl
|
16
|
+
from fosslight_dependency._package_manager import get_url_to_purl, check_license_name
|
18
17
|
from fosslight_dependency.dependency_item import DependencyItem, change_dependson_to_purl
|
19
18
|
from fosslight_util.oss_item import OssItem
|
20
19
|
|
@@ -135,9 +134,7 @@ class Pub(PackageManager):
|
|
135
134
|
purl_dict[f'{oss_origin_name}({oss_item.version})'] = dep_item.purl
|
136
135
|
license_txt = json_data['license']
|
137
136
|
if license_txt is not None:
|
138
|
-
|
139
|
-
if detect_askalono.score > 0.7:
|
140
|
-
oss_item.license = detect_askalono.name
|
137
|
+
oss_item.license = check_license_name(license_txt)
|
141
138
|
|
142
139
|
if self.direct_dep:
|
143
140
|
if oss_origin_name not in self.total_dep_list:
|
@@ -13,7 +13,7 @@ import re
|
|
13
13
|
import fosslight_util.constant as constant
|
14
14
|
import fosslight_dependency.constant as const
|
15
15
|
from fosslight_dependency._package_manager import PackageManager
|
16
|
-
from fosslight_dependency._package_manager import
|
16
|
+
from fosslight_dependency._package_manager import check_license_name, get_url_to_purl
|
17
17
|
from fosslight_dependency.dependency_item import DependencyItem, change_dependson_to_purl
|
18
18
|
from fosslight_util.oss_item import OssItem
|
19
19
|
|
@@ -111,7 +111,7 @@ class Pypi(PackageManager):
|
|
111
111
|
install_cmd = cmd_separator.join(install_cmd_list)
|
112
112
|
else:
|
113
113
|
logger.error(const.SUPPORT_PACKAE[self.package_manager_name])
|
114
|
-
logger.error('Cannot create virtualenv
|
114
|
+
logger.error('Cannot create virtualenv because it cannot find: '
|
115
115
|
+ ', '.join(const.SUPPORT_PACKAE[self.package_manager_name]))
|
116
116
|
logger.error("Please run with '-a' and '-d' option.")
|
117
117
|
return False
|
@@ -302,12 +302,7 @@ class Pypi(PackageManager):
|
|
302
302
|
if license_name is not None:
|
303
303
|
license_name = license_name.replace(';', ',')
|
304
304
|
else:
|
305
|
-
|
306
|
-
license_name_with_lic_scanner = check_and_run_license_scanner(self.platform,
|
307
|
-
self.license_scanner_bin,
|
308
|
-
license_file_dir)
|
309
|
-
if license_name_with_lic_scanner != "":
|
310
|
-
license_name = license_name_with_lic_scanner
|
305
|
+
license_name = check_license_name(d['LicenseFile'], True)
|
311
306
|
oss_item.license = license_name
|
312
307
|
|
313
308
|
if oss_init_name == self.package_name:
|
@@ -140,7 +140,7 @@ class Swift(PackageManager):
|
|
140
140
|
github_repo = "/".join(oss_item.homepage.split('/')[-2:])
|
141
141
|
dep_item.purl = get_url_to_purl(oss_item.download_location, self.package_manager_name, github_repo, oss_item.version)
|
142
142
|
purl_dict[f'{oss_origin_name}({oss_item.version})'] = dep_item.purl
|
143
|
-
oss_item.license = get_github_license(g, github_repo
|
143
|
+
oss_item.license = get_github_license(g, github_repo)
|
144
144
|
|
145
145
|
if self.direct_dep and len(self.direct_dep_list) > 0:
|
146
146
|
if oss_origin_name in self.direct_dep_list:
|
@@ -11,13 +11,12 @@ import requests
|
|
11
11
|
import fosslight_util.constant as constant
|
12
12
|
import fosslight_dependency.constant as const
|
13
13
|
from fosslight_dependency._package_manager import PackageManager
|
14
|
-
from fosslight_dependency._package_manager import
|
14
|
+
from fosslight_dependency._package_manager import check_license_name, get_url_to_purl
|
15
15
|
from fosslight_dependency.dependency_item import DependencyItem
|
16
16
|
from fosslight_util.oss_item import OssItem
|
17
17
|
|
18
18
|
logger = logging.getLogger(constant.LOGGER_NAME)
|
19
19
|
proprietary_license = 'Proprietary License'
|
20
|
-
unclassifed_license = 'UnclassifiedLicense'
|
21
20
|
license_md = 'LICENSE.md'
|
22
21
|
third_party_md = 'Third Party Notices.md'
|
23
22
|
|
@@ -50,10 +49,8 @@ class Unity(PackageManager):
|
|
50
49
|
oss_packagecache_dir = os.path.join(self.packageCache_dir, f'{oss_item.name}@{oss_item.version}')
|
51
50
|
license_f = os.path.join(oss_packagecache_dir, license_md)
|
52
51
|
if os.path.isfile(license_f):
|
53
|
-
license_name =
|
54
|
-
|
55
|
-
license_f)
|
56
|
-
if license_name == unclassifed_license or license_name == '':
|
52
|
+
license_name = check_license_name(license_f, True)
|
53
|
+
if license_name == '':
|
57
54
|
with open(license_f, 'r', encoding='utf-8') as f:
|
58
55
|
for line in f:
|
59
56
|
matched_l = re.search(r'Unity\s[\s\w]*\sLicense', line)
|
@@ -51,17 +51,17 @@ def paginate_file(file_path):
|
|
51
51
|
input("Press Enter to see the next page...")
|
52
52
|
|
53
53
|
|
54
|
-
def find_package_manager(input_dir, abs_path_to_exclude=[]):
|
54
|
+
def find_package_manager(input_dir, abs_path_to_exclude=[], manifest_file_name=[]):
|
55
55
|
ret = True
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
56
|
+
if not manifest_file_name:
|
57
|
+
for value in const.SUPPORT_PACKAE.values():
|
58
|
+
if isinstance(value, list):
|
59
|
+
manifest_file_name.extend(value)
|
60
|
+
else:
|
61
|
+
manifest_file_name.append(value)
|
62
62
|
|
63
63
|
found_manifest_file = []
|
64
|
-
for
|
64
|
+
for parent, dirs, files in os.walk(input_dir):
|
65
65
|
if len(files) < 1:
|
66
66
|
continue
|
67
67
|
if os.path.basename(parent) in _exclude_dir:
|
@@ -76,6 +76,13 @@ def find_package_manager(input_dir, abs_path_to_exclude=[]):
|
|
76
76
|
continue
|
77
77
|
if file in manifest_file_name:
|
78
78
|
found_manifest_file.append(file)
|
79
|
+
for dir in dirs:
|
80
|
+
for manifest_f in manifest_file_name:
|
81
|
+
manifest_l = manifest_f.split(os.path.sep)
|
82
|
+
if len(manifest_l) > 1:
|
83
|
+
if manifest_l[0] == dir:
|
84
|
+
if os.path.exists(os.path.join(parent, manifest_f)):
|
85
|
+
found_manifest_file.append(manifest_f)
|
79
86
|
if len(found_manifest_file) > 0:
|
80
87
|
input_dir = parent
|
81
88
|
break
|
@@ -93,13 +100,16 @@ def find_package_manager(input_dir, abs_path_to_exclude=[]):
|
|
93
100
|
if value == f_idx:
|
94
101
|
found_package_manager[key] = [f_idx]
|
95
102
|
|
103
|
+
# both npm and pnpm are detected, remove npm.
|
104
|
+
if 'npm' in found_package_manager and 'pnpm' in found_package_manager:
|
105
|
+
del found_package_manager['npm']
|
96
106
|
if len(found_package_manager) >= 1:
|
97
|
-
manifest_file_w_path =
|
107
|
+
manifest_file_w_path = [os.path.join(input_dir, file) for pkg, files in found_package_manager.items() for file in files]
|
98
108
|
logger.info(f"Found the manifest file({','.join(manifest_file_w_path)}) automatically.")
|
99
109
|
logger.warning(f"### Set Package Manager = {', '.join(found_package_manager.keys())}")
|
100
110
|
else:
|
101
111
|
ret = False
|
102
|
-
logger.info("
|
112
|
+
logger.info("Cannot find the manifest file.")
|
103
113
|
|
104
114
|
return ret, found_package_manager, input_dir
|
105
115
|
|
@@ -168,17 +178,6 @@ def run_dependency_scanner(package_manager='', input_dir='', output_dir_file='',
|
|
168
178
|
logger.error(msg)
|
169
179
|
return False, scan_item
|
170
180
|
|
171
|
-
autodetect = True
|
172
|
-
if package_manager:
|
173
|
-
autodetect = False
|
174
|
-
support_packagemanager = list(const.SUPPORT_PACKAE.keys())
|
175
|
-
|
176
|
-
if package_manager not in support_packagemanager:
|
177
|
-
logger.error(f"(-m option) You entered the unsupported package manager({package_manager}).")
|
178
|
-
logger.error("Please enter the supported package manager({0}) with '-m' option."
|
179
|
-
.format(", ".join(support_packagemanager)))
|
180
|
-
return False, scan_item
|
181
|
-
|
182
181
|
if input_dir:
|
183
182
|
if os.path.isdir(input_dir):
|
184
183
|
os.chdir(input_dir)
|
@@ -192,20 +191,44 @@ def run_dependency_scanner(package_manager='', input_dir='', output_dir_file='',
|
|
192
191
|
os.chdir(input_dir)
|
193
192
|
scan_item.set_cover_pathinfo(input_dir, path_to_exclude)
|
194
193
|
|
194
|
+
autodetect = True
|
195
195
|
found_package_manager = {}
|
196
|
-
if
|
197
|
-
|
198
|
-
|
196
|
+
if package_manager:
|
197
|
+
autodetect = False
|
198
|
+
support_packagemanager = list(const.SUPPORT_PACKAE.keys())
|
199
|
+
|
200
|
+
if package_manager not in support_packagemanager:
|
201
|
+
logger.error(f"(-m option) You entered the unsupported package manager({package_manager}).")
|
202
|
+
logger.error("Please enter the supported package manager({0}) with '-m' option."
|
203
|
+
.format(", ".join(support_packagemanager)))
|
204
|
+
return False, scan_item
|
205
|
+
manifest_file_name = []
|
206
|
+
value = const.SUPPORT_PACKAE[package_manager]
|
207
|
+
if isinstance(value, list):
|
208
|
+
manifest_file_name.extend(value)
|
209
|
+
else:
|
210
|
+
manifest_file_name.append(value)
|
211
|
+
scan_item.set_cover_comment(f"Manual detect mode (-m {package_manager})")
|
212
|
+
else:
|
213
|
+
manifest_file_name = []
|
214
|
+
|
215
|
+
try:
|
216
|
+
ret, found_package_manager, input_dir = find_package_manager(input_dir, abs_path_to_exclude, manifest_file_name)
|
217
|
+
if ret:
|
199
218
|
os.chdir(input_dir)
|
200
|
-
|
219
|
+
except Exception as e:
|
220
|
+
if autodetect:
|
201
221
|
logger.error(f'Fail to find package manager: {e}')
|
202
222
|
ret = False
|
203
|
-
|
204
|
-
|
205
|
-
|
223
|
+
finally:
|
224
|
+
if not ret:
|
225
|
+
if not autodetect:
|
226
|
+
logger.info('Try to analyze dependency without manifest file. (Manual mode)')
|
227
|
+
found_package_manager[package_manager] = []
|
228
|
+
else:
|
229
|
+
logger.error("Terminated: package manager could not be found.")
|
206
230
|
ret = False
|
207
|
-
|
208
|
-
found_package_manager[package_manager] = ["manual detect ('-m option')"]
|
231
|
+
return False, scan_item
|
209
232
|
|
210
233
|
pass_key = 'PASS'
|
211
234
|
success_pm = []
|
@@ -242,7 +265,8 @@ def run_dependency_scanner(package_manager='', input_dir='', output_dir_file='',
|
|
242
265
|
'and https://fosslight.org/fosslight-guide-en/scanner/3_dependency.html#-prerequisite.'
|
243
266
|
scan_item.set_cover_comment(f"Analysis failed Package manager: {', '.join(fail_pm)} ({info_msg})")
|
244
267
|
else:
|
245
|
-
|
268
|
+
if autodetect:
|
269
|
+
scan_item.set_cover_comment("No Package manager detected.")
|
246
270
|
|
247
271
|
if ret and graph_path:
|
248
272
|
graph_path = os.path.abspath(graph_path)
|
{fosslight_dependency-4.1.7 → fosslight_dependency-4.1.9}/src/fosslight_dependency.egg-info/PKG-INFO
RENAMED
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: fosslight-dependency
|
3
|
-
Version: 4.1.
|
3
|
+
Version: 4.1.9
|
4
4
|
Summary: FOSSLight Dependency Scanner
|
5
5
|
Home-page: https://github.com/fosslight/fosslight_dependency_scanner
|
6
6
|
Author: LG Electronics
|
@@ -164,8 +164,8 @@ Description: <!--
|
|
164
164
|
Platform: UNKNOWN
|
165
165
|
Classifier: License :: OSI Approved :: Apache Software License
|
166
166
|
Classifier: Programming Language :: Python :: 3
|
167
|
-
Classifier: Programming Language :: Python :: 3.6
|
168
|
-
Classifier: Programming Language :: Python :: 3.7
|
169
167
|
Classifier: Programming Language :: Python :: 3.8
|
170
168
|
Classifier: Programming Language :: Python :: 3.9
|
169
|
+
Classifier: Programming Language :: Python :: 3.10
|
170
|
+
Classifier: Programming Language :: Python :: 3.11
|
171
171
|
Description-Content-Type: text/markdown
|
@@ -31,6 +31,7 @@ src/fosslight_dependency/package_manager/Helm.py
|
|
31
31
|
src/fosslight_dependency/package_manager/Maven.py
|
32
32
|
src/fosslight_dependency/package_manager/Npm.py
|
33
33
|
src/fosslight_dependency/package_manager/Nuget.py
|
34
|
+
src/fosslight_dependency/package_manager/Pnpm.py
|
34
35
|
src/fosslight_dependency/package_manager/Pub.py
|
35
36
|
src/fosslight_dependency/package_manager/Pypi.py
|
36
37
|
src/fosslight_dependency/package_manager/Swift.py
|
File without changes
|
File without changes
|
{fosslight_dependency-4.1.7 → fosslight_dependency-4.1.9}/LICENSES/LicenseRef-3rd_party_licenses.txt
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{fosslight_dependency-4.1.7 → fosslight_dependency-4.1.9}/src/fosslight_dependency/__init__.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
|