fosslight-util 2.1.38__py3-none-any.whl → 2.1.40__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.
- fosslight_util/download.py +83 -19
- fosslight_util/exclude.py +17 -4
- fosslight_util/help.py +29 -17
- fosslight_util/write_excel.py +7 -2
- {fosslight_util-2.1.38.dist-info → fosslight_util-2.1.40.dist-info}/METADATA +2 -2
- {fosslight_util-2.1.38.dist-info → fosslight_util-2.1.40.dist-info}/RECORD +10 -10
- {fosslight_util-2.1.38.dist-info → fosslight_util-2.1.40.dist-info}/WHEEL +0 -0
- {fosslight_util-2.1.38.dist-info → fosslight_util-2.1.40.dist-info}/entry_points.txt +0 -0
- {fosslight_util-2.1.38.dist-info → fosslight_util-2.1.40.dist-info}/licenses/LICENSE +0 -0
- {fosslight_util-2.1.38.dist-info → fosslight_util-2.1.40.dist-info}/top_level.txt +0 -0
fosslight_util/download.py
CHANGED
|
@@ -10,7 +10,7 @@ import zipfile
|
|
|
10
10
|
import logging
|
|
11
11
|
import argparse
|
|
12
12
|
import shutil
|
|
13
|
-
from git import
|
|
13
|
+
from git import Git
|
|
14
14
|
import bz2
|
|
15
15
|
import contextlib
|
|
16
16
|
from datetime import datetime
|
|
@@ -217,7 +217,19 @@ def get_remote_refs(git_url: str):
|
|
|
217
217
|
tags = []
|
|
218
218
|
branches = []
|
|
219
219
|
try:
|
|
220
|
-
|
|
220
|
+
env = os.environ.copy()
|
|
221
|
+
env["GIT_TERMINAL_PROMPT"] = "0"
|
|
222
|
+
env["GIT_ASKPASS"] = "echo"
|
|
223
|
+
env["GIT_CREDENTIAL_HELPER"] = ""
|
|
224
|
+
if "GIT_SSH_COMMAND" not in env:
|
|
225
|
+
env["GIT_SSH_COMMAND"] = "ssh -o BatchMode=yes -o StrictHostKeyChecking=no"
|
|
226
|
+
else:
|
|
227
|
+
env["GIT_SSH_COMMAND"] = env["GIT_SSH_COMMAND"] + " -o BatchMode=yes"
|
|
228
|
+
cp = subprocess.run(
|
|
229
|
+
["git", "-c", "credential.helper=", "-c", "credential.helper=!",
|
|
230
|
+
"ls-remote", "--tags", "--heads", git_url],
|
|
231
|
+
env=env, capture_output=True, text=True, timeout=30,
|
|
232
|
+
stdin=subprocess.DEVNULL)
|
|
221
233
|
if cp.returncode == 0:
|
|
222
234
|
for line in cp.stdout.splitlines():
|
|
223
235
|
parts = line.split('\t')
|
|
@@ -291,32 +303,84 @@ def download_git_repository(refs_to_checkout, git_url, target_dir, tag, called_c
|
|
|
291
303
|
|
|
292
304
|
logger.info(f"Download git url :{git_url}")
|
|
293
305
|
env = os.environ.copy()
|
|
294
|
-
|
|
295
|
-
|
|
306
|
+
env["GIT_TERMINAL_PROMPT"] = "0"
|
|
307
|
+
if platform.system() == "Windows":
|
|
308
|
+
env["GIT_ASKPASS"] = "echo"
|
|
309
|
+
else:
|
|
310
|
+
env["GIT_ASKPASS"] = "/bin/echo"
|
|
311
|
+
env["GIT_CREDENTIAL_HELPER"] = ""
|
|
312
|
+
# Disable credential helper via config
|
|
313
|
+
if "GIT_CONFIG_COUNT" not in env:
|
|
314
|
+
env["GIT_CONFIG_COUNT"] = "1"
|
|
315
|
+
env["GIT_CONFIG_KEY_0"] = "credential.helper"
|
|
316
|
+
env["GIT_CONFIG_VALUE_0"] = ""
|
|
317
|
+
if "GIT_SSH_COMMAND" not in env:
|
|
318
|
+
env["GIT_SSH_COMMAND"] = "ssh -o BatchMode=yes -o StrictHostKeyChecking=no"
|
|
319
|
+
else:
|
|
320
|
+
env["GIT_SSH_COMMAND"] = env["GIT_SSH_COMMAND"] + " -o BatchMode=yes"
|
|
321
|
+
|
|
296
322
|
if refs_to_checkout:
|
|
297
323
|
try:
|
|
298
|
-
#
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
324
|
+
# For tags, we need full history. For branches, shallow clone is possible but
|
|
325
|
+
# we use full clone to ensure compatibility with all cases
|
|
326
|
+
# Use subprocess to ensure environment variables are properly passed
|
|
327
|
+
cmd = ["git", "-c", "credential.helper=", "-c", "credential.helper=!", "clone", git_url, target_dir]
|
|
328
|
+
result = subprocess.run(cmd, env=env, capture_output=True, text=True, timeout=600, stdin=subprocess.DEVNULL)
|
|
329
|
+
if result.returncode == 0:
|
|
330
|
+
# Checkout the specific branch or tag
|
|
331
|
+
checkout_cmd = ["git", "-C", target_dir, "checkout", refs_to_checkout]
|
|
332
|
+
checkout_result = subprocess.run(
|
|
333
|
+
checkout_cmd, env=env, capture_output=True, text=True,
|
|
334
|
+
timeout=60, stdin=subprocess.DEVNULL)
|
|
335
|
+
if checkout_result.returncode == 0:
|
|
336
|
+
if any(Path(target_dir).iterdir()):
|
|
337
|
+
success = True
|
|
338
|
+
oss_version = refs_to_checkout
|
|
339
|
+
logger.info(f"Files found in {target_dir} after clone and checkout.")
|
|
340
|
+
else:
|
|
341
|
+
logger.info(f"No files found in {target_dir} after clone.")
|
|
342
|
+
success = False
|
|
343
|
+
else:
|
|
344
|
+
logger.info(f"Git checkout error: {checkout_result.stderr}")
|
|
345
|
+
# Clone succeeded but checkout failed (e.g. non-existent ref):
|
|
346
|
+
# repo has default branch; treat as success with empty version
|
|
347
|
+
if any(Path(target_dir).iterdir()):
|
|
348
|
+
success = True
|
|
349
|
+
oss_version = ""
|
|
350
|
+
logger.info("Checkout failed; keeping default branch.")
|
|
304
351
|
else:
|
|
305
|
-
logger.info(f"
|
|
352
|
+
logger.info(f"Git clone error: {result.stderr}")
|
|
306
353
|
success = False
|
|
307
|
-
except
|
|
308
|
-
logger.info(
|
|
354
|
+
except subprocess.TimeoutExpired:
|
|
355
|
+
logger.info("Git clone timeout")
|
|
309
356
|
success = False
|
|
310
357
|
except Exception as e:
|
|
311
|
-
logger.info(f"
|
|
358
|
+
logger.info(f"Git clone error:{e}")
|
|
312
359
|
success = False
|
|
313
360
|
|
|
314
361
|
if not success:
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
362
|
+
try:
|
|
363
|
+
# Use subprocess to ensure environment variables are properly passed
|
|
364
|
+
# No checkout needed, so shallow clone is sufficient
|
|
365
|
+
cmd = [
|
|
366
|
+
"git", "-c", "credential.helper=", "-c", "credential.helper=!",
|
|
367
|
+
"clone", "--depth", "1", git_url, target_dir
|
|
368
|
+
]
|
|
369
|
+
result = subprocess.run(cmd, env=env, capture_output=True, text=True, timeout=600, stdin=subprocess.DEVNULL)
|
|
370
|
+
if result.returncode == 0:
|
|
371
|
+
if any(Path(target_dir).iterdir()):
|
|
372
|
+
success = True
|
|
373
|
+
else:
|
|
374
|
+
logger.info(f"No files found in {target_dir} after clone.")
|
|
375
|
+
success = False
|
|
376
|
+
else:
|
|
377
|
+
logger.info(f"Git clone error: {result.stderr}")
|
|
378
|
+
success = False
|
|
379
|
+
except subprocess.TimeoutExpired:
|
|
380
|
+
logger.info("Git clone timeout")
|
|
381
|
+
success = False
|
|
382
|
+
except Exception as e:
|
|
383
|
+
logger.info(f"Git clone error:{e}")
|
|
320
384
|
success = False
|
|
321
385
|
return success, oss_version
|
|
322
386
|
|
fosslight_util/exclude.py
CHANGED
|
@@ -109,7 +109,13 @@ def get_excluded_paths(path_to_scan: str, custom_excluded_paths: list = [], cust
|
|
|
109
109
|
path_to_exclude_with_dot = []
|
|
110
110
|
excluded_files = set() # Use set for O(1) operations
|
|
111
111
|
abs_path_to_scan = os.path.abspath(path_to_scan)
|
|
112
|
-
|
|
112
|
+
# Normalize: backslash to slash; trailing /* -> / so directory matching works without special case
|
|
113
|
+
custom_excluded_normalized = []
|
|
114
|
+
for p in custom_excluded_paths:
|
|
115
|
+
p = p.replace('\\', '/')
|
|
116
|
+
if p.endswith('/*'):
|
|
117
|
+
p = p[:-2] + '/'
|
|
118
|
+
custom_excluded_normalized.append(p)
|
|
113
119
|
cnt_file_except_skipped = 0
|
|
114
120
|
|
|
115
121
|
for root, dirs, files in os.walk(path_to_scan):
|
|
@@ -124,6 +130,11 @@ def get_excluded_paths(path_to_scan: str, custom_excluded_paths: list = [], cust
|
|
|
124
130
|
path_to_exclude_with_dot.append(rel_path)
|
|
125
131
|
elif rel_path in custom_excluded_normalized or rel_path + '/' in custom_excluded_normalized:
|
|
126
132
|
path_to_exclude.append(rel_path)
|
|
133
|
+
elif any(
|
|
134
|
+
fnmatch.fnmatch(rel_path, pattern)
|
|
135
|
+
for pattern in custom_excluded_normalized
|
|
136
|
+
):
|
|
137
|
+
path_to_exclude.append(rel_path)
|
|
127
138
|
|
|
128
139
|
for file_name in files:
|
|
129
140
|
file_path = os.path.join(root, file_name)
|
|
@@ -132,9 +143,11 @@ def get_excluded_paths(path_to_scan: str, custom_excluded_paths: list = [], cust
|
|
|
132
143
|
except_info_sheet = False
|
|
133
144
|
if not _has_parent_in_exclude_list(rel_path, path_to_exclude):
|
|
134
145
|
file_ext = os.path.splitext(file_name)[1].lstrip('.').lower()
|
|
135
|
-
if
|
|
136
|
-
|
|
137
|
-
|
|
146
|
+
if any(
|
|
147
|
+
fnmatch.fnmatch(rel_path, pattern)
|
|
148
|
+
or fnmatch.fnmatch(file_name, pattern)
|
|
149
|
+
for pattern in custom_excluded_normalized
|
|
150
|
+
):
|
|
138
151
|
should_exclude = True
|
|
139
152
|
elif file_name.startswith('.'):
|
|
140
153
|
should_exclude = True
|
fosslight_util/help.py
CHANGED
|
@@ -55,23 +55,35 @@ _HELP_MESSAGE_COMMON = f"""
|
|
|
55
55
|
|
|
56
56
|
|
|
57
57
|
_HELP_MESSAGE_DOWNLOAD = """
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
58
|
+
📖 Usage
|
|
59
|
+
────────────────────────────────────────────────────────────────────
|
|
60
|
+
fosslight_download [options] <arguments>
|
|
61
|
+
|
|
62
|
+
📝 Description
|
|
63
|
+
────────────────────────────────────────────────────────────────────
|
|
64
|
+
FOSSLight Downloader is a tool to download a package or source code from a given URL.
|
|
65
|
+
|
|
66
|
+
⚙️ General Options
|
|
67
|
+
────────────────────────────────────────────────────────────────────
|
|
68
|
+
-s <url> URL of the package or source to download (required)
|
|
69
|
+
-t <path> Output directory to save the downloaded files
|
|
70
|
+
-d <log_dir> Directory to save the log file
|
|
71
|
+
-c <branch/tag> Checkout to branch, tag, or version after download
|
|
72
|
+
-z Unzip only compressed file
|
|
73
|
+
-o Generate summary output file
|
|
74
|
+
-h Show this help message
|
|
75
|
+
|
|
76
|
+
💡 Examples
|
|
77
|
+
────────────────────────────────────────────────────────────────────
|
|
78
|
+
# Download a GitHub repository to output_dir and save log
|
|
79
|
+
fosslight_download -s https://github.com/fosslight/fosslight -t output_dir -d log_dir
|
|
80
|
+
|
|
81
|
+
# Download and checkout to a specific branch
|
|
82
|
+
fosslight_download -s https://github.com/fosslight/fosslight -t output_dir -c develop
|
|
83
|
+
|
|
84
|
+
# Download and unzip a compressed file
|
|
85
|
+
fosslight_download -s https://example.com/archive.zip -z -t output_dir
|
|
86
|
+
"""
|
|
75
87
|
|
|
76
88
|
|
|
77
89
|
class PrintHelpMsg():
|
fosslight_util/write_excel.py
CHANGED
|
@@ -9,7 +9,7 @@ import logging
|
|
|
9
9
|
import os
|
|
10
10
|
import pandas as pd
|
|
11
11
|
from pathlib import Path
|
|
12
|
-
from fosslight_util.constant import LOGGER_NAME, SHEET_NAME_FOR_SCANNER, FOSSLIGHT_BINARY
|
|
12
|
+
from fosslight_util.constant import LOGGER_NAME, SHEET_NAME_FOR_SCANNER, FOSSLIGHT_BINARY, FOSSLIGHT_DEPENDENCY, FOSSLIGHT_SOURCE
|
|
13
13
|
from jsonmerge import merge
|
|
14
14
|
|
|
15
15
|
_HEADER = {'BIN (': ['ID', 'Binary Path', 'Source Code Path',
|
|
@@ -121,7 +121,12 @@ def write_result_to_excel(out_file_name, scan_item, extended_header={}, hide_hea
|
|
|
121
121
|
workbook = xlsxwriter.Workbook(out_file_name)
|
|
122
122
|
write_cover_sheet(workbook, scan_item.cover)
|
|
123
123
|
if scan_item.file_items and len(scan_item.file_items.keys()) > 0:
|
|
124
|
-
|
|
124
|
+
sheet_order = [FOSSLIGHT_DEPENDENCY, FOSSLIGHT_SOURCE, FOSSLIGHT_BINARY]
|
|
125
|
+
all_scanners = list(scan_item.file_items.keys())
|
|
126
|
+
priority = {name.lower(): idx for idx, name in enumerate(sheet_order)}
|
|
127
|
+
sorted_scanner_names = sorted(all_scanners,
|
|
128
|
+
key=lambda x: priority.get(x.lower(), len(priority)))
|
|
129
|
+
for scanner_name in sorted_scanner_names:
|
|
125
130
|
sheet_name = ""
|
|
126
131
|
if scanner_name.lower() in SHEET_NAME_FOR_SCANNER:
|
|
127
132
|
sheet_name = SHEET_NAME_FOR_SCANNER[scanner_name.lower()]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: fosslight_util
|
|
3
|
-
Version: 2.1.
|
|
3
|
+
Version: 2.1.40
|
|
4
4
|
Summary: FOSSLight Util
|
|
5
5
|
Home-page: https://github.com/fosslight/fosslight_util
|
|
6
6
|
Download-URL: https://github.com/fosslight/fosslight_util
|
|
@@ -22,7 +22,7 @@ Requires-Dist: lastversion
|
|
|
22
22
|
Requires-Dist: coloredlogs
|
|
23
23
|
Requires-Dist: beautifulsoup4
|
|
24
24
|
Requires-Dist: jsonmerge
|
|
25
|
-
Requires-Dist: spdx-tools==0.8
|
|
25
|
+
Requires-Dist: spdx-tools==0.8.2; sys_platform == "linux"
|
|
26
26
|
Requires-Dist: setuptools>=65.5.1
|
|
27
27
|
Requires-Dist: numpy
|
|
28
28
|
Requires-Dist: requests
|
|
@@ -4,10 +4,10 @@ fosslight_util/compare_yaml.py,sha256=eLqqCLgERxRHN5vsnpQVMXIEU862Lx66mD_y4uMgQE
|
|
|
4
4
|
fosslight_util/constant.py,sha256=3BzJtyxC0o5IFAhYaUW-DeTKkA6f5tDJFJTb0k5ji9Y,2418
|
|
5
5
|
fosslight_util/correct.py,sha256=1WEAL-9_KhjFPLucPhv0PNN3K7avm0z8mU6sTuSyeHM,3864
|
|
6
6
|
fosslight_util/cover.py,sha256=yrWwguN5VM7mOllljiDVykPfuLYfI11kcJ6gEs49Bjo,2616
|
|
7
|
-
fosslight_util/download.py,sha256=
|
|
8
|
-
fosslight_util/exclude.py,sha256=
|
|
7
|
+
fosslight_util/download.py,sha256=8um4tTn7j4nBqa7iET4aI6n5r0FCimpN3ko6MhYlxTY,26796
|
|
8
|
+
fosslight_util/exclude.py,sha256=ojQa9xzPla5_S184GTcKdrrk-jWE-KKn4eBQcEA_Huo,7336
|
|
9
9
|
fosslight_util/get_pom_license.py,sha256=vmh2LG1_4U7ts9SSpN3_UAANWbx5GBAVjremwm62OFY,5639
|
|
10
|
-
fosslight_util/help.py,sha256=
|
|
10
|
+
fosslight_util/help.py,sha256=tOKrQz1thNDMfl9nZYGSHJ8gkPjLKBwgGI44AD3kUyI,6143
|
|
11
11
|
fosslight_util/oss_item.py,sha256=8890JHb5ZoKQWAwN7Fl8badnlYatJtF4MVJz1rdS4yQ,6938
|
|
12
12
|
fosslight_util/output_format.py,sha256=BP23LspxawDZ_a99oWLVKWUQ-G7P5uoUpjEXhkRFKwc,8801
|
|
13
13
|
fosslight_util/parsing_yaml.py,sha256=2zx_N5lMkXT1dRmfJMpzlrru-y_2F_CkVbGlba6vQpU,5380
|
|
@@ -16,7 +16,7 @@ fosslight_util/set_log.py,sha256=AbcLFLvY9GSOYSN0a110wO5gNcyc8KKnNjl7GxHEW9A,400
|
|
|
16
16
|
fosslight_util/spdx_licenses.py,sha256=GvMNe_D4v2meapTVwPu2BJXInnTo3_gIzg669eJhUu0,3691
|
|
17
17
|
fosslight_util/timer_thread.py,sha256=5VbZENQPD-N0NUmzEktqGr6Am-e7vxD79K05mmr29g0,433
|
|
18
18
|
fosslight_util/write_cyclonedx.py,sha256=hq817j-0OM89B8jtZKgHgvVa0YEaYHlz_8R5vNpe21I,9662
|
|
19
|
-
fosslight_util/write_excel.py,sha256=
|
|
19
|
+
fosslight_util/write_excel.py,sha256=lgN1BYXwYRC9qJxsHbvhBrzPfdLPNRt1CZKi4LEF0gQ,10575
|
|
20
20
|
fosslight_util/write_opossum.py,sha256=ltmo6SkugKWdAYupeCqwE4-3lua0GwLpix1XqFC-tT8,11678
|
|
21
21
|
fosslight_util/write_scancodejson.py,sha256=dMCjTtUnNR5BCL6gBCleDT8bTSAN5Gg2RAfimmkGXUE,2692
|
|
22
22
|
fosslight_util/write_spdx.py,sha256=Ov9jBlfVrkWIymcfAxbupUxDZKfCOZZGOPZ4v-x230M,12108
|
|
@@ -25,9 +25,9 @@ fosslight_util/write_yaml.py,sha256=QlEKoIPQsEaYERfbP53TeKgnllYzhLQWm5wYjnWtVjE,
|
|
|
25
25
|
fosslight_util/resources/frequentLicenselist.json,sha256=GUhzK6tu7ok10fekOnmVmUgIGRC-acGABZKTNKfDyYA,4776157
|
|
26
26
|
fosslight_util/resources/frequent_license_nick_list.json,sha256=ryU2C_6ZxHbz90_sUN9OvI9GXkCMLu7oGcmd9W79YYo,5005
|
|
27
27
|
fosslight_util/resources/licenses.json,sha256=mK55z-bhY7Mjpj2KsO1crKGGL-X3F6MBFQJ0zLlx010,240843
|
|
28
|
-
fosslight_util-2.1.
|
|
29
|
-
fosslight_util-2.1.
|
|
30
|
-
fosslight_util-2.1.
|
|
31
|
-
fosslight_util-2.1.
|
|
32
|
-
fosslight_util-2.1.
|
|
33
|
-
fosslight_util-2.1.
|
|
28
|
+
fosslight_util-2.1.40.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
|
29
|
+
fosslight_util-2.1.40.dist-info/METADATA,sha256=59BAUojlZ3JoIUQVaAIHplVJ-qaQHNkLQx6pb3GdCgA,6365
|
|
30
|
+
fosslight_util-2.1.40.dist-info/WHEEL,sha256=SmOxYU7pzNKBqASvQJ7DjX3XGUF92lrGhMb3R6_iiqI,91
|
|
31
|
+
fosslight_util-2.1.40.dist-info/entry_points.txt,sha256=0yZggRWNwDaClDG8UmUA10UFG8cVX3Jiy5gG9nW7hJs,68
|
|
32
|
+
fosslight_util-2.1.40.dist-info/top_level.txt,sha256=2qyYWGLakgBRy4BqoBNt-I5C29tBr_e93e5e1pbuTGA,15
|
|
33
|
+
fosslight_util-2.1.40.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|