fosslight-source 2.3.6__tar.gz → 2.3.7__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.
Files changed (28) hide show
  1. {fosslight_source-2.3.6/src/fosslight_source.egg-info → fosslight_source-2.3.7}/PKG-INFO +1 -1
  2. {fosslight_source-2.3.6 → fosslight_source-2.3.7}/pyproject.toml +1 -1
  3. {fosslight_source-2.3.6 → fosslight_source-2.3.7}/src/fosslight_source/_scan_item.py +1 -0
  4. {fosslight_source-2.3.6 → fosslight_source-2.3.7}/src/fosslight_source/run_manifest_extractor.py +43 -0
  5. {fosslight_source-2.3.6 → fosslight_source-2.3.7/src/fosslight_source.egg-info}/PKG-INFO +1 -1
  6. {fosslight_source-2.3.6 → fosslight_source-2.3.7}/src/fosslight_source.egg-info/SOURCES.txt +1 -0
  7. fosslight_source-2.3.7/tests/test_manifest_composer.py +53 -0
  8. {fosslight_source-2.3.6 → fosslight_source-2.3.7}/LICENSE +0 -0
  9. {fosslight_source-2.3.6 → fosslight_source-2.3.7}/MANIFEST.in +0 -0
  10. {fosslight_source-2.3.6 → fosslight_source-2.3.7}/README.md +0 -0
  11. {fosslight_source-2.3.6 → fosslight_source-2.3.7}/setup.cfg +0 -0
  12. {fosslight_source-2.3.6 → fosslight_source-2.3.7}/src/fosslight_source/__init__.py +0 -0
  13. {fosslight_source-2.3.6 → fosslight_source-2.3.7}/src/fosslight_source/_help.py +0 -0
  14. {fosslight_source-2.3.6 → fosslight_source-2.3.7}/src/fosslight_source/_kb_client.py +0 -0
  15. {fosslight_source-2.3.6 → fosslight_source-2.3.7}/src/fosslight_source/_license_matched.py +0 -0
  16. {fosslight_source-2.3.6 → fosslight_source-2.3.7}/src/fosslight_source/_merge.py +0 -0
  17. {fosslight_source-2.3.6 → fosslight_source-2.3.7}/src/fosslight_source/_parsing_scancode_file_item.py +0 -0
  18. {fosslight_source-2.3.6 → fosslight_source-2.3.7}/src/fosslight_source/_parsing_scanoss_file.py +0 -0
  19. {fosslight_source-2.3.6 → fosslight_source-2.3.7}/src/fosslight_source/_scancode_ignore_binaries.py +0 -0
  20. {fosslight_source-2.3.6 → fosslight_source-2.3.7}/src/fosslight_source/cli.py +0 -0
  21. {fosslight_source-2.3.6 → fosslight_source-2.3.7}/src/fosslight_source/run_scancode.py +0 -0
  22. {fosslight_source-2.3.6 → fosslight_source-2.3.7}/src/fosslight_source/run_scanoss.py +0 -0
  23. {fosslight_source-2.3.6 → fosslight_source-2.3.7}/src/fosslight_source/run_spdx_extractor.py +0 -0
  24. {fosslight_source-2.3.6 → fosslight_source-2.3.7}/src/fosslight_source.egg-info/dependency_links.txt +0 -0
  25. {fosslight_source-2.3.6 → fosslight_source-2.3.7}/src/fosslight_source.egg-info/entry_points.txt +0 -0
  26. {fosslight_source-2.3.6 → fosslight_source-2.3.7}/src/fosslight_source.egg-info/requires.txt +0 -0
  27. {fosslight_source-2.3.6 → fosslight_source-2.3.7}/src/fosslight_source.egg-info/top_level.txt +0 -0
  28. {fosslight_source-2.3.6 → fosslight_source-2.3.7}/tests/test_tox.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fosslight_source
3
- Version: 2.3.6
3
+ Version: 2.3.7
4
4
  Summary: FOSSLight Source Scanner
5
5
  Author: LG Electronics
6
6
  License-Expression: Apache-2.0
@@ -7,7 +7,7 @@ build-backend = "setuptools.build_meta"
7
7
 
8
8
  [project]
9
9
  name = "fosslight_source"
10
- version = "2.3.6"
10
+ version = "2.3.7"
11
11
  description = "FOSSLight Source Scanner"
12
12
  readme = "README.md"
13
13
  license = "Apache-2.0"
@@ -18,6 +18,7 @@ _notice_filename = ['licen[cs]e[s]?', 'notice[s]?', 'legal', 'copyright[s]?', 'c
18
18
  _manifest_filename = [
19
19
  r'.*\.pom$',
20
20
  r'package\.json$',
21
+ r'composer\.json$',
21
22
  r'setup\.py$',
22
23
  r'setup\.cfg$',
23
24
  r'pyproject\.toml$',
@@ -74,6 +74,43 @@ def get_licenses_from_package_json(file_path: str) -> list[str]:
74
74
  return unique
75
75
 
76
76
 
77
+ def get_licenses_from_composer_json(file_path: str) -> list[str]:
78
+ """Extract licenses from Composer ``composer.json`` ``license`` field.
79
+
80
+ Composer schema allows a string or an array of strings
81
+ (SPDX identifiers / expressions).
82
+ """
83
+ try:
84
+ with open(file_path, 'r', encoding='utf-8') as f:
85
+ data = json.load(f)
86
+ except Exception as ex:
87
+ logger.info(f"Failed to read composer.json {file_path}: {ex}")
88
+ return []
89
+
90
+ if not isinstance(data, dict):
91
+ return []
92
+
93
+ licenses: list[str] = []
94
+ license_field = data.get('license')
95
+
96
+ def append_license_value(value) -> None:
97
+ if isinstance(value, str):
98
+ token = value.strip()
99
+ if token:
100
+ licenses.extend(_split_spdx_expression(token))
101
+ elif isinstance(value, list):
102
+ for item in value:
103
+ append_license_value(item)
104
+
105
+ append_license_value(license_field)
106
+
107
+ unique: list[str] = []
108
+ for lic in licenses:
109
+ if lic not in unique:
110
+ unique.append(lic)
111
+ return unique
112
+
113
+
77
114
  def get_licenses_from_setup_cfg(file_path: str) -> list[str]:
78
115
  try:
79
116
  import configparser
@@ -323,6 +360,12 @@ def get_manifest_licenses(file_path: str) -> list[str]:
323
360
  except Exception as ex:
324
361
  logger.info(f"Failed to extract license from package.json {file_path}: {ex}")
325
362
  return []
363
+ elif os.path.basename(file_path).lower() == 'composer.json':
364
+ try:
365
+ return get_licenses_from_composer_json(file_path)
366
+ except Exception as ex:
367
+ logger.info(f"Failed to extract license from composer.json {file_path}: {ex}")
368
+ return []
326
369
  elif os.path.basename(file_path).lower() == 'setup.cfg':
327
370
  try:
328
371
  return get_licenses_from_setup_cfg(file_path)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fosslight_source
3
- Version: 2.3.6
3
+ Version: 2.3.7
4
4
  Summary: FOSSLight Source Scanner
5
5
  Author: LG Electronics
6
6
  License-Expression: Apache-2.0
@@ -22,4 +22,5 @@ src/fosslight_source.egg-info/dependency_links.txt
22
22
  src/fosslight_source.egg-info/entry_points.txt
23
23
  src/fosslight_source.egg-info/requires.txt
24
24
  src/fosslight_source.egg-info/top_level.txt
25
+ tests/test_manifest_composer.py
25
26
  tests/test_tox.py
@@ -0,0 +1,53 @@
1
+ # Copyright (c) 2026 LG Electronics Inc.
2
+ # SPDX-License-Identifier: Apache-2.0
3
+ """Tests for composer.json manifest license extraction."""
4
+
5
+ from fosslight_source._scan_item import is_manifest_file
6
+ from fosslight_source.run_manifest_extractor import (
7
+ get_licenses_from_composer_json,
8
+ get_manifest_licenses,
9
+ )
10
+
11
+
12
+ def test_is_manifest_file_recognizes_composer_json():
13
+ assert is_manifest_file("/tmp/project/composer.json") is True
14
+ assert is_manifest_file("/tmp/project/Composer.JSON") is True
15
+
16
+
17
+ def test_get_licenses_from_composer_json_string(tmp_path):
18
+ path = tmp_path / "composer.json"
19
+ path.write_text('{"name": "acme/demo", "license": "MIT"}', encoding="utf-8")
20
+ assert get_licenses_from_composer_json(str(path)) == ["MIT"]
21
+
22
+
23
+ def test_get_licenses_from_composer_json_array(tmp_path):
24
+ path = tmp_path / "composer.json"
25
+ path.write_text(
26
+ '{"name": "acme/demo", "license": ["LGPL-2.1-only", "GPL-3.0-or-later"]}',
27
+ encoding="utf-8",
28
+ )
29
+ assert get_licenses_from_composer_json(str(path)) == [
30
+ "LGPL-2.1-only",
31
+ "GPL-3.0-or-later",
32
+ ]
33
+
34
+
35
+ def test_get_licenses_from_composer_json_spdx_expression(tmp_path):
36
+ path = tmp_path / "composer.json"
37
+ path.write_text(
38
+ '{"name": "acme/demo", "license": "(MIT OR Apache-2.0)"}',
39
+ encoding="utf-8",
40
+ )
41
+ assert get_licenses_from_composer_json(str(path)) == ["MIT", "Apache-2.0"]
42
+
43
+
44
+ def test_get_manifest_licenses_dispatches_composer_json(tmp_path):
45
+ path = tmp_path / "composer.json"
46
+ path.write_text('{"license": "BSD-3-Clause"}', encoding="utf-8")
47
+ assert get_manifest_licenses(str(path)) == ["BSD-3-Clause"]
48
+
49
+
50
+ def test_get_licenses_from_composer_json_missing_license(tmp_path):
51
+ path = tmp_path / "composer.json"
52
+ path.write_text('{"name": "acme/demo"}', encoding="utf-8")
53
+ assert get_licenses_from_composer_json(str(path)) == []