diff --git a/tests/standalone_plugins/test_deprecate_vts.py b/tests/standalone_plugins/test_deprecate_vts.py index c01a79ec..7c4450a4 100644 --- a/tests/standalone_plugins/test_deprecate_vts.py +++ b/tests/standalone_plugins/test_deprecate_vts.py @@ -11,9 +11,9 @@ _finalize_content, _get_summary, deprecate, - filter_files, get_files_from_path, parse_args, + parse_files, update_summary, ) @@ -26,7 +26,7 @@ def test_parse_args(self): args = parse_args( [ - "--files", + "--file", testfile, "--output-path", output_path, @@ -34,7 +34,7 @@ def test_parse_args(self): reason, ] ) - self.assertEqual(args.files, [Path(testfile)]) + self.assertEqual(args.file, [Path(testfile)]) self.assertEqual(args.output_path, Path(output_path)) self.assertEqual(args.deprecation_reason, reason) @@ -47,7 +47,7 @@ def test_mandatory_arg_group_both(self): with self.assertRaises(SystemExit): parse_args( [ - "--files", + "--file", testfile, "--output-path", output_path, @@ -87,6 +87,28 @@ def test_mandatory_arg_group_neither(self): ] ) + def test_parse_from_file(self): + output_path = "attic/" + with TemporaryDirectory() as tempdir: + from_file = tempdir / "from_file.txt" + testfile1 = tempdir / "testfile1.nasl" + testfile2 = tempdir / "testfile2.nasl" + + from_file.write_text(f"{testfile1}\n{testfile2}\n", encoding="utf8") + + args = parse_args( + [ + "--from-file", + str(from_file), + "--output-path", + output_path, + "-r", + "NOTUS", + ] + ) + + self.assertEqual(args.from_file, from_file) + NASL_CONTENT = ( '...if(description)\n{\n script_oid("1.3.6.1.4.1.25623.1.0.910673");' @@ -190,16 +212,12 @@ def test_get_files_from_path(self): self.assertEqual(result, expected) - def test_filter_files(self): + def test_parse_files(self): with TemporaryDirectory() as in_dir: testfile1 = in_dir / "gb_rhsa_2021_8383_8383.nasl" testfile1.write_text(NASL_CONTENT, encoding="utf8") - testfile2 = in_dir / "gb_rhsa_2020_8383_8383.nasl" - testfile2.write_text(NASL_CONTENT, encoding="utf8") - result = filter_files( - files=[testfile1, testfile2], filename_prefix="gb_rhsa_2021" - ) + result = parse_files(files=[testfile1]) expected = [ DeprecatedFile( name="gb_rhsa_2021_8383_8383.nasl", @@ -209,15 +227,3 @@ def test_filter_files(self): ] self.assertEqual(result, expected) - - def test_filter_files_out(self): - with TemporaryDirectory() as in_dir: - testfile1 = in_dir / "gb_rhsa_2021_8383_8383.nasl" - testfile1.write_text(NASL_CONTENT, encoding="utf8") - - result = filter_files( - files=[testfile1], filename_prefix="gb_rhsa_2020" - ) - expected = [] - - self.assertEqual(result, expected) diff --git a/troubadix/standalone_plugins/deprecate_vts.py b/troubadix/standalone_plugins/deprecate_vts.py index 7c70e495..6ec25134 100644 --- a/troubadix/standalone_plugins/deprecate_vts.py +++ b/troubadix/standalone_plugins/deprecate_vts.py @@ -2,12 +2,14 @@ # SPDX-FileCopyrightText: 2024 Greenbone AG import re -from argparse import ArgumentParser, Namespace +from argparse import ArgumentParser, ArgumentTypeError, Namespace from dataclasses import dataclass from enum import Enum from pathlib import Path from typing import Iterable, Optional +from pontos.terminal.terminal import ConsoleTerminal + from troubadix.argparser import directory_type, file_type from troubadix.helper.patterns import ( ScriptTag, @@ -15,6 +17,7 @@ get_script_tag_pattern, get_special_script_tag_pattern, ) +from troubadix.troubadix import from_file class Deprecations(Enum): @@ -34,6 +37,15 @@ class DeprecatedFile: KB_ITEMS_PATTERN = re.compile(r"set_kb_item\(.+\);") +def existing_file_type(string: str) -> Path: + file_path = Path(string) + if not file_path.exists(): + raise ArgumentTypeError(f'File "{string}" does not exist.') + if not file_path.is_file(): + raise ArgumentTypeError(f'"{string}" is not a file.') + return file_path + + def update_summary(file: DeprecatedFile, deprecation_reason: str) -> str: """Update the summary of the nasl script by adding the information that the script has been deprecated, and if possible, the oid of @@ -83,26 +95,18 @@ def get_files_from_path(dir_path: Path = None) -> list: return [file for file in dir_path.glob("**/*")] -def filter_files( - files: list, filename_prefix: str = None -) -> list[DeprecatedFile]: - """Filter the files based on a provided prefix and convert them into +def parse_files(files: list) -> list[DeprecatedFile]: + """Convert filepaths into DeprecatedFile objects Args: files: a list of files to deprecate, should be .nasl VTs - filename_prefix: an optional prefix to filter only specific files Returns: List of DeprecatedFile objects """ to_deprecate = [] - if filename_prefix: - filename_filter = re.compile(rf"{filename_prefix}") - files[:] = [ - file for file in files if re.match(filename_filter, file.name) - ] for file in files: with file.open("r", encoding="latin-1") as fh: @@ -193,16 +197,6 @@ def parse_args(args: Iterable[str] = None) -> Namespace: required=True, help="Path where the deprecated files should be written to.", ) - parser.add_argument( - "-p", - "--filename-prefix", - metavar="", - nargs="?", - default=None, - type=str, - help="The prefix of the files you would like to deprecate," - "for example 'gb_rhsa_2021' to filter on the year", - ) parser.add_argument( "-r", "--deprecation-reason", @@ -214,16 +208,17 @@ def parse_args(args: Iterable[str] = None) -> Namespace: "been merged with another still active VT, 'duplicate': The VT has" "a still active duplicate, 'defunct': The VT is no longer " "functional.", + required=True, ) group = parser.add_mutually_exclusive_group(required=True) group.add_argument( "-f", - "--files", - metavar="", + "--file", + metavar="", nargs="+", default=None, type=file_type, - help="Files to deprecate", + help="File to deprecate", ) group.add_argument( "-i", @@ -231,20 +226,36 @@ def parse_args(args: Iterable[str] = None) -> Namespace: metavar="", default=None, type=directory_type, - help="Path to the existing nasl script directory", + help="Path to a directory where all files should be deprecated.", + ) + group.add_argument( + "--from-file", + metavar="", + default=None, + type=existing_file_type, + help=( + "Path to a single file that contains a list of files " + "to be deprecated, separated by new lines." + ), ) return parser.parse_args(args) def main(): args = parse_args() + terminal = ConsoleTerminal() input_path = args.input_path if args.input_path else None - filename_prefix = args.filename_prefix + files = [] - files = args.files or get_files_from_path(input_path) - filtered_files = filter_files(files, filename_prefix) + if input_path: + files = get_files_from_path(input_path) + elif args.from_file: + files = from_file(include_file=args.from_file, term=terminal) + elif args.file: + files = args.file - deprecate(args.output_path, filtered_files, args.deprecation_reason) + to_be_deprecated = parse_files(files) + deprecate(args.output_path, to_be_deprecated, args.deprecation_reason) if __name__ == "__main__":