diff --git a/src/cli/VERSION.txt b/src/cli/VERSION.txt index f570a76..67f15dc 100644 --- a/src/cli/VERSION.txt +++ b/src/cli/VERSION.txt @@ -1 +1 @@ -1.7.13-rc1 \ No newline at end of file +1.7.13-rc2 \ No newline at end of file diff --git a/src/cli/soos.py b/src/cli/soos.py index 3d501eb..eb3c1be 100644 --- a/src/cli/soos.py +++ b/src/cli/soos.py @@ -770,7 +770,17 @@ def case_insensitive_map(c): ) # returns count of valid manifests that were uploaded or None on error - def send_manifests(self, project_id, analysis_id, dirs_to_exclude, files_to_exclude, package_managers) -> Optional[int]: + def send_manifests(self, project_id, analysis_id, dirs_to_exclude, files_to_exclude, package_managers, use_lock_file) -> Optional[int]: + + def is_valid_lockfile_pattern(pattern: str, use_lock_file: bool) -> bool: + lock_patterns = [".lockfile", ".lock", "-lock.json"] + return any(lock in pattern for lock in lock_patterns) if use_lock_file else not any(lock in pattern for lock in lock_patterns) + + def build_looking_for_files_str(use_lock_file: bool) -> str: + if use_lock_file: + return "Lock file is on, non-lock files will be ignored." + else: + return "Lock file is off, lock files will be ignored." has_more_than_maximum_manifests = False @@ -779,6 +789,7 @@ def send_manifests(self, project_id, analysis_id, dirs_to_exclude, files_to_excl print() SOOS.console_log("------------------------") SOOS.console_log("Begin Recursive Manifest Search") + SOOS.console_log(build_looking_for_files_str(use_lock_file)) SOOS.console_log("------------------------") MANIFEST_FILES = self.load_manifest_types() @@ -793,12 +804,14 @@ def send_manifests(self, project_id, analysis_id, dirs_to_exclude, files_to_excl for entries in manifest_file["manifests"]: pattern = entries["pattern"] + # Filter lockfiles or not based on use_lock_file + if not is_valid_lockfile_pattern(pattern, use_lock_file): + continue + candidate_files = self.find_manifest_files(pattern=pattern) for cf in candidate_files: files.append(cf) - # iterate each - # avoid directories to exclude for file_name in files: exclude = False @@ -862,6 +875,9 @@ def send_manifests(self, project_id, analysis_id, dirs_to_exclude, files_to_excl "Result: Setting immediate parent folder to " ) pass + + # remove GitHub path if exists, this will avoid running on cloudflare blocking so often + parent_folder = parent_folder.replace("/github/workspace", "") manifest_label = parent_folder @@ -1094,6 +1110,36 @@ def exec(soos_context, project_id, analysis_id): SOOS.console_log("Analysis Start API Exception Occurred. ") return analysis_start_response + +class SOOSProjectSettingsAPI: + + URI_TEMPLATE = "{soos_base_uri}clients/{soos_client_id}/projects/{soos_project_id}/settings" + + @staticmethod + def generate_api_url(soos_context, project_id): + return SOOSProjectSettingsAPI.URI_TEMPLATE.format(soos_base_uri=soos_context.base_uri.replace("api.soos.io", "api-projects.soos.io"), + soos_client_id=soos_context.client_id, + soos_project_id=project_id) + + @staticmethod + def exec(soos_context, project_id): + + url = SOOSProjectSettingsAPI.generate_api_url(soos_context, project_id) + + project_settings_response = None + + try: + project_settings_response = requests.get( + url=url, + params = {'fallback': 'true'}, + headers={'x-soos-apikey': soos_context.api_key, + 'Content-Type': 'application/json'} + ) + + except requests.RequestException as e: + SOOS.console_log(f"Project Settings API Exception Occurred: {str(e)}") + + return project_settings_response class SOOSAnalysisResultAPI: @@ -1647,14 +1693,20 @@ def entry_point(): SOOS.console_log("Analysis Id: " + create_scan_api_response.analysisId) SOOS.console_log("Project Id: " + create_scan_api_response.projectHash) SOOS.console_log("Scan Status URL: " + create_scan_api_response.scanStatusUrl) - # Now get ready to send your manifests out for Start Analysis API + # Get Project Settings so we can filter lock or non lock files + project_settings = SOOSProjectSettingsAPI.exec(soos.context, create_scan_api_response.projectHash) + + project_settings_dict = project_settings.json() + use_lock_file = project_settings_dict.get('useLockFile', False) + use_lock_file = False if use_lock_file is None else use_lock_file valid_manifests_count = soos.send_manifests( project_id=create_scan_api_response.projectHash, analysis_id=create_scan_api_response.analysisId, dirs_to_exclude=soos.script.directories_to_exclude, files_to_exclude=soos.script.files_to_exclude, - package_managers=soos.script.package_managers + package_managers=soos.script.package_managers, + use_lock_file=use_lock_file, ) if valid_manifests_count is not None and valid_manifests_count > 0: diff --git a/tests/tests.py b/tests/tests.py index 962add6..46e22d0 100644 --- a/tests/tests.py +++ b/tests/tests.py @@ -129,12 +129,11 @@ def test_exclude_files(self): files_to_exclude = "pubspec.yaml, *composer.json, cargo* " expected_text = f"FILES_TO_EXCLUDE: {files_to_exclude.strip()}" self.assertEqual(process.stdout.count(expected_text), 1) - self.assertEqual(process.stdout.count('Skipping file due to files_to_exclude:'), 4) + self.assertEqual(process.stdout.count('Skipping file due to files_to_exclude:'), 3) self.assertEqual(process.stdout.count('manifests/exclude_files/pubspec.yaml'), 1) self.assertEqual(process.stdout.count('manifests/exclude_files/composer.json'), 1) self.assertEqual(process.stdout.count('manifests/exclude_files/cargo.toml'), 1) - self.assertEqual(process.stdout.count('manifests/exclude_files/cargo.lock'), 1) - self.assertEqual(process.stdout.count('Found manifest file:'), 2) + self.assertEqual(process.stdout.count('Found manifest file:'), 1) self.assertEqual(process.stdout.count(test_complete_fail), 1, "Invalid completion message.") def test_exclude_dirs(self): @@ -143,11 +142,10 @@ def test_exclude_dirs(self): text=True) print(process.stdout) self.assertEqual(process.returncode, 1, "Invalid return code.") - self.assertEqual(process.stdout.count('Skipping file due to dirs_to_exclude:'), 3) + self.assertEqual(process.stdout.count('Skipping file due to dirs_to_exclude:'), 2) self.assertEqual(process.stdout.count('manifests/exclude_dirs/exclude/composer.json'), 1) self.assertEqual(process.stdout.count('manifests/exclude_dirs/exclude/cargo.toml'), 1) - self.assertEqual(process.stdout.count('manifests/exclude_dirs/exclude/cargo.lock'), 1) - self.assertEqual(process.stdout.count('Found manifest file:'), 3) + self.assertEqual(process.stdout.count('Found manifest file:'), 2) self.assertEqual(process.stdout.count(test_complete_fail), 1, "Invalid completion message.")