socketsecurity 2.0.56__tar.gz → 2.1.2__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 (80) hide show
  1. {socketsecurity-2.0.56 → socketsecurity-2.1.2}/PKG-INFO +8 -8
  2. {socketsecurity-2.0.56 → socketsecurity-2.1.2}/README.md +6 -6
  3. {socketsecurity-2.0.56 → socketsecurity-2.1.2}/pyproject.toml +2 -6
  4. {socketsecurity-2.0.56 → socketsecurity-2.1.2}/socketsecurity/__init__.py +1 -1
  5. {socketsecurity-2.0.56 → socketsecurity-2.1.2}/socketsecurity/core/__init__.py +88 -29
  6. {socketsecurity-2.0.56 → socketsecurity-2.1.2}/socketsecurity/core/socket_config.py +1 -2
  7. socketsecurity-2.0.56/socketsecurity/core/issues.py +0 -2101
  8. socketsecurity-2.0.56/socketsecurity/core/licenses.py +0 -21574
  9. {socketsecurity-2.0.56 → socketsecurity-2.1.2}/.github/CODEOWNERS +0 -0
  10. {socketsecurity-2.0.56 → socketsecurity-2.1.2}/.github/PULL_REQUEST_TEMPLATE/bug-fix.md +0 -0
  11. {socketsecurity-2.0.56 → socketsecurity-2.1.2}/.github/PULL_REQUEST_TEMPLATE/feature.md +0 -0
  12. {socketsecurity-2.0.56 → socketsecurity-2.1.2}/.github/PULL_REQUEST_TEMPLATE/improvement.md +0 -0
  13. {socketsecurity-2.0.56 → socketsecurity-2.1.2}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  14. {socketsecurity-2.0.56 → socketsecurity-2.1.2}/.github/workflows/docker-stable.yml +0 -0
  15. {socketsecurity-2.0.56 → socketsecurity-2.1.2}/.github/workflows/pr-preview.yml +0 -0
  16. {socketsecurity-2.0.56 → socketsecurity-2.1.2}/.github/workflows/release.yml +0 -0
  17. {socketsecurity-2.0.56 → socketsecurity-2.1.2}/.github/workflows/version-check.yml +0 -0
  18. {socketsecurity-2.0.56 → socketsecurity-2.1.2}/.gitignore +0 -0
  19. {socketsecurity-2.0.56 → socketsecurity-2.1.2}/.hooks/sync_version.py +0 -0
  20. {socketsecurity-2.0.56 → socketsecurity-2.1.2}/.pre-commit-config.yaml +0 -0
  21. {socketsecurity-2.0.56 → socketsecurity-2.1.2}/.python-version +0 -0
  22. {socketsecurity-2.0.56 → socketsecurity-2.1.2}/Dockerfile +0 -0
  23. {socketsecurity-2.0.56 → socketsecurity-2.1.2}/LICENSE +0 -0
  24. {socketsecurity-2.0.56 → socketsecurity-2.1.2}/Makefile +0 -0
  25. {socketsecurity-2.0.56 → socketsecurity-2.1.2}/Pipfile.lock +0 -0
  26. {socketsecurity-2.0.56 → socketsecurity-2.1.2}/docs/README.md +0 -0
  27. {socketsecurity-2.0.56 → socketsecurity-2.1.2}/pytest.ini +0 -0
  28. {socketsecurity-2.0.56 → socketsecurity-2.1.2}/requirements-dev.lock +0 -0
  29. {socketsecurity-2.0.56 → socketsecurity-2.1.2}/requirements.lock +0 -0
  30. {socketsecurity-2.0.56 → socketsecurity-2.1.2}/scripts/build_container.sh +0 -0
  31. {socketsecurity-2.0.56 → socketsecurity-2.1.2}/scripts/deploy-test-docker.sh +0 -0
  32. {socketsecurity-2.0.56 → socketsecurity-2.1.2}/scripts/deploy-test-pypi.sh +0 -0
  33. {socketsecurity-2.0.56 → socketsecurity-2.1.2}/scripts/run.sh +0 -0
  34. {socketsecurity-2.0.56 → socketsecurity-2.1.2}/socketsecurity/config.py +0 -0
  35. {socketsecurity-2.0.56 → socketsecurity-2.1.2}/socketsecurity/core/classes.py +0 -0
  36. {socketsecurity-2.0.56 → socketsecurity-2.1.2}/socketsecurity/core/cli_client.py +0 -0
  37. {socketsecurity-2.0.56 → socketsecurity-2.1.2}/socketsecurity/core/exceptions.py +0 -0
  38. {socketsecurity-2.0.56 → socketsecurity-2.1.2}/socketsecurity/core/git_interface.py +0 -0
  39. {socketsecurity-2.0.56 → socketsecurity-2.1.2}/socketsecurity/core/logging.py +0 -0
  40. {socketsecurity-2.0.56 → socketsecurity-2.1.2}/socketsecurity/core/messages.py +0 -0
  41. {socketsecurity-2.0.56 → socketsecurity-2.1.2}/socketsecurity/core/scm/__init__.py +0 -0
  42. {socketsecurity-2.0.56 → socketsecurity-2.1.2}/socketsecurity/core/scm/base.py +0 -0
  43. {socketsecurity-2.0.56 → socketsecurity-2.1.2}/socketsecurity/core/scm/client.py +0 -0
  44. {socketsecurity-2.0.56 → socketsecurity-2.1.2}/socketsecurity/core/scm/github.py +0 -0
  45. {socketsecurity-2.0.56 → socketsecurity-2.1.2}/socketsecurity/core/scm/gitlab.py +0 -0
  46. {socketsecurity-2.0.56 → socketsecurity-2.1.2}/socketsecurity/core/scm_comments.py +0 -0
  47. {socketsecurity-2.0.56 → socketsecurity-2.1.2}/socketsecurity/core/utils.py +0 -0
  48. {socketsecurity-2.0.56 → socketsecurity-2.1.2}/socketsecurity/output.py +0 -0
  49. {socketsecurity-2.0.56 → socketsecurity-2.1.2}/socketsecurity/plugins/__init__.py +0 -0
  50. {socketsecurity-2.0.56 → socketsecurity-2.1.2}/socketsecurity/plugins/base.py +0 -0
  51. {socketsecurity-2.0.56 → socketsecurity-2.1.2}/socketsecurity/plugins/jira.py +0 -0
  52. {socketsecurity-2.0.56 → socketsecurity-2.1.2}/socketsecurity/plugins/manager.py +0 -0
  53. {socketsecurity-2.0.56 → socketsecurity-2.1.2}/socketsecurity/plugins/slack.py +0 -0
  54. {socketsecurity-2.0.56 → socketsecurity-2.1.2}/socketsecurity/plugins/teams.py +0 -0
  55. {socketsecurity-2.0.56 → socketsecurity-2.1.2}/socketsecurity/plugins/webhook.py +0 -0
  56. {socketsecurity-2.0.56 → socketsecurity-2.1.2}/socketsecurity/socketcli.py +0 -0
  57. {socketsecurity-2.0.56 → socketsecurity-2.1.2}/tests/__init__.py +0 -0
  58. {socketsecurity-2.0.56 → socketsecurity-2.1.2}/tests/core/conftest.py +0 -0
  59. {socketsecurity-2.0.56 → socketsecurity-2.1.2}/tests/core/create_diff_input.json +0 -0
  60. {socketsecurity-2.0.56 → socketsecurity-2.1.2}/tests/core/test_diff_generation.py +0 -0
  61. {socketsecurity-2.0.56 → socketsecurity-2.1.2}/tests/core/test_package_and_alerts.py +0 -0
  62. {socketsecurity-2.0.56 → socketsecurity-2.1.2}/tests/core/test_sdk_methods.py +0 -0
  63. {socketsecurity-2.0.56 → socketsecurity-2.1.2}/tests/core/test_supporting_methods.py +0 -0
  64. {socketsecurity-2.0.56 → socketsecurity-2.1.2}/tests/data/fullscans/create_response.json +0 -0
  65. {socketsecurity-2.0.56 → socketsecurity-2.1.2}/tests/data/fullscans/diff/stream_diff.json +0 -0
  66. {socketsecurity-2.0.56 → socketsecurity-2.1.2}/tests/data/fullscans/diff/stream_diff_full.json +0 -0
  67. {socketsecurity-2.0.56 → socketsecurity-2.1.2}/tests/data/fullscans/head_scan/metadata.json +0 -0
  68. {socketsecurity-2.0.56 → socketsecurity-2.1.2}/tests/data/fullscans/head_scan/stream_scan.json +0 -0
  69. {socketsecurity-2.0.56 → socketsecurity-2.1.2}/tests/data/fullscans/head_scan/stream_scan_full.json +0 -0
  70. {socketsecurity-2.0.56 → socketsecurity-2.1.2}/tests/data/fullscans/new_scan/metadata.json +0 -0
  71. {socketsecurity-2.0.56 → socketsecurity-2.1.2}/tests/data/fullscans/new_scan/stream_scan.json +0 -0
  72. {socketsecurity-2.0.56 → socketsecurity-2.1.2}/tests/data/repos/repo_info_error.json +0 -0
  73. {socketsecurity-2.0.56 → socketsecurity-2.1.2}/tests/data/repos/repo_info_no_head.json +0 -0
  74. {socketsecurity-2.0.56 → socketsecurity-2.1.2}/tests/data/repos/repo_info_success.json +0 -0
  75. {socketsecurity-2.0.56 → socketsecurity-2.1.2}/tests/data/settings/security-policy.json +0 -0
  76. {socketsecurity-2.0.56 → socketsecurity-2.1.2}/tests/unit/__init__.py +0 -0
  77. {socketsecurity-2.0.56 → socketsecurity-2.1.2}/tests/unit/test_cli_config.py +0 -0
  78. {socketsecurity-2.0.56 → socketsecurity-2.1.2}/tests/unit/test_client.py +0 -0
  79. {socketsecurity-2.0.56 → socketsecurity-2.1.2}/tests/unit/test_config.py +0 -0
  80. {socketsecurity-2.0.56 → socketsecurity-2.1.2}/tests/unit/test_output.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: socketsecurity
3
- Version: 2.0.56
3
+ Version: 2.1.2
4
4
  Summary: Socket Security CLI for CI/CD
5
5
  Project-URL: Homepage, https://socket.dev
6
6
  Author-email: Douglas Coburn <douglas@socket.dev>
@@ -39,7 +39,7 @@ Requires-Dist: packaging
39
39
  Requires-Dist: prettytable
40
40
  Requires-Dist: python-dotenv
41
41
  Requires-Dist: requests
42
- Requires-Dist: socket-sdk-python>=2.0.21
42
+ Requires-Dist: socket-sdk-python<3,>=2.1.2
43
43
  Provides-Extra: dev
44
44
  Requires-Dist: hatch; extra == 'dev'
45
45
  Requires-Dist: pip-tools>=7.4.0; extra == 'dev'
@@ -96,12 +96,12 @@ If you don't want to provide the Socket API Token every time then you can use th
96
96
  | --commit-sha | False | "" | Commit SHA |
97
97
 
98
98
  #### Path and File
99
- | Parameter | Required | Default | Description |
100
- |:-------------------|:---------|:--------|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
101
- | --target-path | False | ./ | Target path for analysis |
102
- | --sbom-file | False | | SBOM file path |
103
- | --files | False | [] | Files to analyze (JSON array string) |
104
- | --exclude-patterns | False | [] | List of patterns to exclude from analysis (JSON array string). You can get supported files form the [Supported Files API](https://docs.socket.dev/reference/getsupportedfiles) |
99
+ | Parameter | Required | Default | Description |
100
+ |:----------------------|:---------|:--------|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
101
+ | --target-path | False | ./ | Target path for analysis |
102
+ | --sbom-file | False | | SBOM file path |
103
+ | --files | False | [] | Files to analyze (JSON array string) |
104
+ | --excluded-ecosystems | False | [] | List of ecosystems to exclude from analysis (JSON array string). You can get supported files from the [Supported Files API](https://docs.socket.dev/reference/getsupportedfiles) |
105
105
 
106
106
  #### Branch and Scan Configuration
107
107
  | Parameter | Required | Default | Description |
@@ -40,12 +40,12 @@ If you don't want to provide the Socket API Token every time then you can use th
40
40
  | --commit-sha | False | "" | Commit SHA |
41
41
 
42
42
  #### Path and File
43
- | Parameter | Required | Default | Description |
44
- |:-------------------|:---------|:--------|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
45
- | --target-path | False | ./ | Target path for analysis |
46
- | --sbom-file | False | | SBOM file path |
47
- | --files | False | [] | Files to analyze (JSON array string) |
48
- | --exclude-patterns | False | [] | List of patterns to exclude from analysis (JSON array string). You can get supported files form the [Supported Files API](https://docs.socket.dev/reference/getsupportedfiles) |
43
+ | Parameter | Required | Default | Description |
44
+ |:----------------------|:---------|:--------|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
45
+ | --target-path | False | ./ | Target path for analysis |
46
+ | --sbom-file | False | | SBOM file path |
47
+ | --files | False | [] | Files to analyze (JSON array string) |
48
+ | --excluded-ecosystems | False | [] | List of ecosystems to exclude from analysis (JSON array string). You can get supported files from the [Supported Files API](https://docs.socket.dev/reference/getsupportedfiles) |
49
49
 
50
50
  #### Branch and Scan Configuration
51
51
  | Parameter | Required | Default | Description |
@@ -6,7 +6,7 @@ build-backend = "hatchling.build"
6
6
 
7
7
  [project]
8
8
  name = "socketsecurity"
9
- version = "2.0.56"
9
+ version = "2.1.2"
10
10
  requires-python = ">= 3.10"
11
11
  license = {"file" = "LICENSE"}
12
12
  dependencies = [
@@ -16,7 +16,7 @@ dependencies = [
16
16
  'GitPython',
17
17
  'packaging',
18
18
  'python-dotenv',
19
- 'socket-sdk-python>=2.0.21'
19
+ 'socket-sdk-python>=2.1.2,<3'
20
20
  ]
21
21
  readme = "README.md"
22
22
  description = "Socket Security CLI for CI/CD"
@@ -63,10 +63,6 @@ include = [
63
63
  "socketsecurity/**/*.py",
64
64
  "socketsecurity/**/__init__.py"
65
65
  ]
66
- omit = [
67
- "socketsecurity/core/issues.py", # Large data file
68
- "socketsecurity/core/licenses.py" # Large data file
69
- ]
70
66
 
71
67
  [tool.coverage.report]
72
68
  exclude_lines = [
@@ -1,2 +1,2 @@
1
1
  __author__ = 'socket.dev'
2
- __version__ = '2.0.56'
2
+ __version__ = '2.1.2'
@@ -2,10 +2,12 @@ import logging
2
2
  import os
3
3
  import sys
4
4
  import time
5
+ import io
5
6
  from dataclasses import asdict
6
7
  from glob import glob
8
+ from io import BytesIO
7
9
  from pathlib import PurePath
8
- from typing import BinaryIO, Dict, List, Tuple, Set
10
+ from typing import BinaryIO, Dict, List, Tuple, Set, Union
9
11
  import re
10
12
  from socketdev import socketdev
11
13
  from socketdev.exceptions import APIFailure
@@ -13,7 +15,7 @@ from socketdev.fullscans import FullScanParams, SocketArtifact
13
15
  from socketdev.org import Organization
14
16
  from socketdev.repos import RepositoryInfo
15
17
  from socketdev.settings import SecurityPolicyRule
16
-
18
+ import copy
17
19
  from socketsecurity import __version__
18
20
  from socketsecurity.core.classes import (
19
21
  Alert,
@@ -24,7 +26,6 @@ from socketsecurity.core.classes import (
24
26
  Purl
25
27
  )
26
28
  from socketsecurity.core.exceptions import APIResourceNotFound
27
- from socketsecurity.core.licenses import Licenses
28
29
  from .socket_config import SocketConfig
29
30
  from .utils import socket_globs
30
31
  import importlib
@@ -186,6 +187,7 @@ class Core:
186
187
  for ecosystem in patterns:
187
188
  if ecosystem in self.config.excluded_ecosystems:
188
189
  continue
190
+ log.info(f'Scanning ecosystem: {ecosystem}')
189
191
  ecosystem_patterns = patterns[ecosystem]
190
192
  for file_name in ecosystem_patterns:
191
193
  original_pattern = ecosystem_patterns[file_name]["pattern"]
@@ -208,7 +210,7 @@ class Core:
208
210
  glob_end = time.time()
209
211
  log.debug(f"Globbing took {glob_end - glob_start:.4f} seconds")
210
212
 
211
- log.debug(f"Total files found: {len(files)}")
213
+ log.info(f"Total files found: {len(files)}")
212
214
  return sorted(files)
213
215
 
214
216
  def get_supported_patterns(self) -> Dict:
@@ -278,6 +280,14 @@ class Core:
278
280
  """
279
281
  return ''.join(f'[{char.lower()}{char.upper()}]' if char.isalpha() else char for char in input_string)
280
282
 
283
+ @staticmethod
284
+ def empty_head_scan_file() -> list[tuple[str, tuple[str, Union[BinaryIO, BytesIO]]]]:
285
+ # Create an empty file for when no head full scan so that the diff endpoint can always be used
286
+ empty_file_obj = io.BytesIO(b"")
287
+ empty_filename = "initial_head_scan"
288
+ empty_full_scan_file = [(empty_filename, (empty_filename, empty_file_obj))]
289
+ return empty_full_scan_file
290
+
281
291
  @staticmethod
282
292
  def load_files_for_sending(files: List[str], workspace: str) -> List[Tuple[str, Tuple[str, BinaryIO]]]:
283
293
  """
@@ -311,7 +321,7 @@ class Core:
311
321
 
312
322
  return send_files
313
323
 
314
- def create_full_scan(self, files: List[str], params: FullScanParams, has_head_scan: bool = False) -> FullScan:
324
+ def create_full_scan(self, files: list[tuple[str, tuple[str, BytesIO]]], params: FullScanParams) -> FullScan:
315
325
  """
316
326
  Creates a new full scan via the Socket API.
317
327
 
@@ -322,7 +332,7 @@ class Core:
322
332
  Returns:
323
333
  FullScan object with scan results
324
334
  """
325
- log.debug("Creating new full scan")
335
+ log.info("Creating new full scan")
326
336
  create_full_start = time.time()
327
337
 
328
338
  res = self.sdk.fullscans.post(files, params, use_types=True)
@@ -331,16 +341,60 @@ class Core:
331
341
  raise Exception(f"Error creating full scan: {res.message}, status: {res.status}")
332
342
 
333
343
  full_scan = FullScan(**asdict(res.data))
334
- if not has_head_scan:
335
- full_scan.sbom_artifacts = self.get_sbom_data(full_scan.id)
336
- full_scan.packages = self.create_packages_dict(full_scan.sbom_artifacts)
337
-
338
344
  create_full_end = time.time()
339
345
  total_time = create_full_end - create_full_start
340
346
  log.debug(f"New Full Scan created in {total_time:.2f} seconds")
341
347
 
342
348
  return full_scan
343
349
 
350
+ def check_full_scans_status(self, head_full_scan_id: str, new_full_scan_id: str) -> bool:
351
+ is_ready = False
352
+ current_timeout = self.config.timeout
353
+ self.sdk.set_timeout(0.5)
354
+ try:
355
+ self.sdk.fullscans.stream(self.config.org_slug, head_full_scan_id)
356
+ except Exception:
357
+ log.debug(f"Queued up full scan for processing ({head_full_scan_id})")
358
+
359
+ try:
360
+ self.sdk.fullscans.stream(self.config.org_slug, new_full_scan_id)
361
+ except Exception:
362
+ log.debug(f"Queued up full scan for processing ({new_full_scan_id})")
363
+ self.sdk.set_timeout(current_timeout)
364
+ start_check = time.time()
365
+ head_is_ready = False
366
+ new_is_ready = False
367
+ while not is_ready:
368
+ head_full_scan_metadata = self.sdk.fullscans.metadata(self.config.org_slug, head_full_scan_id)
369
+ if head_full_scan_metadata:
370
+ head_state = head_full_scan_metadata.get("scan_state")
371
+ else:
372
+ head_state = None
373
+ new_full_scan_metadata = self.sdk.fullscans.metadata(self.config.org_slug, new_full_scan_id)
374
+ if new_full_scan_metadata:
375
+ new_state = new_full_scan_metadata.get("scan_state")
376
+ else:
377
+ new_state = None
378
+ if head_state and head_state == "resolve":
379
+ head_is_ready = True
380
+ if new_state and new_state == "resolve":
381
+ new_is_ready = True
382
+ if head_is_ready and new_is_ready:
383
+ is_ready = True
384
+ current_time = time.time()
385
+ if current_time - start_check >= self.config.timeout:
386
+ log.debug(
387
+ f"Timeout reached while waiting for full scans to be ready "
388
+ f"({head_full_scan_id}, {new_full_scan_id})"
389
+ )
390
+ break
391
+ total_time = time.time() - start_check
392
+ if is_ready:
393
+ log.info(f"Full scans are ready in {total_time:.2f} seconds")
394
+ else:
395
+ log.warning(f"Full scans are not ready yet ({head_full_scan_id}, {new_full_scan_id})")
396
+ return is_ready
397
+
344
398
  def get_full_scan(self, full_scan_id: str) -> FullScan:
345
399
  """
346
400
  Get a FullScan object for an existing full scan including sbom_artifacts and packages.
@@ -403,14 +457,9 @@ class Core:
403
457
  return ""
404
458
 
405
459
  license_raw = package.license
406
- all_licenses = Licenses()
407
- license_str = Licenses.make_python_safe(license_raw)
408
-
409
- if license_str is not None and hasattr(all_licenses, license_str):
410
- license_obj = getattr(all_licenses, license_str)
411
- return license_obj.licenseText
412
-
413
- return ""
460
+ data = self.sdk.licensemetadata.post([license_raw], {'includetext': 'true'})
461
+ license_str = data.data[0].license if data and len(data) == 1 else ""
462
+ return license_str
414
463
 
415
464
  def get_repo_info(self, repo_slug: str, default_branch: str = "socket-default-branch") -> RepositoryInfo:
416
465
  """
@@ -485,7 +534,7 @@ class Core:
485
534
  pkg.url += f"/{pkg.name}/overview/{pkg.version}"
486
535
  return pkg
487
536
 
488
- def get_added_and_removed_packages(self, head_full_scan_id: str, new_full_scan: FullScan) -> Tuple[Dict[str, Package], Dict[str, Package]]:
537
+ def get_added_and_removed_packages(self, head_full_scan_id: str, new_full_scan_id: str) -> Tuple[Dict[str, Package], Dict[str, Package]]:
489
538
  """
490
539
  Get packages that were added and removed between scans.
491
540
 
@@ -496,14 +545,11 @@ class Core:
496
545
  Returns:
497
546
  Tuple of (added_packages, removed_packages) dictionaries
498
547
  """
499
- if head_full_scan_id is None:
500
- log.info(f"No head scan found. New scan ID: {new_full_scan.id}")
501
- return new_full_scan.packages, {}
502
548
 
503
- log.info(f"Comparing scans - Head scan ID: {head_full_scan_id}, New scan ID: {new_full_scan.id}")
549
+ log.info(f"Comparing scans - Head scan ID: {head_full_scan_id}, New scan ID: {new_full_scan_id}")
504
550
  diff_start = time.time()
505
551
  try:
506
- diff_report = self.sdk.fullscans.stream_diff(self.config.org_slug, head_full_scan_id, new_full_scan.id, use_types=True).data
552
+ diff_report = self.sdk.fullscans.stream_diff(self.config.org_slug, head_full_scan_id, new_full_scan_id, use_types=True).data
507
553
  except APIFailure as e:
508
554
  log.error(f"API Error: {e}")
509
555
  sys.exit(1)
@@ -572,22 +618,30 @@ class Core:
572
618
  # Find manifest files
573
619
  files = self.find_files(path)
574
620
  files_for_sending = self.load_files_for_sending(files, path)
575
- has_head_scan = False
576
621
  if not files:
577
622
  return Diff(id="no_diff_id")
578
623
 
579
624
  try:
580
625
  # Get head scan ID
581
626
  head_full_scan_id = self.get_head_scan_for_repo(params.repo)
582
- if head_full_scan_id is not None:
583
- has_head_scan = True
584
627
  except APIResourceNotFound:
585
628
  head_full_scan_id = None
586
629
 
630
+ if head_full_scan_id is None:
631
+ new_params = copy.deepcopy(params.__dict__)
632
+ new_params.pop('include_license_details')
633
+ tmp_params = FullScanParams(**new_params)
634
+ tmp_params.include_license_details = params.include_license_details
635
+ tmp_params.tmp = True
636
+ tmp_params.set_as_pending_head = False
637
+ tmp_params.make_default_branch = False
638
+ head_full_scan = self.create_full_scan(Core.empty_head_scan_file(), tmp_params)
639
+ head_full_scan_id = head_full_scan.id
640
+
587
641
  # Create new scan
588
642
  try:
589
643
  new_scan_start = time.time()
590
- new_full_scan = self.create_full_scan(files_for_sending, params, has_head_scan)
644
+ new_full_scan = self.create_full_scan(files_for_sending, params)
591
645
  new_full_scan.sbom_artifacts = self.get_sbom_data(new_full_scan.id)
592
646
  new_scan_end = time.time()
593
647
  log.info(f"Total time to create new full scan: {new_scan_end - new_scan_start:.2f}")
@@ -600,7 +654,10 @@ class Core:
600
654
  log.error(f"Stack trace:\n{traceback.format_exc()}")
601
655
  raise
602
656
 
603
- added_packages, removed_packages = self.get_added_and_removed_packages(head_full_scan_id, new_full_scan)
657
+ scans_ready = self.check_full_scans_status(head_full_scan_id, new_full_scan.id)
658
+ if scans_ready is False:
659
+ log.error(f"Full scans did not complete within {self.config.timeout} seconds")
660
+ added_packages, removed_packages = self.get_added_and_removed_packages(head_full_scan_id, new_full_scan.id)
604
661
 
605
662
  diff = self.create_diff_report(added_packages, removed_packages)
606
663
 
@@ -742,6 +799,8 @@ class Core:
742
799
  introduced_by = []
743
800
  if package.direct:
744
801
  manifests = ""
802
+ if not hasattr(package, "manifestFiles"):
803
+ return introduced_by
745
804
  for manifest_data in package.manifestFiles:
746
805
  manifest_file = manifest_data.get("file")
747
806
  manifests += f"{manifest_file};"
@@ -4,7 +4,7 @@ from urllib.parse import urlparse
4
4
  from typing import Set, List
5
5
  import os
6
6
 
7
- from socketsecurity.core.issues import AllIssues
7
+ from socketdev.core.issues import AllIssues
8
8
  from socketsecurity import __version__
9
9
 
10
10
 
@@ -48,7 +48,6 @@ class SocketConfig:
48
48
 
49
49
  # Initialize AllIssues if None
50
50
  if self.all_issues is None:
51
- from socketsecurity.core.issues import AllIssues
52
51
  self.all_issues = AllIssues()
53
52
 
54
53
  @staticmethod