35 # Modifications: |
35 # Modifications: |
36 # - removed dependency to prettytable |
36 # - removed dependency to prettytable |
37 # - removed some not needed code |
37 # - removed some not needed code |
38 # - changed 'create_licenses_table' to 'create_licenses_list' |
38 # - changed 'create_licenses_table' to 'create_licenses_list' |
39 # - changed 'create_summary_table' to 'create_summary_list' |
39 # - changed 'create_summary_table' to 'create_summary_list' |
40 # - added 'create_summary_by_license_list' together with the |
|
41 # '--summary-by-license' switch to count each individual |
|
42 # license used |
|
43 # - changed 'create_output_string' to return a JSON string |
40 # - changed 'create_output_string' to return a JSON string |
44 # - added 'get_installed_distributions' to get the distributions |
|
45 # via pip in order to filter for 'local only' and/or 'user only' |
|
46 # |
41 # |
47 |
42 |
48 from __future__ import annotations |
43 from __future__ import annotations |
49 |
44 |
50 import argparse |
45 import argparse |
55 from collections import Counter |
50 from collections import Counter |
56 from enum import Enum, auto |
51 from enum import Enum, auto |
57 from pathlib import Path |
52 from pathlib import Path |
58 from typing import TYPE_CHECKING, List, Type, cast |
53 from typing import TYPE_CHECKING, List, Type, cast |
59 |
54 |
|
55 # modified for 'eric-ide' for Python < 3.8 |
|
56 try: |
|
57 from importlib import metadata as importlib_metadata |
|
58 except ImportError: |
|
59 importlib_metadata = None |
|
60 |
60 if TYPE_CHECKING: |
61 if TYPE_CHECKING: |
61 from typing import Iterator, Optional, Sequence |
62 from typing import Iterator, Optional, Sequence |
62 |
|
63 |
|
64 def get_installed_distributions(): |
|
65 """ |
|
66 Function to get the installed packages via pip. |
|
67 |
|
68 @return list of installed distributions |
|
69 @rtype list |
|
70 """ |
|
71 try: |
|
72 from importlib import metadata as importlib_metadata |
|
73 return importlib_metadata.distributions() |
|
74 except ImportError: |
|
75 try: |
|
76 from pip._internal.metadata import get_environment |
|
77 except ImportError: |
|
78 # For backward compatibility with pip version 20.3.4 |
|
79 from pip._internal.utils import misc |
|
80 return misc.get_installed_distributions( |
|
81 local_only=True, |
|
82 user_only=False |
|
83 ) |
|
84 else: |
|
85 from pip._internal.utils.compat import stdlib_pkgs |
|
86 dists = get_environment(None).iter_installed_distributions( |
|
87 local_only=True, |
|
88 user_only=False, |
|
89 skip=stdlib_pkgs, |
|
90 include_editables=True, |
|
91 editables_only=False, |
|
92 ) |
|
93 return [d._dist for d in dists] |
|
94 |
63 |
95 |
64 |
96 __pkgname__ = "pip-licenses" |
65 __pkgname__ = "pip-licenses" |
97 __version__ = "4.1.0" |
66 __version__ = "4.1.0" |
98 __author__ = "raimon" |
67 __author__ = "raimon" |
228 else: |
197 else: |
229 pkg_info[k] = filter_string(cast(str, pkg_info[k])) |
198 pkg_info[k] = filter_string(cast(str, pkg_info[k])) |
230 |
199 |
231 return pkg_info |
200 return pkg_info |
232 |
201 |
233 pkgs = get_installed_distributions() |
202 # modified for 'eric-ide' for Python < 3.8 |
|
203 if importlib_metadata is None: |
|
204 return [] |
|
205 else: |
|
206 pkgs = importlib_metadata.distributions() |
234 ignore_pkgs_as_lower = [pkg.lower() for pkg in args.ignore_packages] |
207 ignore_pkgs_as_lower = [pkg.lower() for pkg in args.ignore_packages] |
235 pkgs_as_lower = [pkg.lower() for pkg in args.packages] |
208 pkgs_as_lower = [pkg.lower() for pkg in args.packages] |
236 |
209 |
237 fail_on_licenses = set() |
210 fail_on_licenses = set() |
238 if args.fail_on: |
211 if args.fail_on: |
346 }) |
321 }) |
347 |
322 |
348 return licenses |
323 return licenses |
349 |
324 |
350 |
325 |
351 def create_summary_by_license_list(args: "CustomNamespace"): |
|
352 licenses_list = [] |
|
353 for pkg in get_packages(args): |
|
354 licenses_list.extend(select_license_by_source( |
|
355 args.from_, pkg['license_classifier'], pkg['license'])) |
|
356 counts = Counter(licenses_list) |
|
357 |
|
358 licenses = [] |
|
359 for license, count in counts.items(): |
|
360 licenses.append({ |
|
361 "Count": count, |
|
362 "License": license, |
|
363 }) |
|
364 |
|
365 return licenses |
|
366 |
|
367 |
|
368 def case_insensitive_set_intersect(set_a, set_b): |
326 def case_insensitive_set_intersect(set_a, set_b): |
369 """Same as set.intersection() but case-insensitive""" |
327 """Same as set.intersection() but case-insensitive""" |
370 common_items = set() |
328 common_items = set() |
371 set_b_lower = {item.lower() for item in set_b} |
329 set_b_lower = {item.lower() for item in set_b} |
372 for elem in set_a: |
330 for elem in set_a: |
444 output_fields.append("NoticeFile") |
402 output_fields.append("NoticeFile") |
445 |
403 |
446 return output_fields |
404 return output_fields |
447 |
405 |
448 |
406 |
|
407 # modified for 'eric-ide' |
449 def create_output_string(args: "CustomNamespace"): |
408 def create_output_string(args: "CustomNamespace"): |
450 output_fields = get_output_fields(args) |
409 output_fields = get_output_fields(args) |
451 |
410 |
452 if args.summary: |
411 if args.summary: |
453 licenses = create_summary_list(args) |
412 licenses = create_summary_list(args) |
454 elif args.summary_by_license: |
|
455 licenses = create_summary_by_license_list(args) |
|
456 else: |
413 else: |
457 licenses = create_licenses_list(args, output_fields) |
414 licenses = create_licenses_list(args, output_fields) |
458 |
415 |
459 return json.dumps(licenses) |
416 return json.dumps(licenses) |
460 |
417 |
656 '--summary', |
610 '--summary', |
657 action='store_true', |
611 action='store_true', |
658 default=False, |
612 default=False, |
659 help='dump summary of each license') |
613 help='dump summary of each license') |
660 common_options.add_argument( |
614 common_options.add_argument( |
661 '--summary-by-license', |
|
662 action='store_true', |
|
663 default=False, |
|
664 help='dump summary of each individual license') |
|
665 common_options.add_argument( |
|
666 '--output-file', |
615 '--output-file', |
667 action='store', type=str, |
616 action='store', type=str, |
668 help='save license list to file') |
617 help='save license list to file') |
669 common_options.add_argument( |
618 common_options.add_argument( |
670 "-i", |
619 "-i", |