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
@@ -1,1090 +0,0 @@
1
- #!/usr/bin/env python
2
- # -*- coding: utf-8 -*-
3
- # Copyright (c) 2020 LG Electronics Inc.
4
- # SPDX-License-Identifier: Apache-2.0
5
-
6
- from __future__ import print_function
7
- from io import open
8
- import os
9
- import sys
10
- import argparse
11
- from openpyxl import load_workbook, Workbook
12
- import platform
13
- import shutil
14
- import subprocess
15
- import json
16
- import re
17
- from xml.etree.ElementTree import parse
18
- from bs4 import BeautifulSoup
19
- import pkg_resources
20
- import yaml
21
- from lastversion import lastversion
22
- from fosslight_util.set_log import init_log
23
- from datetime import datetime
24
- from . import __version__
25
- from fosslight_util.write_excel import write_excel_and_csv
26
-
27
-
28
- # Check the manifest file
29
- manifest_array = [["pip", "requirements.txt"], ["npm", "package.json"], ["maven", "pom.xml"],
30
- ["gradle", "build.gradle"], ["pub", "pubspec.yaml"], ["cocoapods", "Podfile.lock"]]
31
-
32
- # binary url to check license text
33
- license_scanner_url_linux = "third_party/nomos/nomossa"
34
- license_scanner_url_macos = "third_party/askalono/askalono_macos"
35
- license_scanner_url_windows = "third_party\\askalono\\askalono.exe"
36
-
37
-
38
-
39
- def check_valid_manifest_file():
40
- global PACKAGE
41
-
42
- manifest_file_name = [i[1] for i in manifest_array]
43
-
44
- idx = 0
45
- found_idx = []
46
- for f in manifest_file_name:
47
- if os.path.isfile(f):
48
- found_idx.append(idx)
49
- idx += 1
50
-
51
- if len(found_idx) == 1:
52
- PACKAGE = manifest_array[int(found_idx[0])][0]
53
- logger.info("### Info Message ###")
54
- logger.info("Found the manifest file(" + manifest_array[int(found_idx[0])][1] + ")automatically.")
55
- logger.warn("Set PACKAGE =" + PACKAGE)
56
- ret = 0
57
- else:
58
- ret = 1
59
-
60
- return ret
61
-
62
-
63
- def help_print():
64
- print("### Option Usage ###")
65
- print(" -v : version")
66
- print(" -m : package manager")
67
- print(" ex) pip, npm, maven, gradle, pub, cocoapods")
68
- print(" -p : input directory where the script will be run.")
69
- print(" -o : output directory where the result file will be generated.")
70
- print("# pypi only options")
71
- print(" -a : virtual environment activate command")
72
- print(" -d : virtual environment deactivate command")
73
- print("# maven, gradle only option")
74
- print(" -c : customized build output directory")
75
-
76
-
77
- def parse_option():
78
- global MANUAL_DETECT, PIP_ACTIVATE, PIP_DEACTIVATE, PACKAGE, OUTPUT_CUSTOM_DIR, CUR_PATH, OUTPUT_RESULT_DIR
79
-
80
- default_unspecified = "UNSPECIFIED"
81
-
82
- parser = argparse.ArgumentParser(add_help=False)
83
- parser.add_argument('-h', '--help', action='store_true', required=False)
84
- parser.add_argument('-m', '--manager', nargs=1, type=str, default=default_unspecified, required=False)
85
- parser.add_argument('-a', '--activate', nargs=1, type=str, default=default_unspecified, required=False)
86
- parser.add_argument('-d', '--deactivate', nargs=1, type=str, default=default_unspecified, required=False)
87
- parser.add_argument('-c', '--customized', nargs=1, type=str, required=False)
88
- parser.add_argument('-p', '--path', nargs=1, type=str, required=False)
89
- parser.add_argument('-v', '--version', action='store_true', required=False)
90
- parser.add_argument('-o', '--output', nargs=1, type=str, required=False)
91
-
92
- args = parser.parse_args()
93
-
94
- # -h option
95
- if args.help:
96
- help_print()
97
- sys.exit(0)
98
-
99
- # -v option
100
- if args.version:
101
- print(__version__)
102
- sys.exit(0)
103
-
104
- # -m option
105
- if args.manager == default_unspecified:
106
- MANUAL_DETECT = 0 # It will be detected the package manager automatically with manifest file.
107
- else:
108
- MANUAL_DETECT = 1
109
- PACKAGE = "".join(args.manager)
110
-
111
- # -a option
112
- if args.activate:
113
- PIP_ACTIVATE = "".join(args.activate)
114
-
115
- # -d option
116
- if args.deactivate:
117
- PIP_DEACTIVATE = "".join(args.deactivate)
118
-
119
- # -c option
120
- if args.customized:
121
- OUTPUT_CUSTOM_DIR = "".join(args.customized)
122
- else:
123
- OUTPUT_CUSTOM_DIR = ""
124
-
125
- # -o option
126
- if args.output:
127
- OUTPUT_RESULT_DIR = "".join(args.output)
128
- if os.path.isdir(OUTPUT_RESULT_DIR):
129
- OUTPUT_RESULT_DIR = os.path.abspath(OUTPUT_RESULT_DIR)
130
- else:
131
- try:
132
- os.mkdir(OUTPUT_RESULT_DIR)
133
- except:
134
- print("You entered wrong output path(" + OUTPUT_RESULT_DIR + ") to generate output file.")
135
- sys.exit(1)
136
- OUTPUT_RESULT_DIR = os.path.abspath(OUTPUT_RESULT_DIR)
137
- else:
138
- OUTPUT_RESULT_DIR = os.getcwd()
139
-
140
- # -p option
141
- if args.path:
142
- CUR_PATH = "".join(args.path)
143
- if os.path.isdir(CUR_PATH):
144
- os.chdir(CUR_PATH)
145
- CUR_PATH = os.getcwd()
146
- else:
147
- print("You entered wrong path(" + CUR_PATH + ") to run the script.")
148
- sys.exit(1)
149
- else:
150
- CUR_PATH = os.getcwd()
151
- os.chdir(CUR_PATH)
152
-
153
-
154
- def configure_package():
155
- if MANUAL_DETECT == 0:
156
- ret = check_valid_manifest_file()
157
- if ret != 0:
158
- logger.error("### Error Message ###")
159
- logger.error("Please enter the package manager with -m option.")
160
- logger.error("You can see the '-m' option with help messages('-h')")
161
- sys.exit(1)
162
-
163
-
164
- ####################
165
- # Common functions #
166
- ####################
167
-
168
- def check_python_version():
169
- if int(sys.version[0]) < 3:
170
- python_version = 2
171
- else:
172
- python_version = 3
173
- logger.info("python_version = " + str(python_version))
174
- return python_version
175
-
176
-
177
- def check_virtualenv_arg():
178
- global PIP_ACTIVATE, PIP_DEACTIVATE, venv_tmp_dir
179
-
180
- if PIP_ACTIVATE == "UNSPECIFIED":
181
- is_requirements_file = os.path.isfile("requirements.txt")
182
-
183
- if is_requirements_file != 1:
184
- logger.error("### Error Message ###")
185
- logger.error("Cannot find the virtualenv directory:" + PIP_ACTIVATE)
186
- logger.error("Also it cannot find 'requirements.txt' file and install pip package.")
187
- logger.error("Please check the '-a' option argument.")
188
- sys.exit(1)
189
-
190
- python_version = check_python_version()
191
-
192
- venv_path = os.path.join(CUR_PATH,venv_tmp_dir)
193
-
194
- if python_version == 2:
195
- create_venv_command = "virtualenv -p python " + venv_tmp_dir
196
- else:
197
- create_venv_command = "virtualenv -p python3 " + venv_tmp_dir
198
-
199
- if check_os() == "Windows":
200
- activate_command = ".\\" + os.path.join(venv_tmp_dir, "Scripts", "activate")
201
- else:
202
- activate_command = ". " + os.path.join(venv_path, "bin", "activate")
203
-
204
- PIP_ACTIVATE = activate_command
205
-
206
- install_command = "pip install -r requirements.txt"
207
- deactivate_command = "deactivate"
208
- PIP_DEACTIVATE = deactivate_command
209
-
210
- logger.info("You didn't enter the '-a' option.")
211
- logger.info("It makes virtualenv tmp dir(" + venv_path + ") to install pip package with requirements.txt.")
212
-
213
- if check_os() == "Windows":
214
- command_separator = "&"
215
- else:
216
- command_separator = ";"
217
- command_list = [create_venv_command, activate_command, install_command, deactivate_command]
218
- command = command_separator.join(command_list)
219
- command_ret = subprocess.call(command, shell=True)
220
- if command_ret != 0:
221
- logger.error("### Error Message ###")
222
- logger.error("This command(" + command + ") returns an error")
223
- logger.error("Please check if you installed virtualenv.")
224
- sys.exit(1)
225
-
226
-
227
- def add_plugin_in_pom():
228
- global pom_backup
229
-
230
- is_append = False
231
-
232
- if os.path.isfile(manifest_array[2][1]) != 1:
233
- logger.error(manifest_array[2][1] + " is not existed in this directory.")
234
- sys.exit(1)
235
-
236
- shutil.move(manifest_array[2][1], pom_backup)
237
-
238
- license_maven_plugin = '<plugin>\
239
- <groupId>org.codehaus.mojo</groupId>\
240
- <artifactId>license-maven-plugin</artifactId>\
241
- <version>2.0.0</version>\
242
- <executions>\
243
- <execution>\
244
- <id>aggregate-download-licenses</id>\
245
- <goals>\
246
- <goal>aggregate-download-licenses</goal>\
247
- </goals>\
248
- </execution>\
249
- </executions>\
250
- </plugin>'
251
-
252
- tmp_plugin = BeautifulSoup(license_maven_plugin, 'xml')
253
-
254
- license_maven_plugins = '<plugins>' + license_maven_plugin + '<plugins>'
255
- tmp_plugins = BeautifulSoup(license_maven_plugins, 'xml')
256
-
257
- with open(pom_backup, 'r', encoding='utf8') as f:
258
- f_xml = f.read()
259
- f_content = BeautifulSoup(f_xml, 'xml')
260
-
261
- build = f_content.find('build')
262
- if build is not None:
263
- plugins = build.find('plugins')
264
- if plugins is not None:
265
- plugins.append(tmp_plugin.plugin)
266
- is_append = True
267
- else:
268
- build.append(tmp_plugins.plugins)
269
- is_append = True
270
-
271
- if is_append:
272
- with open(manifest_array[2][1], "w", encoding='utf8') as f_w:
273
- f_w.write(f_content.prettify(formatter="minimal").encode().decode('utf-8'))
274
-
275
- return is_append
276
-
277
-
278
- def clean_run_maven_plugin_output():
279
- global input_file_name
280
-
281
- if OUTPUT_CUSTOM_DIR != "":
282
- input_tmp = input_file_name.split('/')
283
- input_rest_tmp = ''
284
- for i in range(len(input_tmp)):
285
- if i > 0:
286
- input_rest_tmp = input_rest_tmp + '/' + input_tmp[i]
287
- input_file_name = str(OUTPUT_CUSTOM_DIR) + str(input_rest_tmp)
288
-
289
- directory_name = os.path.dirname(input_file_name)
290
- licenses_path = directory_name + '/licenses'
291
- if os.path.isdir(licenses_path) == 1:
292
- shutil.rmtree(licenses_path)
293
- os.remove(directory_name + '/licenses.xml')
294
- logger.info('remove temporary directory: ' + licenses_path)
295
-
296
- if len(os.listdir(directory_name)) == 0:
297
- shutil.rmtree(directory_name)
298
-
299
- shutil.move(pom_backup, manifest_array[2][1])
300
-
301
-
302
- def run_maven_plugin():
303
- logger.info('run maven license scanning plugin with temporary pom.xml')
304
- command = "mvn license:aggregate-download-licenses"
305
-
306
- ret = subprocess.call(command, shell=True)
307
-
308
- if ret != 0:
309
- logger.error("### Error Message ###")
310
- logger.error("This command(" + command + ") returns an error.")
311
-
312
- clean_run_maven_plugin_output()
313
- sys.exit(1)
314
-
315
-
316
- def open_input_file():
317
- global input_file_name
318
-
319
- if OUTPUT_CUSTOM_DIR != "":
320
- input_tmp = input_file_name.split('/')
321
- input_rest_tmp = ''
322
- for i in range(len(input_tmp)):
323
- if i > 0:
324
- input_rest_tmp = input_rest_tmp + '/' + input_tmp[i]
325
- input_file_name = str(OUTPUT_CUSTOM_DIR) + str(input_rest_tmp)
326
-
327
- if os.path.isfile(input_file_name) != 1:
328
- logger.error("### Error Message ###")
329
- logger.error(input_file_name + " doesn't exist in this directory.")
330
-
331
- if PACKAGE == "maven":
332
- global is_maven_first_try
333
-
334
- if is_maven_first_try:
335
- is_append = add_plugin_in_pom()
336
- is_maven_first_try = False
337
-
338
- if is_append:
339
- run_maven_plugin()
340
- return open_input_file()
341
- else:
342
- clean_run_maven_plugin_output()
343
-
344
- logger.error("Please check the below thing first.")
345
- logger.error(" 1.Did you run the license-maven-plugin?")
346
- logger.error(" 2.Or if your project has the customized build output directory, then use '-c' option with your customized build output directory name")
347
- logger.error(" $ fosslight_dependency -c output")
348
- sys.exit(1)
349
-
350
- input_fp = open(input_file_name, 'r', encoding='utf8')
351
-
352
- return input_fp
353
-
354
-
355
- def close_input_file(input_fp):
356
- input_fp.close()
357
-
358
-
359
- def make_custom_json(tmp_custom_json):
360
- with open(tmp_custom_json, 'w', encoding='utf8') as custom:
361
- custom.write(
362
- "{\n\t\"name\": \"\",\n\t\"version\": \"\",\n\t\"licenses\": \"\",\n\t\"repository\": \"\",\n\t\"url\": \"\",\n\t\"copyright\": \"\",\n\t\"licenseText\": \"\"\n}\n".encode().decode(
363
- "utf-8"))
364
-
365
-
366
- def start_license_checker():
367
- tmp_custom_json = "custom.json"
368
- tmp_file_name = "tmp_npm_license_output.json"
369
- flag_tmp_node_modules = False
370
-
371
- if os.path.isfile(tmp_custom_json) == 1:
372
- os.remove(tmp_custom_json)
373
- if os.path.isfile(tmp_file_name) == 1:
374
- os.remove(tmp_file_name)
375
-
376
- test_command = "license-checker > test.tmp"
377
- ret = os.system(test_command)
378
- os.remove("test.tmp")
379
- if ret != 0:
380
- logger.error("### Error Message ###")
381
- logger.error("Running license-checker returns error. Please check if the license-checker is installed.")
382
- logger.error(">>Command for installing license-checker (Root permission is required to run this command.)")
383
- logger.error(" sudo npm install -g license-checker")
384
- sys.exit(1)
385
-
386
- if os.path.isdir("node_modules") != 1:
387
- logger.info("node_modules directory is not existed.it executes 'npm install'.")
388
- flag_tmp_node_modules = True
389
- command = 'npm install'
390
- command_ret = subprocess.call(command, shell=True)
391
- if command_ret != 0:
392
- logger.error("### Error Message ###")
393
- logger.error("This command(" + command + ") returns an error")
394
- sys.exit(1)
395
-
396
- # customized json file for obtaining specific items with license-checker
397
- make_custom_json(tmp_custom_json)
398
-
399
- # license-checker option
400
- # --production : not prints devDependencies
401
- # --json : prints output file with json format
402
- # --out : output file name with path
403
- # --customPath : add the specified items to the usual ones
404
- command = 'license-checker --production --json --out ' + tmp_file_name + ' --customPath ' + tmp_custom_json
405
- command_ret = os.system(command)
406
- os.remove(tmp_custom_json)
407
- if flag_tmp_node_modules:
408
- shutil.rmtree('node_modules')
409
-
410
- return tmp_file_name
411
-
412
-
413
- def start_pip_licenses():
414
- global PIP_ACTIVATE
415
-
416
- tmp_file_name = "tmp_pip_license_output.json"
417
-
418
- if PIP_ACTIVATE.startswith("source "):
419
- tmp_activate = PIP_ACTIVATE[7:]
420
- PIP_ACTIVATE = ". " + tmp_activate
421
- elif PIP_ACTIVATE.startswith("conda "):
422
- if check_os() == "Linux":
423
- tmp_activate = "eval \"$(conda shell.bash hook)\""
424
- PIP_ACTIVATE = tmp_activate + PIP_ACTIVATE
425
-
426
- if check_os() == 'Windows':
427
- command_separator = "&"
428
- else:
429
- command_separator = ";"
430
- activate_command = PIP_ACTIVATE
431
- install_pip_command = "pip install pip-licenses"
432
- pip_licenses_command = "pip-licenses --from=mixed --with-url --format=json --with-license-file > " + tmp_file_name
433
- uninstall_pip_command = "pip uninstall -y pip-licenses PTable"
434
- deactivate_command = PIP_DEACTIVATE
435
-
436
- command_list = [activate_command, install_pip_command, pip_licenses_command, uninstall_pip_command,
437
- deactivate_command]
438
- command = command_separator.join(command_list)
439
-
440
- ret = subprocess.call(command, shell=True)
441
-
442
- if ret == 0:
443
- return tmp_file_name
444
- else:
445
- logger.error("### Error Message ###")
446
- logger.error("This command(" + command + ") returns an error.")
447
- sys.exit(1)
448
-
449
-
450
- def check_os():
451
- # return value : Linux, Windows, Darwin(Mac OS)
452
- return platform.system()
453
-
454
-
455
- def resource_path(relative_path):
456
- base_path = getattr(sys, '_MEIPASS', os.path.dirname(os.path.abspath(__file__)))
457
- return os.path.join(base_path, relative_path)
458
-
459
-
460
- def check_license_scanner(os_name):
461
- global license_scanner_url, license_scanner_bin
462
-
463
- if os_name == 'Linux':
464
- license_scanner_url = license_scanner_url_linux
465
- elif os_name == 'Darwin':
466
- license_scanner_url = license_scanner_url_macos
467
- elif os_name == 'Windows':
468
- license_scanner_url = license_scanner_url_windows
469
- else:
470
- logger.info("Not supported OS to analyze license text with binary.")
471
- return
472
-
473
- try:
474
- base_path = sys._MEIPASS
475
- except Exception:
476
- base_path = os.path.dirname(__file__)
477
-
478
- data_path = os.path.join(base_path, license_scanner_url)
479
- license_scanner_bin = data_path
480
-
481
-
482
- def check_and_run_license_scanner(file_dir, os_name):
483
- global license_scanner_bin
484
-
485
- try:
486
- tmp_output_file_name = "tmp_license_scanner_output.txt"
487
-
488
- if file_dir == "UNKNOWN":
489
- license_name = ""
490
- else:
491
- if os_name == 'Linux':
492
- run_license_scanner = license_scanner_bin + " " + file_dir + " > " + tmp_output_file_name
493
- elif os_name == 'Darwin':
494
- run_license_scanner = license_scanner_bin + " identify " + file_dir + " > " + tmp_output_file_name
495
- elif os_name == 'Windows':
496
- run_license_scanner = license_scanner_bin + " identify " + file_dir + " > " + tmp_output_file_name
497
- else:
498
- run_license_scanner = ''
499
-
500
- if run_license_scanner is None:
501
- license_name = ""
502
- return license_name
503
- else:
504
- ret = os.system(run_license_scanner)
505
- if ret != 0:
506
- return ""
507
-
508
- fp = open(tmp_output_file_name, "r", encoding='utf8')
509
- license_output = fp.read()
510
- fp.close()
511
- os.remove(tmp_output_file_name)
512
-
513
- if os_name == 'Linux':
514
- license_output_re = re.findall(r'.*contains license\(s\)\s(.*)', license_output)
515
- else:
516
- license_output_re = re.findall(r"License:\s{1}(\S*)\s{1}", license_output)
517
-
518
- if len(license_output_re) == 1:
519
- license_name = license_output_re[0]
520
- if license_name == "No_license_found":
521
- license_name = ""
522
- else:
523
- license_name = ""
524
-
525
- except Exception as ex:
526
- logger.info("There are some errors for the license scanner binary")
527
- logger.info("Error:"+ str(ex))
528
- license_name = ""
529
-
530
- return license_name
531
-
532
-
533
- def check_multi_license(license_name):
534
- if isinstance(license_name, list):
535
- multi_license = 1
536
- else:
537
- multi_license = 0
538
-
539
- return multi_license
540
-
541
-
542
- def parse_oss_name_version_in_filename(name):
543
- filename = name.rstrip('.jar')
544
- split_name = filename.rpartition('-')
545
-
546
- oss_name = split_name[0]
547
- oss_version = split_name[2]
548
-
549
- return oss_name, oss_version
550
-
551
-
552
- def parse_oss_name_version_in_artifactid(name):
553
- artifact_comp = name.split(':')
554
-
555
- group_id = artifact_comp[0]
556
- artifact_id = artifact_comp[1]
557
- oss_version = artifact_comp[2]
558
-
559
- return group_id, artifact_id, oss_version
560
-
561
-
562
- def version_refine(oss_version):
563
- version_cmp = oss_version.upper()
564
-
565
- if version_cmp.find(".RELEASE") != -1:
566
- oss_version = version_cmp.rstrip(".RELEASE")
567
- elif version_cmp.find(".FINAL") != -1:
568
- oss_version = version_cmp.rstrip(".FINAL")
569
-
570
- return oss_version
571
-
572
-
573
- #################################################################################################################################
574
- # Functions for parsing generated file from OSS that could scan license information about dependencies of each package manager. #
575
- #################################################################################################################################
576
-
577
- def check_UNKNOWN(text):
578
- if text == ['UNKNOWN'] or text == 'UNKNOWN':
579
- text = ""
580
-
581
- return text
582
-
583
-
584
- def parse_and_generate_output_pip(tmp_file_name):
585
- global license_scanner_bin
586
-
587
- os_name = check_os()
588
- check_license_scanner(os_name)
589
-
590
- sheet_list = {}
591
-
592
- try:
593
- with open(tmp_file_name, 'r', encoding='utf-8') as json_file:
594
- json_data = json.load(json_file)
595
-
596
- sheet_list["SRC"] = []
597
-
598
- for d in json_data:
599
- oss_init_name = d['Name']
600
- oss_name = "pypi:" + oss_init_name
601
- license_name = check_UNKNOWN(d['License'])
602
- homepage = check_UNKNOWN(d['URL'])
603
- oss_version = d['Version']
604
- dn_loc = dn_url + oss_init_name + "/" + oss_version
605
-
606
- license_file_dir = d['LicenseFile']
607
- license_name_with_license_scanner = check_and_run_license_scanner(license_file_dir, os_name)
608
-
609
- if license_name_with_license_scanner != "":
610
- license_name = license_name_with_license_scanner
611
-
612
- sheet_list["SRC"].append(['pip', oss_name, oss_version, license_name, dn_loc, homepage, '', '', ''])
613
-
614
- except Exception as ex:
615
- logger.error("Error:"+ str(ex))
616
-
617
- if os.path.isdir(venv_tmp_dir):
618
- shutil.rmtree(venv_tmp_dir)
619
- logger.info("remove tmp directory: " + venv_tmp_dir)
620
-
621
- return sheet_list
622
-
623
-
624
- def parse_and_generate_output_npm(tmp_file_name):
625
- with open(tmp_file_name, 'r', encoding='utf8') as json_file:
626
- json_data = json.load(json_file)
627
-
628
- sheet_list = {}
629
- sheet_list["SRC"] = []
630
-
631
- keys = [key for key in json_data]
632
-
633
- for i in range(0, len(keys)):
634
- d = json_data.get(keys[i - 1])
635
- oss_init_name = d['name']
636
- oss_name = "npm:" + oss_init_name
637
-
638
- if d['licenses']:
639
- license_name = d['licenses']
640
- else:
641
- license_name = ''
642
-
643
- oss_version = d['version']
644
-
645
- if d['repository']:
646
- dn_loc = d['repository']
647
- else:
648
- dn_loc = dn_url + oss_init_name + '/v/' + oss_version
649
-
650
- homepage = dn_url + oss_init_name
651
-
652
- if d['copyright']:
653
- copyright_text = d['copyright']
654
- else:
655
- copyright_text = ''
656
-
657
- multi_license = check_multi_license(license_name)
658
-
659
- if multi_license == 1:
660
- for l_idx in range(0, len(license_name)):
661
- license_name = license_name[l_idx].replace(",", "")
662
-
663
- sheet_list["SRC"].append(['package.json', oss_name, oss_version, license_name, dn_loc, homepage, '', '', ''])
664
- else:
665
- license_name = license_name.replace(",", "")
666
-
667
- sheet_list["SRC"].append(['package.json', oss_name, oss_version, license_name, dn_loc, homepage, '', '', ''])
668
-
669
- return sheet_list
670
-
671
-
672
- def parse_and_generate_output_maven(input_fp):
673
- tree = parse(input_fp)
674
-
675
- root = tree.getroot()
676
- dependencies = root.find("dependencies")
677
-
678
- sheet_list = {}
679
- sheet_list["SRC"] = []
680
-
681
- for d in dependencies.iter("dependency"):
682
- groupid = d.findtext("groupId")
683
- artifactid = d.findtext("artifactId")
684
- version = d.findtext("version")
685
- oss_version = version_refine(version)
686
-
687
- oss_name = groupid + ":" + artifactid
688
- dn_loc = dn_url + groupid + "/" + artifactid + "/" + version
689
- homepage = dn_url + groupid + "/" + artifactid
690
-
691
- licenses = d.find("licenses")
692
- if len(licenses):
693
- license_names = []
694
- for key_license in licenses.iter("license"):
695
- license_names.append(key_license.findtext("name").replace(",", ""))
696
- license_name = ', '.join(license_names)
697
- else:
698
- # Case that doesn't include License tag value.
699
- license_name = ''
700
-
701
- sheet_list["SRC"].append(['pom.xml', oss_name, oss_version, license_name, dn_loc, homepage, '', '', ''])
702
-
703
- return sheet_list
704
-
705
-
706
- def parse_and_generate_output_gradle(input_fp):
707
- json_data = json.load(input_fp)
708
-
709
- sheet_list = {}
710
- sheet_list["SRC"] = []
711
-
712
- for d in json_data['dependencies']:
713
-
714
- used_filename = "false"
715
- group_id = ""
716
- artifact_id = ""
717
-
718
- name = d['name']
719
- filename = d['file']
720
-
721
- if name != filename:
722
- group_id, artifact_id, oss_ini_version = parse_oss_name_version_in_artifactid(name)
723
- oss_name = group_id + ":" + artifact_id
724
- else:
725
- oss_name, oss_ini_version = parse_oss_name_version_in_filename(filename)
726
- used_filename = "true"
727
-
728
- oss_version = version_refine(oss_ini_version)
729
-
730
- license_names = []
731
- for licenses in d['licenses']:
732
- license_names.append(licenses['name'].replace(",", ""))
733
- license_name = ', '.join(license_names)
734
-
735
- if used_filename == "true" or group_id == "":
736
- dn_loc = 'Unknown'
737
- homepage = ''
738
-
739
- else:
740
- dn_loc = dn_url + group_id + "/" + artifact_id + "/" + oss_ini_version
741
- homepage = dn_url + group_id + "/" + artifact_id
742
-
743
- sheet_list["SRC"].append(['build.gradle', oss_name, oss_version, license_name, dn_loc, homepage, '', '', ''])
744
-
745
- return sheet_list
746
-
747
-
748
- def preprocess_pub_result(input_file):
749
- matched_json = re.findall(r'final ossLicenses = <String, dynamic>({.*});', input_file.read())
750
-
751
- if matched_json[0] is not None:
752
- return matched_json[0]
753
- else:
754
- logger.error("### Error Message ###")
755
- logger.error("Cannot parse the result json from pub input file.")
756
- exit(1)
757
-
758
-
759
- def parse_and_generate_output_pub(tmp_file_name):
760
- global license_scanner_bin, tmp_license_txt_file_name
761
-
762
- json_txt = preprocess_pub_result(tmp_file_name)
763
- json_data = json.loads(json_txt)
764
-
765
- sheet_list = {}
766
- sheet_list["SRC"] = []
767
-
768
- os_name = check_os()
769
- check_license_scanner(os_name)
770
-
771
- idx = 1
772
- for key in json_data:
773
- oss_origin_name = json_data[key]['name']
774
- oss_name = "pub:" + oss_origin_name
775
- oss_version = json_data[key]['version']
776
- homepage = json_data[key]['homepage']
777
- # dn_loc = homepage
778
- dn_loc = dn_url + oss_origin_name + "/versions/" + oss_version
779
- license_txt = json_data[key]['license']
780
-
781
- tmp_license_txt = open(tmp_license_txt_file_name, 'w', encoding='utf-8')
782
- tmp_license_txt.write(license_txt)
783
- # tmp_license_txt.write(license_txt.encode().decode('utf-8'))
784
- tmp_license_txt.close()
785
-
786
- license_name_with_license_scanner = check_and_run_license_scanner(tmp_license_txt_file_name, os_name)
787
-
788
- if license_name_with_license_scanner != "":
789
- license_name = license_name_with_license_scanner
790
- else:
791
- license_name = ''
792
-
793
- sheet_list["SRC"].append(['pubspec.yaml', oss_name, oss_version, license_name, dn_loc, homepage, '', '', ''])
794
-
795
- os.remove(tmp_license_txt_file_name)
796
-
797
- return sheet_list
798
-
799
-
800
- def compile_pods_item(pods_item, spec_repo_list, pod_in_sepc_list, pod_not_in_spec_list):
801
- pods_item_re = re.findall(r'(\S*)\s{1}\((.*)\)', pods_item)
802
-
803
- oss_name = pods_item_re[0][0]
804
- oss_version = pods_item_re[0][1]
805
-
806
- oss_info = []
807
- oss_info.append(oss_name)
808
- oss_info.append(oss_version)
809
-
810
- if oss_name in spec_repo_list:
811
- pod_in_sepc_list.append(oss_info)
812
- spec_repo_list.remove(oss_name)
813
- else:
814
- pod_not_in_spec_list.append(oss_info)
815
-
816
- return pod_in_sepc_list, spec_repo_list, pod_not_in_spec_list
817
-
818
-
819
- def parse_and_generate_output_cocoapods(input_fp):
820
- global source_type
821
-
822
- pod_in_sepc_list = []
823
- pod_not_in_spec_list = []
824
- spec_repo_list = []
825
- podfile_yaml = yaml.load(input_fp, Loader=yaml.FullLoader)
826
-
827
- for spec_item_key in podfile_yaml['SPEC REPOS']:
828
- for spec_item in podfile_yaml['SPEC REPOS'][spec_item_key]:
829
- spec_repo_list.append(spec_item)
830
-
831
- for pods_list in podfile_yaml['PODS']:
832
- if not isinstance(pods_list, str):
833
- for pods_list_key, pods_list_item in pods_list.items():
834
- pod_in_sepc_list, spec_repo_list, pod_not_in_spec_list = compile_pods_item(pods_list_key, spec_repo_list, pod_in_sepc_list, pod_not_in_spec_list)
835
- else:
836
- pod_in_sepc_list, spec_repo_list, pod_not_in_spec_list = compile_pods_item(pods_list, spec_repo_list, pod_in_sepc_list, pod_not_in_spec_list)
837
-
838
- if len(spec_repo_list) != 0:
839
- for spec_in_item in spec_repo_list:
840
- spec_oss_name_adding_core = spec_in_item + "/Core"
841
- for pod_not_item in pod_not_in_spec_list:
842
- if spec_oss_name_adding_core == pod_not_item[0]:
843
- pod_in_sepc_list.append([spec_in_item, pod_not_item[1]])
844
-
845
-
846
- sheet_list = {}
847
- sheet_list["SRC"] = []
848
-
849
- idx = 1
850
- for pod_oss in pod_in_sepc_list:
851
-
852
- search_oss_name = ""
853
- for alphabet_oss in pod_oss[0]:
854
- if not alphabet_oss.isalnum():
855
- search_oss_name += "\\\\" + alphabet_oss
856
- else:
857
- search_oss_name += alphabet_oss
858
-
859
- command = 'pod spec which --regex ' + '^' +search_oss_name + '$'
860
- spec_which = os.popen(command).readline()
861
- if spec_which.startswith('[!]'):
862
- logger.error("### Error Message ###")
863
- logger.error("This command(" + command + ") returns an error")
864
- sys.exit(1)
865
-
866
- file_path = spec_which.rstrip().split(os.path.sep)
867
- if file_path[0] == '':
868
- file_path_without_version = os.path.join(os.sep,*file_path[:-2])
869
- else:
870
- file_path_without_version = os.path.join(*file_path[:-2])
871
- spec_file_path = os.path.join(file_path_without_version,pod_oss[1],file_path[-1])
872
-
873
- with open(spec_file_path, 'r', encoding='utf8') as json_file:
874
- json_data = json.load(json_file)
875
-
876
- keys = [key for key in json_data]
877
-
878
- oss_origin_name = json_data['name']
879
- oss_name = "cocoapods:" + oss_origin_name
880
- oss_version = json_data['version']
881
- homepage = dn_url + 'pods/' + oss_origin_name
882
-
883
- if not isinstance(json_data['license'], str):
884
- if 'type' in json_data['license']:
885
- license_name = json_data['license']['type']
886
- else:
887
- license_name = json_data['license']
888
-
889
- license_name = license_name.replace(",", "")
890
-
891
- source_keys = [key for key in json_data['source']]
892
- for src_type_i in source_type:
893
- if src_type_i in source_keys:
894
- dn_loc = json_data['source'][src_type_i]
895
- if dn_loc.endswith('.git'):
896
- dn_loc = dn_loc[:-4]
897
-
898
- sheet_list["SRC"].append(['Podfile.lock', oss_name, oss_version, license_name, dn_loc, homepage, '', '', ''])
899
-
900
- return sheet_list
901
-
902
-
903
- ###########################################
904
- # Main functions for each package manager #
905
- ###########################################
906
-
907
- def main_pip():
908
- # It needs the virtualenv path that pip packages are installed.
909
- check_virtualenv_arg()
910
-
911
- # Run the command 'pip-licenses with option'.
912
- tmp_file_name = start_pip_licenses()
913
-
914
- # Make output file for OSS report using temporary output file for pip-licenses.
915
- sheet_list = parse_and_generate_output_pip(tmp_file_name)
916
-
917
- # Remove temporary output file.
918
- if os.path.isfile(tmp_file_name):
919
- os.remove(tmp_file_name)
920
-
921
- return sheet_list
922
-
923
-
924
- def main_npm():
925
- # Install the license-checker (npm package) with global option.
926
- # os.system("npm install -g license-checker")
927
-
928
- # Run the command 'license-checker' with option'.
929
- tmp_file_name = start_license_checker()
930
-
931
- # Make output file for OSS report using temporary output file for license-checker.
932
- sheet_list = parse_and_generate_output_npm(tmp_file_name)
933
-
934
- # Remove temporary output file.
935
- os.remove(tmp_file_name)
936
-
937
- return sheet_list
938
-
939
-
940
- def main_maven():
941
- # Before running this script, first you should add the maven-license-plugin in pom.xml and run it.
942
-
943
- # open license.xml
944
- input_fp = open_input_file()
945
-
946
- # Make output file for OSS report using temporary output file for maven-license-plugin.
947
- sheet_list = parse_and_generate_output_maven(input_fp)
948
-
949
- # close licenses.xml
950
- close_input_file(input_fp)
951
-
952
- if not is_maven_first_try:
953
- clean_run_maven_plugin_output()
954
-
955
- return sheet_list
956
-
957
-
958
- def main_gradle():
959
- # Before running this script, first you should add the com.github.hierynomus.license in build.gradle and run it.
960
-
961
- # open dependency-license.json
962
- input_fp = open_input_file()
963
-
964
- # Make output file for OSS report using temporary output file for License Gradle Plugin.
965
- sheet_list = parse_and_generate_output_gradle(input_fp)
966
-
967
- # close dependency-license.json
968
- close_input_file(input_fp)
969
-
970
- return sheet_list
971
-
972
-
973
- def main_pub():
974
- input_fp = open_input_file()
975
-
976
- sheet_list = parse_and_generate_output_pub(input_fp)
977
-
978
- close_input_file(input_fp)
979
-
980
- return sheet_list
981
-
982
-
983
- def main_cocoapods():
984
-
985
- # open Podfile.lock
986
- input_fp = open_input_file()
987
-
988
- sheet_list = parse_and_generate_output_cocoapods(input_fp)
989
-
990
- close_input_file(input_fp)
991
-
992
- return sheet_list
993
-
994
-
995
- def main():
996
-
997
- global PACKAGE, output_file_name, input_file_name, CUR_PATH, OUTPUT_RESULT_DIR, MANUAL_DETECT, OUTPUT_CUSTOM_DIR, dn_url, PIP_ACTIVATE, PIP_DEACTIVATE
998
- global license_scanner_url, license_scanner_bin, venv_tmp_dir, pom_backup, is_maven_first_try, tmp_license_txt_file_name, source_type, logger
999
-
1000
- start_time = datetime.now().strftime('%Y-%m-%d_%H-%M-%S')
1001
-
1002
- parse_option()
1003
- logger = init_log(os.path.join(OUTPUT_RESULT_DIR, "fosslight_dependency_log_"+start_time+".txt"), True, 20, 10)
1004
-
1005
- # Check the latest version
1006
- latest_version = lastversion.has_update(repo="fosslight_dependency", at='pip', current_version=__version__)
1007
- if latest_version:
1008
- logger.info('### Version Info ###')
1009
- logger.info('Newer version is available:{}'.format(str(latest_version)))
1010
- logger.info('You can update it with command (\'pip install fosslight_dependency --upgrade\')')
1011
-
1012
- # Configure global variables according to package manager.
1013
- try:
1014
- configure_package()
1015
- except:
1016
- logger.error("Error : Failed to configure package.")
1017
- sys.exit(1)
1018
-
1019
- if PACKAGE == "pip":
1020
- dn_url = "https://pypi.org/project/"
1021
- output_file_name = "pip_dependency_output"
1022
- venv_tmp_dir = "venv_osc_dep_tmp"
1023
-
1024
- elif PACKAGE == "npm":
1025
- dn_url = "https://www.npmjs.com/package/"
1026
- output_file_name = "npm_dependency_output"
1027
-
1028
- elif PACKAGE == "maven":
1029
- dn_url = "https://mvnrepository.com/artifact/"
1030
- input_file_name = "target/generated-resources/licenses.xml"
1031
- output_file_name = "maven_dependency_output"
1032
- pom_backup = "pom.xml_backup"
1033
- is_maven_first_try = True
1034
-
1035
- elif PACKAGE == "gradle":
1036
- dn_url = "https://mvnrepository.com/artifact/"
1037
- input_file_name = "build/reports/license/dependency-license.json"
1038
- output_file_name = "gradle_dependency_output"
1039
-
1040
- elif PACKAGE == "pub":
1041
- dn_url = "https://pub.dev/packages/"
1042
- input_file_name = "lib/oss_licenses.dart"
1043
- output_file_name = "pub_dependency_output"
1044
- tmp_license_txt_file_name = "tmp_license.txt"
1045
-
1046
- elif PACKAGE == "cocoapods":
1047
- dn_url = "https://cocoapods.org/"
1048
- input_file_name = "Podfile.lock"
1049
- output_file_name = "cocoapods_dependency_output"
1050
- source_type = ['git', 'http', 'svn', 'hg']
1051
-
1052
- else:
1053
- logger.error("### Error Message ###")
1054
- logger.error("You enter the wrong first argument.")
1055
- logger.error("Please enter the supported package manager. (Check the help message with (-h) option.)")
1056
- sys.exit(1)
1057
-
1058
- if PACKAGE == "pip":
1059
- sheet_list = main_pip()
1060
- elif PACKAGE == "npm":
1061
- sheet_list = main_npm()
1062
- elif PACKAGE == "maven":
1063
- sheet_list = main_maven()
1064
- elif PACKAGE == "gradle":
1065
- sheet_list = main_gradle()
1066
- elif PACKAGE == "pub":
1067
- sheet_list = main_pub()
1068
- elif PACKAGE == "cocoapods":
1069
- sheet_list = main_cocoapods()
1070
- else:
1071
- logger.error("### Error Message ###")
1072
- logger.error("Please enter the supported package manager. (Check the help message with (-h) option.)")
1073
- sys.exit(1)
1074
-
1075
- if sheet_list is not None:
1076
- success, msg = write_excel_and_csv(os.path.join(OUTPUT_RESULT_DIR, output_file_name), sheet_list)
1077
- if success:
1078
- logger.info("Generated {0}.xlsx and {0}.csv into {1}!".format(output_file_name, OUTPUT_RESULT_DIR))
1079
- else:
1080
- logger.error("Fail to generate result file. msg:()", msg)
1081
- else:
1082
- logger.error("Fail to analyze dependency.")
1083
-
1084
- logger.info("### FINISH!! ###")
1085
-
1086
- sys.exit(0)
1087
-
1088
-
1089
- if __name__ == '__main__':
1090
- main()