fosslight-dependency 4.1.8__py3-none-any.whl → 4.1.9__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.
@@ -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
@@ -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',
@@ -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}'.")
@@ -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}')
@@ -100,8 +100,11 @@ def find_package_manager(input_dir, abs_path_to_exclude=[], manifest_file_name=[
100
100
  if value == f_idx:
101
101
  found_package_manager[key] = [f_idx]
102
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']
103
106
  if len(found_package_manager) >= 1:
104
- manifest_file_w_path = map(lambda x: os.path.join(input_dir, x), found_manifest_file)
107
+ manifest_file_w_path = [os.path.join(input_dir, file) for pkg, files in found_package_manager.items() for file in files]
105
108
  logger.info(f"Found the manifest file({','.join(manifest_file_w_path)}) automatically.")
106
109
  logger.warning(f"### Set Package Manager = {', '.join(found_package_manager.keys())}")
107
110
  else:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: fosslight-dependency
3
- Version: 4.1.8
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
@@ -1,11 +1,11 @@
1
1
  fosslight_dependency/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- fosslight_dependency/_analyze_dependency.py,sha256=uYbHDlFfEf-LsCWc6hTKN-QCD1T_2jaEgBf3z4M_4Lk,4226
2
+ fosslight_dependency/_analyze_dependency.py,sha256=AKwKPEjA5x4p3oCWMJugQjd4zX9WKy9zfUqp44gL63Q,4617
3
3
  fosslight_dependency/_graph_convertor.py,sha256=D8GwmJfuj9Wg3_DeKRPLGGdyHSLcoU2Q0VzKQbkJG4g,2267
4
- fosslight_dependency/_help.py,sha256=INeP24fFfV2HPhZJMqk_KCu08X7nneAumBqMWQ7Sbw8,3336
4
+ fosslight_dependency/_help.py,sha256=S5tt26ccMLp-BEgWoXWyPxd8JzLtwZ5bIc-A2UTeM4k,3365
5
5
  fosslight_dependency/_package_manager.py,sha256=GUqMLidGGVrek0XpApron3SWFf66VsmfycsmnvxQOkY,14890
6
- fosslight_dependency/constant.py,sha256=FAkzrW1S6Ua_TAbvQ2y6d0dhEZcgonB11miKUj7lB98,1080
6
+ fosslight_dependency/constant.py,sha256=nGa2Q_IWMojHEKkwdvoFvZrsqZZ4jMCk9h3M78j_lMc,1122
7
7
  fosslight_dependency/dependency_item.py,sha256=wNLWcsNycf3HQ5Pib2WrMeo2dn0eHCRg20NLcL95Qew,3345
8
- fosslight_dependency/run_dependency_scanner.py,sha256=zFlHAwj9fhsiaut_VhvQneX8Ngz82xgau4ThmHxk8pI,17399
8
+ fosslight_dependency/run_dependency_scanner.py,sha256=rCHwKW2NsOSRyRxsFmUunKruK9vN24O2ucHghJYgey4,17600
9
9
  fosslight_dependency/LICENSES/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
10
10
  fosslight_dependency/LICENSES/LicenseRef-3rd_party_licenses.txt,sha256=EcsFt7aE1rp3OXAdJgmXayfOZdpRdBMcmRnyoqWMCsw,95687
11
11
  fosslight_dependency/package_manager/Android.py,sha256=0UZFvbLxDIreerK4fR316YPyhUpPliV_kfZulrxkUyo,3218
@@ -16,19 +16,20 @@ fosslight_dependency/package_manager/Go.py,sha256=O-6DTTRM2EoTpCVmlIPKFy8ZTz64EH
16
16
  fosslight_dependency/package_manager/Gradle.py,sha256=IYmj9q3XiE_DPKdtll6lyRr98lFuyKWW2qz57X26Fn0,4359
17
17
  fosslight_dependency/package_manager/Helm.py,sha256=ucx2Y0tWX37UHIzIGaRyTe7uQ2vlu2nUuO09hOMq9ZU,4223
18
18
  fosslight_dependency/package_manager/Maven.py,sha256=XDVTmxRjeQmATpJDP__yw47Pk5e4utXAkkEkskXPQCQ,10443
19
- fosslight_dependency/package_manager/Npm.py,sha256=hwKC08m05KlHgfQpPX7lnDEJC-A7WKF9OniYW4n9TDM,10638
19
+ fosslight_dependency/package_manager/Npm.py,sha256=EvXXJUJ3-4cyvGNQU2cXPGkOcOQPr4CkuxpNDKk-49w,10655
20
20
  fosslight_dependency/package_manager/Nuget.py,sha256=x1SPdxwXS2Oyi1RnLasvJJL-IFJl45VI2CXt3wReW24,8884
21
+ fosslight_dependency/package_manager/Pnpm.py,sha256=LDKooFGQHui_Q5U7XqSJ8KcCPiLVndXf5oGKTJExh5w,7056
21
22
  fosslight_dependency/package_manager/Pub.py,sha256=Rrz8_6wdrmMU6f3vbbuAwyMbODBauXNnBbI619OQgDk,10184
22
23
  fosslight_dependency/package_manager/Pypi.py,sha256=A3pXJC_7H7PTa6i3B_PvJY85qsc6W9AqOze7kB8E3Ws,15831
23
24
  fosslight_dependency/package_manager/Swift.py,sha256=8fdbdAXTNlp2NDoSqQXm48JGAg9UhxA91M1-NhHkT40,6752
24
25
  fosslight_dependency/package_manager/Unity.py,sha256=n1006GZ6Qrk8wAdO6wla1Q-JD7Evin7REVj-HDeTARc,5142
25
26
  fosslight_dependency/package_manager/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
26
- fosslight_dependency-4.1.8.dist-info/Apache-2.0.txt,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
27
- fosslight_dependency-4.1.8.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
28
- fosslight_dependency-4.1.8.dist-info/LicenseRef-3rd_party_licenses.txt,sha256=EcsFt7aE1rp3OXAdJgmXayfOZdpRdBMcmRnyoqWMCsw,95687
29
- fosslight_dependency-4.1.8.dist-info/METADATA,sha256=t5oEFJ8QBw9OduU3e6TB_IaeC4EcABk13D9D0mfO87Q,4984
30
- fosslight_dependency-4.1.8.dist-info/MIT.txt,sha256=9cx4CbArgByWvkoEZNqpzbpJgA9TUe2D62rMocQpgfs,1082
31
- fosslight_dependency-4.1.8.dist-info/WHEEL,sha256=tZoeGjtWxWRfdplE7E3d45VPlLNQnvbKiYnx7gwAy8A,92
32
- fosslight_dependency-4.1.8.dist-info/entry_points.txt,sha256=e1QZbnCrQvfbwe9L6PxXnkRZMhl-PSo0QyUes0dGjU8,91
33
- fosslight_dependency-4.1.8.dist-info/top_level.txt,sha256=Jc0V7VcVCH0TEM8ksb8dwroTYz4AmRaQnlr3FB71Hcs,21
34
- fosslight_dependency-4.1.8.dist-info/RECORD,,
27
+ fosslight_dependency-4.1.9.dist-info/Apache-2.0.txt,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
28
+ fosslight_dependency-4.1.9.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
29
+ fosslight_dependency-4.1.9.dist-info/LicenseRef-3rd_party_licenses.txt,sha256=EcsFt7aE1rp3OXAdJgmXayfOZdpRdBMcmRnyoqWMCsw,95687
30
+ fosslight_dependency-4.1.9.dist-info/METADATA,sha256=16aIkcJigbjdeWlh6yp9jFBwrQjjpEZR-yrpGA1ohDY,4984
31
+ fosslight_dependency-4.1.9.dist-info/MIT.txt,sha256=9cx4CbArgByWvkoEZNqpzbpJgA9TUe2D62rMocQpgfs,1082
32
+ fosslight_dependency-4.1.9.dist-info/WHEEL,sha256=tZoeGjtWxWRfdplE7E3d45VPlLNQnvbKiYnx7gwAy8A,92
33
+ fosslight_dependency-4.1.9.dist-info/entry_points.txt,sha256=e1QZbnCrQvfbwe9L6PxXnkRZMhl-PSo0QyUes0dGjU8,91
34
+ fosslight_dependency-4.1.9.dist-info/top_level.txt,sha256=Jc0V7VcVCH0TEM8ksb8dwroTYz4AmRaQnlr3FB71Hcs,21
35
+ fosslight_dependency-4.1.9.dist-info/RECORD,,