cycode 3.24.1.dev2__py3-none-any.whl → 3.24.1.dev3__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.
cycode/__init__.py CHANGED
@@ -5,4 +5,4 @@ import time as _time
5
5
  # end-to-end scan duration from the moment the user actually triggered it.
6
6
  _BOOT_WALL: float = _time.time()
7
7
 
8
- __version__ = '3.24.1.dev2' # DON'T TOUCH. Placeholder. Will be filled automatically on poetry build from Git Tag
8
+ __version__ = '3.24.1.dev3' # DON'T TOUCH. Placeholder. Will be filled automatically on poetry build from Git Tag
@@ -1,5 +1,6 @@
1
1
  import os
2
2
  import time
3
+ import zipfile
3
4
  from platform import platform
4
5
  from typing import TYPE_CHECKING, Callable, Optional
5
6
 
@@ -23,6 +24,7 @@ from cycode.cli.files_collector.path_documents import get_relevant_documents
23
24
  from cycode.cli.files_collector.sca.sca_file_collector import add_sca_dependencies_tree_documents_if_needed
24
25
  from cycode.cli.files_collector.zip_documents import zip_documents
25
26
  from cycode.cli.models import CliError, Document, LocalScanResult
27
+ from cycode.cli.utils.host_info import is_64bit
26
28
  from cycode.cli.utils.path_utils import get_absolute_path, get_path_by_os
27
29
  from cycode.cli.utils.progress_bar import ScanProgressBarSection
28
30
  from cycode.cli.utils.scan_batch import run_parallel_batched_scan
@@ -145,6 +147,7 @@ def _get_scan_documents_thread_func(
145
147
  is_git_diff: bool,
146
148
  is_commit_range: bool,
147
149
  scan_parameters: dict,
150
+ prezipped: Optional['InMemoryZip'] = None,
148
151
  ) -> Callable[[list[Document]], tuple[str, CliError, LocalScanResult]]:
149
152
  cycode_client = ctx.obj['client']
150
153
  scan_type = ctx.obj['scan_type']
@@ -164,9 +167,14 @@ def _get_scan_documents_thread_func(
164
167
 
165
168
  should_use_sync_flow = _should_use_sync_flow(command_scan_type, scan_type, sync_option)
166
169
 
170
+ # the single ZIP flow already built the archive to check that it fits; don't build it twice
171
+ zipped_documents = prezipped
172
+
167
173
  try:
168
- logger.debug('Preparing local files, %s', {'batch_files_count': len(batch)})
169
- zipped_documents = zip_documents(scan_type, batch)
174
+ if zipped_documents is None:
175
+ logger.debug('Preparing local files, %s', {'batch_files_count': len(batch)})
176
+ zipped_documents = zip_documents(scan_type, batch)
177
+
170
178
  zip_file_size = zipped_documents.size
171
179
  scan_result = _perform_scan(
172
180
  cycode_client,
@@ -189,6 +197,9 @@ def _get_scan_documents_thread_func(
189
197
  except Exception as e:
190
198
  error = handle_scan_exception(ctx, e, return_exception=True)
191
199
  error_message = str(e)
200
+ finally:
201
+ if zipped_documents is not None:
202
+ zipped_documents.cleanup()
192
203
 
193
204
  if local_scan_result:
194
205
  detections_count = local_scan_result.detections_count
@@ -225,34 +236,77 @@ def _get_scan_documents_thread_func(
225
236
  return _scan_batch_thread_func
226
237
 
227
238
 
239
+ def _log_selected_upload_mode(mode: str, reason: str, documents_count: int) -> None:
240
+ logger.debug(
241
+ 'Selected upload mode, %s',
242
+ {
243
+ 'mode': mode,
244
+ 'reason': reason,
245
+ 'documents_count': documents_count,
246
+ 'max_files_count': consts.ZIP_MAX_FILES_COUNT,
247
+ 'zip64_enabled': is_64bit(),
248
+ },
249
+ )
250
+
251
+
252
+ def _exceeds_non_zip64_files_count(documents_to_scan: list[Document]) -> bool:
253
+ """Whether a single ZIP can't hold all the documents because ZIP64 is unavailable.
254
+
255
+ Without ZIP64 (32-bit interpreter) the archive is capped at 65,535 entries.
256
+ """
257
+ return not is_64bit() and len(documents_to_scan) > consts.ZIP_MAX_FILES_COUNT
258
+
259
+
228
260
  def _run_presigned_upload_scan(
229
- scan_batch_thread_func: Callable,
230
- scan_type: str,
261
+ ctx: typer.Context,
262
+ is_git_diff: bool,
263
+ is_commit_range: bool,
264
+ scan_parameters: dict,
231
265
  documents_to_scan: list[Document],
232
266
  progress_bar: 'BaseProgressBar',
233
267
  printer: 'ConsolePrinter',
234
268
  ) -> tuple:
235
- try:
236
- # Try to zip all documents as a single batch; ZipTooLargeError raised if it exceeds the scan type's limit
237
- zip_documents(scan_type, documents_to_scan)
238
- # It fits: skip batching and upload everything as one ZIP
269
+ scan_type = ctx.obj['scan_type']
270
+ documents_count = len(documents_to_scan)
271
+
272
+ def run_batched() -> tuple:
239
273
  return run_parallel_batched_scan(
240
- scan_batch_thread_func,
274
+ _get_scan_documents_thread_func(ctx, is_git_diff, is_commit_range, scan_parameters),
241
275
  scan_type,
242
276
  documents_to_scan,
243
277
  progress_bar=progress_bar,
244
- skip_batching=True,
245
278
  )
246
- except custom_exceptions.ZipTooLargeError:
279
+
280
+ if _exceeds_non_zip64_files_count(documents_to_scan):
281
+ # Don't waste time zipping documents we already know won't fit into a single ZIP
282
+ _log_selected_upload_mode('batched', 'files_count_exceeds_non_zip64_limit', documents_count)
283
+ return run_batched()
284
+
285
+ zipped_documents = None
286
+ try:
287
+ # Try to zip all documents as a single batch; ZipTooLargeError raised if it exceeds the scan type's limit
288
+ zipped_documents = zip_documents(scan_type, documents_to_scan)
289
+ except (custom_exceptions.ZipTooLargeError, zipfile.LargeZipFile):
290
+ # LargeZipFile is a safety net: the files count pre-check above should have caught it already
291
+ _log_selected_upload_mode('batched', 'zip_too_large', documents_count)
292
+ if zipped_documents is not None:
293
+ zipped_documents.cleanup()
294
+
247
295
  printer.print_warning(
248
296
  'The scan is too large to upload as a single file. This may result in corrupted scan results.'
249
297
  )
250
- return run_parallel_batched_scan(
251
- scan_batch_thread_func,
252
- scan_type,
253
- documents_to_scan,
254
- progress_bar=progress_bar,
255
- )
298
+ return run_batched()
299
+
300
+ # It fits: skip batching and upload everything as one ZIP. The archive we just built is the one
301
+ # that gets uploaded, so the scan doesn't pay for compressing every document twice
302
+ _log_selected_upload_mode('single_zip', 'fits_single_zip', documents_count)
303
+ return run_parallel_batched_scan(
304
+ _get_scan_documents_thread_func(ctx, is_git_diff, is_commit_range, scan_parameters, zipped_documents),
305
+ scan_type,
306
+ documents_to_scan,
307
+ progress_bar=progress_bar,
308
+ skip_batching=True,
309
+ )
256
310
 
257
311
 
258
312
  def scan_documents(
@@ -277,18 +331,19 @@ def scan_documents(
277
331
  )
278
332
  return
279
333
 
280
- scan_batch_thread_func = _get_scan_documents_thread_func(ctx, is_git_diff, is_commit_range, scan_parameters)
281
-
282
334
  # Presigned single-file upload is async-only; a --sync scan must stay on the batched inline path
283
335
  # so it never builds one oversized zip to POST synchronously.
284
336
  should_use_sync_flow = _should_use_sync_flow(ctx.info_name, scan_type, ctx.obj['sync'])
285
337
  if should_use_presigned_upload(scan_type) and not should_use_sync_flow:
286
338
  errors, local_scan_results = _run_presigned_upload_scan(
287
- scan_batch_thread_func, scan_type, documents_to_scan, progress_bar, printer
339
+ ctx, is_git_diff, is_commit_range, scan_parameters, documents_to_scan, progress_bar, printer
288
340
  )
289
341
  else:
290
342
  errors, local_scan_results = run_parallel_batched_scan(
291
- scan_batch_thread_func, scan_type, documents_to_scan, progress_bar=progress_bar
343
+ _get_scan_documents_thread_func(ctx, is_git_diff, is_commit_range, scan_parameters),
344
+ scan_type,
345
+ documents_to_scan,
346
+ progress_bar=progress_bar,
292
347
  )
293
348
 
294
349
  try_set_aggregation_report_url_if_needed(ctx, scan_parameters, ctx.obj['client'], scan_type)
@@ -214,6 +214,9 @@ def _scan_commit_range_documents(
214
214
 
215
215
  zip_file_size = from_commit_zipped_documents.size + to_commit_zipped_documents.size
216
216
 
217
+ from_commit_zipped_documents.cleanup()
218
+ to_commit_zipped_documents.cleanup()
219
+
217
220
  detections_count = relevant_detections_count = 0
218
221
  if local_scan_result:
219
222
  detections_count = local_scan_result.detections_count
cycode/cli/consts.py CHANGED
@@ -227,6 +227,12 @@ FILE_MAX_SIZE_LIMIT_IN_BYTES = 5000000
227
227
  PRESIGNED_LINK_UPLOADED_ZIP_MAX_SIZE_LIMIT_IN_BYTES = 5 * 1024 * 1024 * 1024 # 5 GB (S3 presigned POST limit)
228
228
  PRESIGNED_UPLOAD_SCAN_TYPES = {SAST_SCAN_TYPE, SECRET_SCAN_TYPE}
229
229
 
230
+ # the non-ZIP64 central directory stores the entry count in 16 bits; ZIP64 (64-bit interpreters) lifts it
231
+ ZIP_MAX_FILES_COUNT = 65_535
232
+
233
+ # the ZIP is built in memory up to this size, and spilled to a temp file beyond it
234
+ ZIP_SPOOL_MAX_SIZE_IN_BYTES = 64 * 1024 * 1024
235
+
230
236
  DEFAULT_ZIP_MAX_SIZE_LIMIT_IN_BYTES = 20 * 1024 * 1024
231
237
  ZIP_MAX_SIZE_LIMIT_IN_BYTES = {
232
238
  SCA_SCAN_TYPE: 200 * 1024 * 1024,
@@ -1,3 +1,4 @@
1
+ import zipfile
1
2
  from typing import Optional
2
3
 
3
4
  import typer
@@ -26,6 +27,13 @@ def handle_scan_exception(ctx: typer.Context, err: Exception, *, return_exceptio
26
27
  'Please try ignoring irrelevant paths using the `cycode ignore --by-path` command '
27
28
  'and execute the scan again',
28
29
  ),
30
+ zipfile.LargeZipFile: CliError(
31
+ soft_fail=True,
32
+ code='zip_too_large_error',
33
+ message='The path you attempted to scan contains too many files to pack into a single archive. '
34
+ 'Scanning such paths requires a 64-bit Python interpreter. '
35
+ 'Please try ignoring irrelevant paths using a .cycodeignore file and execute the scan again',
36
+ ),
29
37
  custom_exceptions.FileCollectionError: CliError(
30
38
  soft_fail=False,
31
39
  code='file_collection_error',
@@ -1,20 +1,48 @@
1
+ import shutil
2
+ import tempfile
1
3
  from collections import defaultdict
2
- from io import BytesIO
4
+ from os import SEEK_END
3
5
  from pathlib import Path
4
- from sys import getsizeof
5
- from typing import Optional
6
+ from typing import IO, Optional
6
7
  from zipfile import ZIP_DEFLATED, ZipFile
7
8
 
9
+ from cycode.cli import consts
8
10
  from cycode.cli.user_settings.configuration_manager import ConfigurationManager
11
+ from cycode.cli.utils.host_info import is_64bit
9
12
  from cycode.cli.utils.path_utils import concat_unique_id
13
+ from cycode.logger import get_logger
14
+
15
+ logger = get_logger('ZIP')
16
+
17
+ _SPOOL_DIRECTORY_NAME = 'tmp'
18
+
19
+
20
+ def _get_spool_directory(configuration_manager: ConfigurationManager) -> Optional[str]:
21
+ """Directory to spill big ZIPs into. None falls back to the system temp directory."""
22
+ try:
23
+ directory = Path(configuration_manager.global_config_file_manager.get_config_directory_path())
24
+ spool_directory = directory / _SPOOL_DIRECTORY_NAME
25
+ spool_directory.mkdir(parents=True, exist_ok=True)
26
+ return str(spool_directory)
27
+ except OSError as e:
28
+ logger.debug('Failed to create the spool directory; falling back to the system one', exc_info=e)
29
+ return None
10
30
 
11
31
 
12
32
  class InMemoryZip:
13
33
  def __init__(self) -> None:
14
34
  self.configuration_manager = ConfigurationManager()
15
35
 
16
- self.in_memory_zip = BytesIO()
17
- self.zip = ZipFile(self.in_memory_zip, mode='a', compression=ZIP_DEFLATED, allowZip64=False)
36
+ self._spool_max_size = consts.ZIP_SPOOL_MAX_SIZE_IN_BYTES
37
+ self._buffer = tempfile.SpooledTemporaryFile( # noqa: SIM115 # closed by cleanup(), lives past close()
38
+ max_size=self._spool_max_size,
39
+ dir=_get_spool_directory(self.configuration_manager),
40
+ )
41
+
42
+ # ZIP64 lifts the 65,535 entries and 4 GiB caps of the original ZIP format.
43
+ # It requires 64-bit offsets, so we only enable it on a 64-bit interpreter.
44
+ self._allow_zip64 = is_64bit()
45
+ self.zip = ZipFile(self._buffer, mode='a', compression=ZIP_DEFLATED, allowZip64=self._allow_zip64)
18
46
 
19
47
  self._files_count = 0
20
48
  self._extension_statistics = defaultdict(int)
@@ -35,17 +63,54 @@ class InMemoryZip:
35
63
  def close(self) -> None:
36
64
  self.zip.close()
37
65
 
66
+ def cleanup(self) -> None:
67
+ """Release the buffer, deleting the spilled temp file if there is one."""
68
+ self._buffer.close()
69
+
70
+ def __enter__(self) -> 'InMemoryZip': # noqa: PYI034 # typing.Self needs Python 3.11
71
+ return self
72
+
73
+ def __exit__(self, *_: object) -> None:
74
+ self.cleanup()
75
+
76
+ def stream(self) -> IO[bytes]:
77
+ """The whole archive as a file object, rewound. Doesn't copy it into memory.
78
+
79
+ Note: before Python 3.11 SpooledTemporaryFile isn't a real IOBase, so the returned object
80
+ has no seekable()/readable()/writable(). read/seek/tell work on every supported version.
81
+ """
82
+ self._buffer.seek(0)
83
+ return self._buffer
84
+
38
85
  def read(self) -> bytes:
39
- self.in_memory_zip.seek(0)
40
- return self.in_memory_zip.read()
86
+ self._buffer.seek(0)
87
+ return self._buffer.read()
41
88
 
42
89
  def write_on_disk(self, path: 'Path') -> None:
43
90
  with open(path, 'wb') as f:
44
- f.write(self.read())
91
+ shutil.copyfileobj(self.stream(), f)
45
92
 
46
93
  @property
47
94
  def size(self) -> int:
48
- return getsizeof(self.in_memory_zip)
95
+ position = self._buffer.tell()
96
+ try:
97
+ self._buffer.seek(0, SEEK_END)
98
+ return self._buffer.tell()
99
+ finally:
100
+ self._buffer.seek(position)
101
+
102
+ @property
103
+ def is_rolled_over(self) -> bool:
104
+ """Whether the archive outgrew the threshold and moved from memory to the disk.
105
+
106
+ SpooledTemporaryFile spills on the write that crosses max_size, and the archive only grows,
107
+ so the size says it without reaching into the private _rolled flag.
108
+ """
109
+ return self.size > self._spool_max_size
110
+
111
+ @property
112
+ def allow_zip64(self) -> bool:
113
+ return self._allow_zip64
49
114
 
50
115
  @property
51
116
  def files_count(self) -> int:
@@ -49,6 +49,11 @@ def _read_text_file(path: str) -> Optional[str]:
49
49
  return None
50
50
 
51
51
 
52
+ def is_64bit() -> bool:
53
+ """Whether the running Python interpreter is 64-bit (not the OS)."""
54
+ return sys.maxsize > 2**32
55
+
56
+
52
57
  def get_hostname() -> Optional[str]:
53
58
  try:
54
59
  return socket.gethostname() or None
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cycode
3
- Version: 3.24.1.dev2
3
+ Version: 3.24.1.dev3
4
4
  Summary: Boost security in your dev lifecycle via SAST, SCA, Secrets & IaC scanning.
5
5
  License-Expression: MIT
6
6
  License-File: LICENCE
@@ -1,4 +1,4 @@
1
- cycode/__init__.py,sha256=TGnaJP0fWShd83OGAGzngPbjXG-1A9ACQThCYV9aIOc,396
1
+ cycode/__init__.py,sha256=xN7LgjtKq-0qdFl0zVHMknIPgyr202mSalE6jyAUwGk,396
2
2
  cycode/__main__.py,sha256=Z3bD5yrA7yPvAChcADQrqCaZd0ChGI1gdiwALwbWJ6U,104
3
3
  cycode/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
4
  cycode/cli/app.py,sha256=AlR2durAEbsa47PDfIj7JtMvJDWA_Dq6wPtVuMJYSCs,10250
@@ -68,10 +68,10 @@ cycode/cli/apps/report_import/sbom/sbom_command.py,sha256=uWvBhVdROHcHsjoR3l44h3
68
68
  cycode/cli/apps/sca_options.py,sha256=-3iXoJV5qOkfjr-WGIWuAgaeNYeItJIbm2n6O2Kg5D8,1666
69
69
  cycode/cli/apps/scan/__init__.py,sha256=-q1AIBnrQ4GP0CVKFLr_2CdWf9TBQC90ejSL4I7rxuA,2444
70
70
  cycode/cli/apps/scan/aggregation_report.py,sha256=8f9kPfO7biNf5OsDZG6UhMPqG6ymoFrX5GBtlEIfFAg,1540
71
- cycode/cli/apps/scan/code_scanner.py,sha256=e5jAsDp99VyeSoiLLIkm7P3HOYOInaTq8qZ-OytsO3w,17513
71
+ cycode/cli/apps/scan/code_scanner.py,sha256=kCCt08MHye3UIJo1cgSz2uP3E-6EZfAwsR7mNU6S_8g,19741
72
72
  cycode/cli/apps/scan/commit_history/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
73
73
  cycode/cli/apps/scan/commit_history/commit_history_command.py,sha256=zTVmN8yeLXGAiCbyDL-EyEzSPNLzcRpP2q6Qq7p4uZA,1011
74
- cycode/cli/apps/scan/commit_range_scanner.py,sha256=OB7mmgRrEptvXxwyTeyfTWzq2iFry3-uTVZPIbbs13w,17283
74
+ cycode/cli/apps/scan/commit_range_scanner.py,sha256=kUth9ksOHmoarseE8EhAzVCycs0Tqz2g1E6WGKhMCtE,17368
75
75
  cycode/cli/apps/scan/detection_excluder.py,sha256=0zaNa1PxVshATHv8axp4e-xWvmuNQdg_r5DYsdQ9EVo,6432
76
76
  cycode/cli/apps/scan/path/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
77
77
  cycode/cli/apps/scan/path/path_command.py,sha256=x4HXqq1Wy6onziKMc6ELQxqeI5k-m3t_T3RG9kQxrq0,591
@@ -98,14 +98,14 @@ cycode/cli/apps/status/version_command.py,sha256=c6Iko_rmZo9T_kQSd3HUloBi40Qv7cj
98
98
  cycode/cli/cli_types.py,sha256=Xqf2eSx3yUvFoQG29ObUZ3QLVBhtZ4mkqxf_cJXpntU,3406
99
99
  cycode/cli/config.py,sha256=Op-lX_neanJtvPvoOEx4ByBdveh5ygElIga1FdSHhOI,299
100
100
  cycode/cli/console.py,sha256=vp-DHwlkwpwdsPyfwGdjsPF-6-Bi3f8W7G-W_YXCMH8,1914
101
- cycode/cli/consts.py,sha256=bSP2N_deQnRgFMik6rQkYzyenezdZjFBB-5DDX_q6ZA,10001
101
+ cycode/cli/consts.py,sha256=7RXx2ezNO7Ss_tEBcNsjklYt0esldiqM0iKhgIFrDt8,10268
102
102
  cycode/cli/exceptions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
103
103
  cycode/cli/exceptions/custom_exceptions.py,sha256=SImny5zXhnKocTw6GDaTm9x4I3bWRZW4wZEXg2Q-NTI,4742
104
104
  cycode/cli/exceptions/handle_ai_remediation_errors.py,sha256=mA70upSYXK3rL_fmanzKYeUzLENhpXdkW8k3aIHrKzU,785
105
105
  cycode/cli/exceptions/handle_auth_errors.py,sha256=m3q9keRUKAg6OnFlOlzpNUFzdQHGEeyq8N2Ywqs-QQ4,597
106
106
  cycode/cli/exceptions/handle_errors.py,sha256=za3vQcM_eFTvbT-53tTc6ky-J0wav6lupD1hXWw0e54,881
107
107
  cycode/cli/exceptions/handle_report_sbom_errors.py,sha256=bi0EizHtQLL-ovhHRH98CZ7qXdDPLTYnI59Jn1Y5c0E,926
108
- cycode/cli/exceptions/handle_scan_errors.py,sha256=1KkBFb7LniflYRr0vMl1FPIZDALPZu1LiXhORGl0jhs,2195
108
+ cycode/cli/exceptions/handle_scan_errors.py,sha256=po91RQgRi0beQChSrjuiV2DXVARb-NOqzpVDhbvRKmw,2617
109
109
  cycode/cli/files_collector/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
110
110
  cycode/cli/files_collector/commit_range_documents.py,sha256=Bvv9MJBoiraXI396A46412x9zgusjPS3g3nWdSFprPE,21095
111
111
  cycode/cli/files_collector/documents_walk_ignore.py,sha256=G4e-3vfP4WZ7wa9-VbZ66xCKCioTXnPBfbrs4_hh8xY,4705
@@ -113,7 +113,7 @@ cycode/cli/files_collector/file_excluder.py,sha256=atua_L2qDbmhFXj4nB6rDqSn5--Mu
113
113
  cycode/cli/files_collector/iac/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
114
114
  cycode/cli/files_collector/iac/tf_content_generator.py,sha256=a65zA0Ejv_LSA5jac2omHck4IKoNS5MX6v6ltF2wo4E,2873
115
115
  cycode/cli/files_collector/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
116
- cycode/cli/files_collector/models/in_memory_zip.py,sha256=a56bTdOgg7E3PpWRh0ixVX8laY_3ifWilPZoQRMNFYs,1838
116
+ cycode/cli/files_collector/models/in_memory_zip.py,sha256=jYLb8P2tcHWyvnDjDdREIpDXUTZxvgFdEZoB77RnXss,4411
117
117
  cycode/cli/files_collector/path_documents.py,sha256=7oNLcFZFHC_3sO34iD9FaKdS6_0lCogAl-nh11ejT_w,5040
118
118
  cycode/cli/files_collector/repository_documents.py,sha256=53QQsfCzXXSV6F3EcInaN8G6aCwEVzceWiYwasG8CgM,860
119
119
  cycode/cli/files_collector/sca/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -180,7 +180,7 @@ cycode/cli/utils/binary_utils.py,sha256=PxP-rVJ1lEiOam-DQ1XU68oWtfwup4sCFHXv54cf
180
180
  cycode/cli/utils/enum_utils.py,sha256=h_VTCfJ-0hnhwDsEznmx56rJrCb5FQ8u6PrI6p8MP3E,187
181
181
  cycode/cli/utils/get_api_client.py,sha256=wwHabfVCDbFjcIwOn5Raho8MEPiOAgkHlGUEfXKpl8U,3542
182
182
  cycode/cli/utils/git_proxy.py,sha256=FPHMBiyLFK9X9vKYpKySRKJH6Dc9Cb3nO241Q95dASE,2911
183
- cycode/cli/utils/host_info.py,sha256=ba3scmnOJQOtNpVT-rf2-FKb0ocGzpPUONsG-uxmhro,6249
183
+ cycode/cli/utils/host_info.py,sha256=Clln3qCJR00rw6HndD0bAIv329n_bOEx42TKW6FqXFQ,6379
184
184
  cycode/cli/utils/ignore_utils.py,sha256=cODqhnOHA2kRo8rMY0YcmcKkmXNPOC9UTCmFu62RRqE,15567
185
185
  cycode/cli/utils/jwt_utils.py,sha256=EGI-0CKhCGY8hIcZ9b9diq9hqtOUf8Ha8ukeVJIf974,818
186
186
  cycode/cli/utils/path_utils.py,sha256=zc48CSU7hxqjSgfH6h5M1B0kIcKW44BOJrUa_6z-mAo,4317
@@ -217,8 +217,8 @@ cycode/cyclient/report_client.py,sha256=Scq30NeJPzgXv0hPLO1U05AdE9i_2iu6cIrSKpEJ
217
217
  cycode/cyclient/scan_client.py,sha256=DqAZ7u6Z_cvw9A9RlLkAQUgLRwPCCAsUq5U9umt4F7Y,16955
218
218
  cycode/cyclient/scan_config_base.py,sha256=mXsPZGYCtp85rv5GIige40yQZXuRcEKUW-VQJ0vgFzk,1201
219
219
  cycode/logger.py,sha256=EfZGRK6VC5rE_LAjIcRrHFiQCueylCDXoG6bvGkrIME,2111
220
- cycode-3.24.1.dev2.dist-info/METADATA,sha256=AxXWfRpzaPJHwREMYa_RvGp_-JGo4iGbXkzEPbZBMGM,93687
221
- cycode-3.24.1.dev2.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
222
- cycode-3.24.1.dev2.dist-info/entry_points.txt,sha256=iDcVJM8ByLElVgvBgtYxDjw1kT7O8Mo0LcWZIT5L3Ig,45
223
- cycode-3.24.1.dev2.dist-info/licenses/LICENCE,sha256=2Wx4N6mD_4xB7-E3hPkZ3MPhpJy__k_I8MaCSO-PDRo,1068
224
- cycode-3.24.1.dev2.dist-info/RECORD,,
220
+ cycode-3.24.1.dev3.dist-info/METADATA,sha256=bM6WYXKcnPc1t1mUojDIV4fzk3XU4rHwaJA2UJPS2Wc,93687
221
+ cycode-3.24.1.dev3.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
222
+ cycode-3.24.1.dev3.dist-info/entry_points.txt,sha256=iDcVJM8ByLElVgvBgtYxDjw1kT7O8Mo0LcWZIT5L3Ig,45
223
+ cycode-3.24.1.dev3.dist-info/licenses/LICENCE,sha256=2Wx4N6mD_4xB7-E3hPkZ3MPhpJy__k_I8MaCSO-PDRo,1068
224
+ cycode-3.24.1.dev3.dist-info/RECORD,,