fosslight-source 2.3.5__tar.gz → 2.3.6__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 (27) hide show
  1. {fosslight_source-2.3.5/src/fosslight_source.egg-info → fosslight_source-2.3.6}/PKG-INFO +1 -1
  2. {fosslight_source-2.3.5 → fosslight_source-2.3.6}/pyproject.toml +1 -1
  3. {fosslight_source-2.3.5 → fosslight_source-2.3.6}/src/fosslight_source/cli.py +2 -2
  4. {fosslight_source-2.3.5 → fosslight_source-2.3.6}/src/fosslight_source/run_scanoss.py +66 -11
  5. {fosslight_source-2.3.5 → fosslight_source-2.3.6/src/fosslight_source.egg-info}/PKG-INFO +1 -1
  6. {fosslight_source-2.3.5 → fosslight_source-2.3.6}/LICENSE +0 -0
  7. {fosslight_source-2.3.5 → fosslight_source-2.3.6}/MANIFEST.in +0 -0
  8. {fosslight_source-2.3.5 → fosslight_source-2.3.6}/README.md +0 -0
  9. {fosslight_source-2.3.5 → fosslight_source-2.3.6}/setup.cfg +0 -0
  10. {fosslight_source-2.3.5 → fosslight_source-2.3.6}/src/fosslight_source/__init__.py +0 -0
  11. {fosslight_source-2.3.5 → fosslight_source-2.3.6}/src/fosslight_source/_help.py +0 -0
  12. {fosslight_source-2.3.5 → fosslight_source-2.3.6}/src/fosslight_source/_kb_client.py +0 -0
  13. {fosslight_source-2.3.5 → fosslight_source-2.3.6}/src/fosslight_source/_license_matched.py +0 -0
  14. {fosslight_source-2.3.5 → fosslight_source-2.3.6}/src/fosslight_source/_merge.py +0 -0
  15. {fosslight_source-2.3.5 → fosslight_source-2.3.6}/src/fosslight_source/_parsing_scancode_file_item.py +0 -0
  16. {fosslight_source-2.3.5 → fosslight_source-2.3.6}/src/fosslight_source/_parsing_scanoss_file.py +0 -0
  17. {fosslight_source-2.3.5 → fosslight_source-2.3.6}/src/fosslight_source/_scan_item.py +0 -0
  18. {fosslight_source-2.3.5 → fosslight_source-2.3.6}/src/fosslight_source/_scancode_ignore_binaries.py +0 -0
  19. {fosslight_source-2.3.5 → fosslight_source-2.3.6}/src/fosslight_source/run_manifest_extractor.py +0 -0
  20. {fosslight_source-2.3.5 → fosslight_source-2.3.6}/src/fosslight_source/run_scancode.py +0 -0
  21. {fosslight_source-2.3.5 → fosslight_source-2.3.6}/src/fosslight_source/run_spdx_extractor.py +0 -0
  22. {fosslight_source-2.3.5 → fosslight_source-2.3.6}/src/fosslight_source.egg-info/SOURCES.txt +0 -0
  23. {fosslight_source-2.3.5 → fosslight_source-2.3.6}/src/fosslight_source.egg-info/dependency_links.txt +0 -0
  24. {fosslight_source-2.3.5 → fosslight_source-2.3.6}/src/fosslight_source.egg-info/entry_points.txt +0 -0
  25. {fosslight_source-2.3.5 → fosslight_source-2.3.6}/src/fosslight_source.egg-info/requires.txt +0 -0
  26. {fosslight_source-2.3.5 → fosslight_source-2.3.6}/src/fosslight_source.egg-info/top_level.txt +0 -0
  27. {fosslight_source-2.3.5 → fosslight_source-2.3.6}/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.5
3
+ Version: 2.3.6
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.5"
10
+ version = "2.3.6"
11
11
  description = "FOSSLight Source Scanner"
12
12
  readme = "README.md"
13
13
  license = "Apache-2.0"
@@ -219,13 +219,13 @@ def create_report_file(
219
219
  scan_item.set_cover_comment("(No OSS detected.)")
220
220
 
221
221
  if scanoss_skipped:
222
- is_kb_success = run_kb_msg != "" and "Completed" in run_kb_msg
222
+ is_kb_success = run_kb_msg != "" and run_kb_msg.endswith("Completed")
223
223
  if is_kb_success:
224
224
  scan_item.set_cover_comment("SCANOSS replaced with KB")
225
225
  else:
226
226
  scan_item.set_cover_comment("SCANOSS skipped")
227
227
 
228
- if run_kb_msg:
228
+ if run_kb_msg and not run_kb_msg.endswith("Completed"):
229
229
  scan_item.set_cover_comment(run_kb_msg)
230
230
  display_mode = selected_scanner
231
231
  if selected_scanner == ALL_MODE:
@@ -59,6 +59,7 @@ def run_scanoss_py(path_to_scan: str, output_path: str = "", format: list = [],
59
59
  if os.path.exists(output_json_file):
60
60
  os.remove(output_json_file)
61
61
 
62
+ output_buffer = io.StringIO()
62
63
  try:
63
64
  logger.debug(f"|---Running SCANOSS on {path_to_scan}")
64
65
  scanoss_settings = ScanossSettings()
@@ -69,22 +70,76 @@ def run_scanoss_py(path_to_scan: str, output_path: str = "", format: list = [],
69
70
  scan_options=ScanType.SCAN_SNIPPETS.value,
70
71
  nb_threads=num_threads if num_threads > 0 else 10,
71
72
  scanoss_settings=scanoss_settings,
72
- timeout=timeout
73
+ timeout=timeout,
74
+ retry=0
73
75
  )
74
- output_buffer = io.StringIO()
76
+
77
+ # Check API connectivity & API Limit using dummy WFP POST
78
+ try:
79
+ logger.debug(f"|---Checking SCANOSS API connectivity to {scanner.scanoss_api.url}")
80
+ dummy_wfp = "file=72214db4e1e543018d1bafe86ea3b444,21,dummy.txt\nfh2=b200cd2eff5d535886e598b3a833aab5\n"
81
+ ping_response = scanner.scanoss_api.session.post(
82
+ scanner.scanoss_api.url,
83
+ files={'file': ('dummy.wfp', dummy_wfp)},
84
+ headers=scanner.scanoss_api.headers,
85
+ timeout=5
86
+ )
87
+ if ping_response.status_code != 200:
88
+ response_text = ping_response.text.lower()
89
+ is_limit = ping_response.status_code in [429, 503]
90
+ is_limit = is_limit or "rate limit" in response_text
91
+ is_limit = is_limit or "limits being exceeded" in response_text
92
+ if is_limit:
93
+ logger.debug(f"[SCANOSS] API Limit Exceeded: HTTP {ping_response.status_code}")
94
+ elif ping_response.status_code in [401, 403]:
95
+ logger.debug(f"[SCANOSS] Authentication Failed: HTTP {ping_response.status_code}")
96
+ else:
97
+ logger.debug(f"[SCANOSS] API is not ready: HTTP {ping_response.status_code}")
98
+ scanoss_skipped = True
99
+ return scanoss_file_list, scanoss_skipped
100
+ except Exception as ping_error:
101
+ logger.debug(f"[SCANOSS] Connection failed to {scanner.scanoss_api.url}: {ping_error}")
102
+ scanoss_skipped = True
103
+ return scanoss_file_list, scanoss_skipped
104
+
75
105
  with contextlib.redirect_stdout(output_buffer), contextlib.redirect_stderr(output_buffer):
76
106
  scanner.scan_folder_with_options(scan_dir=path_to_scan)
77
- captured_output = output_buffer.getvalue()
78
- api_limit_exceed = "due to service limits being exceeded" in captured_output
79
- timeout_occurred = "The SCANOSS API request timed out" in captured_output
107
+ except Exception as error:
108
+ logger.debug(f"SCANOSS execution failed: {error}")
109
+
110
+ captured_output = output_buffer.getvalue()
111
+ if captured_output:
112
+ for line in captured_output.splitlines():
113
+ line_strip = line.strip()
114
+ if line_strip.startswith("ERROR:") or "rejected" in line_strip:
115
+ logger.debug(f"[SCANOSS] {line_strip}")
116
+
117
+ api_limit_patterns = [
118
+ "due to service limits being exceeded",
119
+ "service limits/rate limit being exceeded",
120
+ "Rate limit exceeded",
121
+ "HTTP 429"
122
+ ]
123
+ timeout_patterns = [
124
+ "The SCANOSS API request timed out",
125
+ "Service unavailable (HTTP 503)",
126
+ "The SCANOSS API is currently unavailable",
127
+ "ConnectionError communicating with",
128
+ "The SCANOSS API request failed",
129
+ "Connection aborted",
130
+ "RemoteDisconnected"
131
+ ]
132
+ api_limit_exceed = any(p in captured_output for p in api_limit_patterns)
133
+ timeout_occurred = any(p in captured_output for p in timeout_patterns)
80
134
  if timeout_occurred or api_limit_exceed:
81
135
  scanoss_skipped = True
82
- if timeout_occurred:
83
- logger.debug("SCANOSS skipped (Timeout)")
84
- elif api_limit_exceed:
136
+ if api_limit_exceed:
85
137
  logger.debug("SCANOSS skipped (API Limit Exceeded)")
138
+ elif timeout_occurred:
139
+ logger.debug("SCANOSS skipped (Timeout)")
86
140
 
87
- if os.path.isfile(output_json_file):
141
+ if os.path.isfile(output_json_file):
142
+ try:
88
143
  logger.debug("|---SCANOSS Parsing")
89
144
  with open(output_json_file, "r") as st_json:
90
145
  st_python = json.load(st_json)
@@ -96,8 +151,8 @@ def run_scanoss_py(path_to_scan: str, output_path: str = "", format: list = [],
96
151
  with open(output_json_file, "r") as st_json:
97
152
  st_python = json.load(st_json)
98
153
  scanoss_file_list = parsing_scan_result(st_python, excluded_files)
99
- except Exception as error:
100
- logger.debug(f"SCANOSS Parsing {path_to_scan}: {error}")
154
+ except Exception as error:
155
+ logger.debug(f"SCANOSS Parsing {path_to_scan}: {error}")
101
156
 
102
157
  if not write_json_file:
103
158
  if os.path.isfile(output_json_file):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fosslight_source
3
- Version: 2.3.5
3
+ Version: 2.3.6
4
4
  Summary: FOSSLight Source Scanner
5
5
  Author: LG Electronics
6
6
  License-Expression: Apache-2.0