troubadix 25.12.3__py3-none-any.whl → 26.1.0__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.
- troubadix/__version__.py +1 -1
- troubadix/argparser.py +4 -14
- troubadix/helper/date_format.py +3 -7
- troubadix/helper/helper.py +1 -3
- troubadix/helper/if_block_parser.py +14 -37
- troubadix/helper/linguistic_exception_handler.py +6 -18
- troubadix/helper/patterns.py +7 -19
- troubadix/helper/remove_comments.py +1 -4
- troubadix/helper/text_utils.py +1 -3
- troubadix/plugin.py +3 -9
- troubadix/plugins/__init__.py +6 -20
- troubadix/plugins/badwords.py +3 -9
- troubadix/plugins/copyright_text.py +2 -5
- troubadix/plugins/copyright_year.py +4 -12
- troubadix/plugins/creation_date.py +3 -9
- troubadix/plugins/cvss_format.py +1 -3
- troubadix/plugins/dependencies.py +2 -5
- troubadix/plugins/dependency_category_order.py +7 -20
- troubadix/plugins/deprecated_dependency.py +6 -16
- troubadix/plugins/deprecated_functions.py +1 -2
- troubadix/plugins/double_end_points.py +2 -7
- troubadix/plugins/duplicate_oid.py +1 -3
- troubadix/plugins/forking_nasl_functions.py +1 -4
- troubadix/plugins/get_kb_on_services.py +2 -4
- troubadix/plugins/grammar.py +6 -12
- troubadix/plugins/http_links_in_tags.py +1 -3
- troubadix/plugins/illegal_characters.py +5 -13
- troubadix/plugins/log_messages.py +1 -2
- troubadix/plugins/malformed_dependencies.py +2 -6
- troubadix/plugins/missing_desc_exit.py +1 -3
- troubadix/plugins/multiple_re_parameters.py +2 -6
- troubadix/plugins/newlines.py +1 -2
- troubadix/plugins/overlong_description_lines.py +2 -6
- troubadix/plugins/prod_svc_detect_in_vulnvt.py +1 -4
- troubadix/plugins/script_add_preference_id.py +3 -10
- troubadix/plugins/script_add_preference_type.py +2 -7
- troubadix/plugins/script_calls_empty_values.py +3 -3
- troubadix/plugins/script_calls_recommended.py +5 -8
- troubadix/plugins/script_copyright.py +1 -3
- troubadix/plugins/script_family.py +1 -2
- troubadix/plugins/script_tag_form.py +1 -3
- troubadix/plugins/script_tag_whitespaces.py +4 -8
- troubadix/plugins/script_tags_mandatory.py +2 -5
- troubadix/plugins/script_version_and_last_modification_tags.py +6 -17
- troubadix/plugins/script_xref_form.py +1 -3
- troubadix/plugins/script_xref_url.py +3 -7
- troubadix/plugins/security_messages.py +6 -17
- troubadix/plugins/severity_date.py +3 -9
- troubadix/plugins/severity_format.py +1 -3
- troubadix/plugins/severity_origin.py +1 -3
- troubadix/plugins/solution_text.py +6 -10
- troubadix/plugins/solution_type.py +1 -2
- troubadix/plugins/spaces_before_dots.py +2 -8
- troubadix/plugins/spaces_in_filename.py +1 -2
- troubadix/plugins/spelling.py +5 -14
- troubadix/plugins/trailing_spaces_tabs.py +2 -5
- troubadix/plugins/using_display.py +2 -6
- troubadix/plugins/valid_oid.py +51 -60
- troubadix/plugins/valid_script_tag_names.py +2 -5
- troubadix/plugins/variable_assigned_in_if.py +2 -7
- troubadix/plugins/variable_redefinition_in_foreach.py +2 -6
- troubadix/plugins/vt_placement.py +2 -8
- troubadix/reporter.py +6 -19
- troubadix/results.py +2 -8
- troubadix/runner.py +5 -14
- troubadix/standalone_plugins/allowed_rev_diff.py +8 -25
- troubadix/standalone_plugins/changed_creation_date.py +3 -9
- troubadix/standalone_plugins/changed_cves.py +4 -12
- troubadix/standalone_plugins/changed_oid.py +2 -6
- troubadix/standalone_plugins/changed_packages/changed_packages.py +3 -8
- troubadix/standalone_plugins/changed_packages/marker/changed_update.py +1 -3
- troubadix/standalone_plugins/changed_packages/marker/dropped_architecture.py +1 -3
- troubadix/standalone_plugins/changed_packages/package.py +2 -5
- troubadix/standalone_plugins/dependency_graph/checks.py +5 -15
- troubadix/standalone_plugins/dependency_graph/dependency_graph.py +5 -13
- troubadix/standalone_plugins/deprecate_vts.py +3 -9
- troubadix/standalone_plugins/file_extensions.py +3 -10
- troubadix/standalone_plugins/last_modification.py +3 -9
- troubadix/standalone_plugins/no_solution.py +12 -32
- troubadix/standalone_plugins/version_updated.py +4 -12
- troubadix/troubadix.py +1 -4
- {troubadix-25.12.3.dist-info → troubadix-26.1.0.dist-info}/METADATA +1 -1
- troubadix-26.1.0.dist-info/RECORD +116 -0
- troubadix-25.12.3.dist-info/RECORD +0 -116
- {troubadix-25.12.3.dist-info → troubadix-26.1.0.dist-info}/WHEEL +0 -0
- {troubadix-25.12.3.dist-info → troubadix-26.1.0.dist-info}/entry_points.txt +0 -0
- {troubadix-25.12.3.dist-info → troubadix-26.1.0.dist-info}/licenses/LICENSE +0 -0
troubadix/reporter.py
CHANGED
|
@@ -77,9 +77,7 @@ class Reporter:
|
|
|
77
77
|
self._term.ok(message)
|
|
78
78
|
self._log_append(f"\t\t{message}".replace("\n", "\n\t\t"))
|
|
79
79
|
|
|
80
|
-
def _process_plugin_results(
|
|
81
|
-
self, plugin_name: str, plugin_results: Iterable[LinterResult]
|
|
82
|
-
):
|
|
80
|
+
def _process_plugin_results(self, plugin_name: str, plugin_results: Iterable[LinterResult]):
|
|
83
81
|
"""Process the results of a plugin: Print/Log results if
|
|
84
82
|
verbosity/logging fits and count the results"""
|
|
85
83
|
if plugin_results and self._verbose > 0:
|
|
@@ -123,9 +121,7 @@ class Reporter:
|
|
|
123
121
|
with self._term.indent():
|
|
124
122
|
self._process_plugin_results(plugin_name, plugin_results)
|
|
125
123
|
|
|
126
|
-
def report_by_file_plugin(
|
|
127
|
-
self, file_results: FileResults, pos: int
|
|
128
|
-
) -> None:
|
|
124
|
+
def report_by_file_plugin(self, file_results: FileResults, pos: int) -> None:
|
|
129
125
|
"""Print/log the results of all plugins for a specific file
|
|
130
126
|
|
|
131
127
|
Arguments:
|
|
@@ -135,12 +131,8 @@ class Reporter:
|
|
|
135
131
|
"""
|
|
136
132
|
if file_results and self._verbose > 0 or self._verbose > 1:
|
|
137
133
|
# only print the part "common/some_nasl.nasl"
|
|
138
|
-
from_root_path = get_path_from_root(
|
|
139
|
-
|
|
140
|
-
)
|
|
141
|
-
self._report_bold_info(
|
|
142
|
-
f"Checking {from_root_path} ({pos}/{self._files_count})"
|
|
143
|
-
)
|
|
134
|
+
from_root_path = get_path_from_root(file_results.file_path, self._root)
|
|
135
|
+
self._report_bold_info(f"Checking {from_root_path} ({pos}/{self._files_count})")
|
|
144
136
|
|
|
145
137
|
with self._term.indent():
|
|
146
138
|
for (
|
|
@@ -164,9 +156,7 @@ class Reporter:
|
|
|
164
156
|
if included:
|
|
165
157
|
self.report_info(f"Included Plugins: {', '.join(included)}")
|
|
166
158
|
|
|
167
|
-
self.report_info(
|
|
168
|
-
f"Running plugins: {', '.join([p.name for p in plugins])}"
|
|
169
|
-
)
|
|
159
|
+
self.report_info(f"Running plugins: {', '.join([p.name for p in plugins])}")
|
|
170
160
|
|
|
171
161
|
def report_statistic(self) -> None:
|
|
172
162
|
"""Print a Error/Warning summary from the different plugins"""
|
|
@@ -195,10 +185,7 @@ class Reporter:
|
|
|
195
185
|
if self._fix and self._ignore_warnings:
|
|
196
186
|
line = f"{plugin:48} {count['error']:8} {count['fix']:8}"
|
|
197
187
|
elif self._fix:
|
|
198
|
-
line =
|
|
199
|
-
f"{plugin:48} {count['error']:8} {count['warning']:8}"
|
|
200
|
-
f" {count['fix']:8}"
|
|
201
|
-
)
|
|
188
|
+
line = f"{plugin:48} {count['error']:8} {count['warning']:8}" f" {count['fix']:8}"
|
|
202
189
|
elif self._ignore_warnings:
|
|
203
190
|
line = f"{plugin:48} {count['error']:8}"
|
|
204
191
|
else:
|
troubadix/results.py
CHANGED
|
@@ -28,15 +28,9 @@ class Results:
|
|
|
28
28
|
self.has_plugin_results = False
|
|
29
29
|
self._ignore_warnings = ignore_warnings
|
|
30
30
|
|
|
31
|
-
def add_plugin_results(
|
|
32
|
-
self, plugin_name: str, results: Iterator[LinterResult]
|
|
33
|
-
) -> "Results":
|
|
31
|
+
def add_plugin_results(self, plugin_name: str, results: Iterator[LinterResult]) -> "Results":
|
|
34
32
|
if self._ignore_warnings:
|
|
35
|
-
results = [
|
|
36
|
-
result
|
|
37
|
-
for result in results
|
|
38
|
-
if not isinstance(result, LinterWarning)
|
|
39
|
-
]
|
|
33
|
+
results = [result for result in results if not isinstance(result, LinterWarning)]
|
|
40
34
|
else:
|
|
41
35
|
results = list(results)
|
|
42
36
|
|
troubadix/runner.py
CHANGED
|
@@ -86,9 +86,7 @@ class Runner:
|
|
|
86
86
|
def _check_file(self, file_path: Path) -> FileResults:
|
|
87
87
|
"""Run all file plugins on a single file and collect the results"""
|
|
88
88
|
results = FileResults(file_path, ignore_warnings=self._ignore_warnings)
|
|
89
|
-
context = FilePluginContext(
|
|
90
|
-
root=self._root, nasl_file=file_path.resolve()
|
|
91
|
-
)
|
|
89
|
+
context = FilePluginContext(root=self._root, nasl_file=file_path.resolve())
|
|
92
90
|
|
|
93
91
|
for plugin_class in self.plugins.file_plugins:
|
|
94
92
|
plugin = plugin_class(context)
|
|
@@ -105,8 +103,7 @@ class Runner:
|
|
|
105
103
|
# run files plugins
|
|
106
104
|
context = FilesPluginContext(root=self._root, nasl_files=files)
|
|
107
105
|
files_plugins = [
|
|
108
|
-
plugin_class(context)
|
|
109
|
-
for plugin_class in self.plugins.files_plugins
|
|
106
|
+
plugin_class(context) for plugin_class in self.plugins.files_plugins
|
|
110
107
|
]
|
|
111
108
|
|
|
112
109
|
for results in pool.imap_unordered(
|
|
@@ -116,14 +113,10 @@ class Runner:
|
|
|
116
113
|
|
|
117
114
|
# run file plugins
|
|
118
115
|
for i, results in enumerate(
|
|
119
|
-
iterable=pool.imap_unordered(
|
|
120
|
-
self._check_file, files, chunksize=CHUNKSIZE
|
|
121
|
-
),
|
|
116
|
+
iterable=pool.imap_unordered(self._check_file, files, chunksize=CHUNKSIZE),
|
|
122
117
|
start=1,
|
|
123
118
|
):
|
|
124
|
-
self._reporter.report_by_file_plugin(
|
|
125
|
-
file_results=results, pos=i
|
|
126
|
-
)
|
|
119
|
+
self._reporter.report_by_file_plugin(file_results=results, pos=i)
|
|
127
120
|
|
|
128
121
|
except KeyboardInterrupt:
|
|
129
122
|
pool.terminate()
|
|
@@ -145,9 +138,7 @@ class Runner:
|
|
|
145
138
|
start = datetime.datetime.now()
|
|
146
139
|
self._run_pooled(files)
|
|
147
140
|
|
|
148
|
-
self._reporter.report_info(
|
|
149
|
-
f"Time elapsed: {datetime.datetime.now() - start}"
|
|
150
|
-
)
|
|
141
|
+
self._reporter.report_info(f"Time elapsed: {datetime.datetime.now() - start}")
|
|
151
142
|
self._reporter.report_statistic()
|
|
152
143
|
|
|
153
144
|
# Return true if no error exists
|
|
@@ -29,8 +29,7 @@ def parse_arguments() -> Namespace:
|
|
|
29
29
|
"--directory",
|
|
30
30
|
default=Path.cwd(),
|
|
31
31
|
type=Path,
|
|
32
|
-
help="The directory the repository to check is located in. "
|
|
33
|
-
"Defaults to 'pwd'",
|
|
32
|
+
help="The directory the repository to check is located in. " "Defaults to 'pwd'",
|
|
34
33
|
)
|
|
35
34
|
|
|
36
35
|
ignored_linestart_group = argument_parser.add_mutually_exclusive_group()
|
|
@@ -42,8 +41,7 @@ def parse_arguments() -> Namespace:
|
|
|
42
41
|
nargs="*",
|
|
43
42
|
type=str,
|
|
44
43
|
default=DEFAULT_IGNORED_LINESTARTS,
|
|
45
|
-
help="A list of line starts which will make the line be ignored. "
|
|
46
|
-
"Default: %(default)s",
|
|
44
|
+
help="A list of line starts which will make the line be ignored. " "Default: %(default)s",
|
|
47
45
|
)
|
|
48
46
|
|
|
49
47
|
ignored_linestart_group.add_argument(
|
|
@@ -73,9 +71,7 @@ def parse_arguments() -> Namespace:
|
|
|
73
71
|
"to check the diff for",
|
|
74
72
|
)
|
|
75
73
|
|
|
76
|
-
argument_parser.add_argument(
|
|
77
|
-
"-s", "--source", type=str, required=True, help="The upstream rev"
|
|
78
|
-
)
|
|
74
|
+
argument_parser.add_argument("-s", "--source", type=str, required=True, help="The upstream rev")
|
|
79
75
|
|
|
80
76
|
argument_parser.add_argument(
|
|
81
77
|
"-t", "--target", type=str, required=True, help="The downstream rev"
|
|
@@ -84,14 +80,8 @@ def parse_arguments() -> Namespace:
|
|
|
84
80
|
return argument_parser.parse_args()
|
|
85
81
|
|
|
86
82
|
|
|
87
|
-
def check_diff_line_starts_with_ignored_linestart(
|
|
88
|
-
|
|
89
|
-
) -> bool:
|
|
90
|
-
return any(
|
|
91
|
-
linestart
|
|
92
|
-
for linestart in ignored_linestarts
|
|
93
|
-
if line.startswith(linestart)
|
|
94
|
-
)
|
|
83
|
+
def check_diff_line_starts_with_ignored_linestart(line: str, ignored_linestarts: List[str]) -> bool:
|
|
84
|
+
return any(linestart for linestart in ignored_linestarts if line.startswith(linestart))
|
|
95
85
|
|
|
96
86
|
|
|
97
87
|
def check_diff_line_matches_pattern(line: str, patterns: List[Pattern]) -> bool:
|
|
@@ -104,9 +94,7 @@ def check_diff(
|
|
|
104
94
|
return [
|
|
105
95
|
line
|
|
106
96
|
for line in lines
|
|
107
|
-
if not check_diff_line_starts_with_ignored_linestart(
|
|
108
|
-
line, ignored_linestarts
|
|
109
|
-
)
|
|
97
|
+
if not check_diff_line_starts_with_ignored_linestart(line, ignored_linestarts)
|
|
110
98
|
and not check_diff_line_matches_pattern(line, patterns)
|
|
111
99
|
]
|
|
112
100
|
|
|
@@ -121,10 +109,7 @@ def read_ignored_linestarts(path: Path) -> List[str]:
|
|
|
121
109
|
|
|
122
110
|
def read_patterns(path: Path) -> List[Pattern]:
|
|
123
111
|
with open(path, "r", encoding="UTF-8") as file:
|
|
124
|
-
return [
|
|
125
|
-
re.compile(pattern.removesuffix("\n"))
|
|
126
|
-
for pattern in file.readlines()
|
|
127
|
-
]
|
|
112
|
+
return [re.compile(pattern.removesuffix("\n")) for pattern in file.readlines()]
|
|
128
113
|
|
|
129
114
|
|
|
130
115
|
def main() -> int:
|
|
@@ -140,9 +125,7 @@ def main() -> int:
|
|
|
140
125
|
|
|
141
126
|
diff = repo.git.diff(target, merge_base, unified=0)
|
|
142
127
|
|
|
143
|
-
result = check_diff(
|
|
144
|
-
diff.splitlines(), arguments.ignored_linestarts, patterns
|
|
145
|
-
)
|
|
128
|
+
result = check_diff(diff.splitlines(), arguments.ignored_linestarts, patterns)
|
|
146
129
|
|
|
147
130
|
if result:
|
|
148
131
|
print("The following lines don't match the any pattern:")
|
|
@@ -61,9 +61,7 @@ def parse_arguments() -> Namespace:
|
|
|
61
61
|
return args
|
|
62
62
|
|
|
63
63
|
|
|
64
|
-
def check_changed_creation_date(
|
|
65
|
-
commit_range: str, nasl_files: list[Path]
|
|
66
|
-
) -> bool:
|
|
64
|
+
def check_changed_creation_date(commit_range: str, nasl_files: list[Path]) -> bool:
|
|
67
65
|
"""
|
|
68
66
|
This script checks (via git diff) if the creation date of
|
|
69
67
|
passed VTs has changed, which is not allowed.
|
|
@@ -90,9 +88,7 @@ def check_changed_creation_date(
|
|
|
90
88
|
text,
|
|
91
89
|
re.MULTILINE,
|
|
92
90
|
)
|
|
93
|
-
if not creation_date_added or not (
|
|
94
|
-
added := creation_date_added.group("creation_date")
|
|
95
|
-
):
|
|
91
|
+
if not creation_date_added or not (added := creation_date_added.group("creation_date")):
|
|
96
92
|
continue
|
|
97
93
|
|
|
98
94
|
creation_date_removed = re.search(
|
|
@@ -125,9 +121,7 @@ def main() -> int:
|
|
|
125
121
|
git_base = git("rev-parse", "--show-toplevel")
|
|
126
122
|
os.chdir(git_base.rstrip("\n"))
|
|
127
123
|
except subprocess.SubprocessError:
|
|
128
|
-
logger.error(
|
|
129
|
-
"Your current working directory doesn't belong to a git repository"
|
|
130
|
-
)
|
|
124
|
+
logger.error("Your current working directory doesn't belong to a git repository")
|
|
131
125
|
return 1
|
|
132
126
|
|
|
133
127
|
args = parse_arguments()
|
|
@@ -12,9 +12,7 @@ from troubadix.standalone_plugins.common import get_merge_base, git
|
|
|
12
12
|
CVE_PATTERN = re.compile(r"CVE-\d{4}-\d{4,}")
|
|
13
13
|
|
|
14
14
|
|
|
15
|
-
def compare(
|
|
16
|
-
old_content: str, current_content: str
|
|
17
|
-
) -> Tuple[List[str], List[str]]:
|
|
15
|
+
def compare(old_content: str, current_content: str) -> Tuple[List[str], List[str]]:
|
|
18
16
|
old_cves = get_cves_from_content(old_content)
|
|
19
17
|
current_cves = get_cves_from_content(current_content)
|
|
20
18
|
|
|
@@ -25,9 +23,7 @@ def compare(
|
|
|
25
23
|
|
|
26
24
|
|
|
27
25
|
def get_cves_from_content(content: str) -> Set[str]:
|
|
28
|
-
pattern = _get_special_script_tag_pattern(
|
|
29
|
-
name="cve_id", flags=re.MULTILINE | re.DOTALL
|
|
30
|
-
)
|
|
26
|
+
pattern = _get_special_script_tag_pattern(name="cve_id", flags=re.MULTILINE | re.DOTALL)
|
|
31
27
|
match = pattern.search(content)
|
|
32
28
|
if not match:
|
|
33
29
|
return set()
|
|
@@ -72,18 +68,14 @@ def main():
|
|
|
72
68
|
args = parse_args()
|
|
73
69
|
terminal = ConsoleTerminal()
|
|
74
70
|
|
|
75
|
-
terminal.info(
|
|
76
|
-
f"Checking {len(args.files)} file(s) from {args.start_commit} to HEAD"
|
|
77
|
-
)
|
|
71
|
+
terminal.info(f"Checking {len(args.files)} file(s) from {args.start_commit} to HEAD")
|
|
78
72
|
|
|
79
73
|
for file in args.files:
|
|
80
74
|
try:
|
|
81
75
|
old_content = git("show", f"{args.start_commit}:{file}")
|
|
82
76
|
current_content = git("show", f"HEAD:{file}")
|
|
83
77
|
except CalledProcessError:
|
|
84
|
-
terminal.error(
|
|
85
|
-
f"Could not find {file} at {args.start_commit} or HEAD"
|
|
86
|
-
)
|
|
78
|
+
terminal.error(f"Could not find {file} at {args.start_commit} or HEAD")
|
|
87
79
|
continue
|
|
88
80
|
|
|
89
81
|
missing_cves, added_cves = compare(old_content, current_content)
|
|
@@ -69,9 +69,7 @@ def check_oid(args: Namespace) -> bool:
|
|
|
69
69
|
if not args.files:
|
|
70
70
|
args.files += [
|
|
71
71
|
Path(f)
|
|
72
|
-
for f in git(
|
|
73
|
-
"diff", "--name-only", "--diff-filter=d", args.commit_range
|
|
74
|
-
).splitlines()
|
|
72
|
+
for f in git("diff", "--name-only", "--diff-filter=d", args.commit_range).splitlines()
|
|
75
73
|
]
|
|
76
74
|
|
|
77
75
|
rcode = False
|
|
@@ -125,9 +123,7 @@ def main() -> int:
|
|
|
125
123
|
git_base = git("rev-parse", "--show-toplevel")
|
|
126
124
|
os.chdir(git_base.rstrip("\n"))
|
|
127
125
|
except subprocess.SubprocessError:
|
|
128
|
-
print(
|
|
129
|
-
"Your current working directory doesn't belong to a git repository"
|
|
130
|
-
)
|
|
126
|
+
print("Your current working directory doesn't belong to a git repository")
|
|
131
127
|
return 1
|
|
132
128
|
|
|
133
129
|
if check_oid(parse_args(args)):
|
|
@@ -64,8 +64,7 @@ def filter_reasons(packages: List[Package], reasons: Iterable[Reasons]):
|
|
|
64
64
|
return [
|
|
65
65
|
package
|
|
66
66
|
for package in packages
|
|
67
|
-
if not package.reasons
|
|
68
|
-
or any([reason not in reasons for reason in package.reasons])
|
|
67
|
+
if not package.reasons or any([reason not in reasons for reason in package.reasons])
|
|
69
68
|
]
|
|
70
69
|
|
|
71
70
|
|
|
@@ -154,9 +153,7 @@ def main():
|
|
|
154
153
|
hide_reasons = set(args.hide_reasons)
|
|
155
154
|
terminal = ConsoleTerminal()
|
|
156
155
|
|
|
157
|
-
terminal.info(
|
|
158
|
-
f"Checking {len(args.files)} file(s) from {args.start_commit} to HEAD"
|
|
159
|
-
)
|
|
156
|
+
terminal.info(f"Checking {len(args.files)} file(s) from {args.start_commit} to HEAD")
|
|
160
157
|
|
|
161
158
|
for file in args.files:
|
|
162
159
|
try:
|
|
@@ -164,9 +161,7 @@ def main():
|
|
|
164
161
|
content = git("show", f"HEAD:{file}")
|
|
165
162
|
missing_packages, new_packages = compare(old_content, content)
|
|
166
163
|
except CalledProcessError:
|
|
167
|
-
terminal.error(
|
|
168
|
-
f"Could not find {file} at {args.start_commit} or HEAD"
|
|
169
|
-
)
|
|
164
|
+
terminal.error(f"Could not find {file} at {args.start_commit} or HEAD")
|
|
170
165
|
continue
|
|
171
166
|
except ValueError as e:
|
|
172
167
|
terminal.error(f"Error while handling {file}: {e}")
|
|
@@ -43,9 +43,7 @@ class ChangedUpdate(Marker):
|
|
|
43
43
|
old_package
|
|
44
44
|
for old_package in missing_packages
|
|
45
45
|
if package.name == old_package.name
|
|
46
|
-
and old_package.version.startswith(
|
|
47
|
-
package.version.replace(suffix, "")
|
|
48
|
-
)
|
|
46
|
+
and old_package.version.startswith(package.version.replace(suffix, ""))
|
|
49
47
|
and package.release == old_package.release
|
|
50
48
|
),
|
|
51
49
|
None,
|
|
@@ -46,6 +46,4 @@ class DroppedArchitecture(Marker):
|
|
|
46
46
|
continue
|
|
47
47
|
|
|
48
48
|
package.reasons[Reasons.DROPPED_ARCHITECTURE] = Direction.PASSIVE
|
|
49
|
-
other_package.reasons[Reasons.DROPPED_ARCHITECTURE] =
|
|
50
|
-
Direction.ACTIVE
|
|
51
|
-
)
|
|
49
|
+
other_package.reasons[Reasons.DROPPED_ARCHITECTURE] = Direction.ACTIVE
|
|
@@ -42,9 +42,7 @@ class Reasons(str, Enum):
|
|
|
42
42
|
try:
|
|
43
43
|
return cls[cli_argument.upper().replace("-", "_")]
|
|
44
44
|
except KeyError as error:
|
|
45
|
-
raise ArgumentError(
|
|
46
|
-
None, f"Invalid reason '{cli_argument}'"
|
|
47
|
-
) from error
|
|
45
|
+
raise ArgumentError(None, f"Invalid reason '{cli_argument}'") from error
|
|
48
46
|
|
|
49
47
|
|
|
50
48
|
@dataclass()
|
|
@@ -80,8 +78,7 @@ class Package:
|
|
|
80
78
|
result = f"{self.name : <50} {self.version : <40} {self.release : <10}"
|
|
81
79
|
|
|
82
80
|
reasons = ", ".join(
|
|
83
|
-
f"{change}"
|
|
84
|
-
f"{' in new package' if direction == Direction.PASSIVE else ''}"
|
|
81
|
+
f"{change}" f"{' in new package' if direction == Direction.PASSIVE else ''}"
|
|
85
82
|
for change, direction in self.reasons.items()
|
|
86
83
|
)
|
|
87
84
|
result += f"{reasons : <10}"
|
|
@@ -23,28 +23,21 @@ def check_duplicates(scripts: list[Script]) -> Result:
|
|
|
23
23
|
return Result(name="duplicate dependency", warnings=warnings)
|
|
24
24
|
|
|
25
25
|
|
|
26
|
-
def check_missing_dependencies(
|
|
27
|
-
scripts: list[Script], graph: nx.DiGraph
|
|
28
|
-
) -> Result:
|
|
26
|
+
def check_missing_dependencies(scripts: list[Script], graph: nx.DiGraph) -> Result:
|
|
29
27
|
"""
|
|
30
28
|
Checks if any scripts that are depended on are missing from
|
|
31
29
|
the list of scripts created from the local file system,
|
|
32
30
|
logs the scripts dependending on the missing script
|
|
33
31
|
"""
|
|
34
32
|
errors = []
|
|
35
|
-
dependency_names = {
|
|
36
|
-
dep.name for script in scripts for dep in script.dependencies
|
|
37
|
-
}
|
|
33
|
+
dependency_names = {dep.name for script in scripts for dep in script.dependencies}
|
|
38
34
|
script_names = {script.name for script in scripts}
|
|
39
35
|
missing_dependencies = dependency_names - script_names
|
|
40
36
|
|
|
41
37
|
for missing in missing_dependencies:
|
|
42
38
|
depending_scripts = graph.predecessors(missing)
|
|
43
39
|
errors.append(
|
|
44
|
-
f"{missing}:"
|
|
45
|
-
+ "".join(
|
|
46
|
-
f"\n - used by: {script}" for script in depending_scripts
|
|
47
|
-
)
|
|
40
|
+
f"{missing}:" + "".join(f"\n - used by: {script}" for script in depending_scripts)
|
|
48
41
|
)
|
|
49
42
|
|
|
50
43
|
return Result(name="missing dependency", errors=errors)
|
|
@@ -63,9 +56,7 @@ def check_cycles(graph) -> Result:
|
|
|
63
56
|
return Result(name="cyclic dependency", errors=errors)
|
|
64
57
|
|
|
65
58
|
|
|
66
|
-
def cross_feed_dependencies(
|
|
67
|
-
graph, is_enterprise_checked: bool
|
|
68
|
-
) -> list[tuple[str, str]]:
|
|
59
|
+
def cross_feed_dependencies(graph, is_enterprise_checked: bool) -> list[tuple[str, str]]:
|
|
69
60
|
"""
|
|
70
61
|
creates a list of script and dependency for scripts
|
|
71
62
|
in community feed that depend on scripts in enterprise folders
|
|
@@ -105,8 +96,7 @@ def check_category_order(graph) -> Result:
|
|
|
105
96
|
problematic_edges = [
|
|
106
97
|
(dependent, dependency)
|
|
107
98
|
for dependent, dependency in graph.edges()
|
|
108
|
-
if graph.nodes[dependent]["category"]
|
|
109
|
-
< graph.nodes[dependency].get("category", -1)
|
|
99
|
+
if graph.nodes[dependent]["category"] < graph.nodes[dependency].get("category", -1)
|
|
110
100
|
]
|
|
111
101
|
|
|
112
102
|
errors = [
|
|
@@ -34,9 +34,7 @@ from .checks import (
|
|
|
34
34
|
from .cli import Feed, parse_args
|
|
35
35
|
from .models import Dependency, Result, Script
|
|
36
36
|
|
|
37
|
-
DEPENDENCY_PATTERN = _get_special_script_tag_pattern(
|
|
38
|
-
"dependencies", flags=re.DOTALL | re.MULTILINE
|
|
39
|
-
)
|
|
37
|
+
DEPENDENCY_PATTERN = _get_special_script_tag_pattern("dependencies", flags=re.DOTALL | re.MULTILINE)
|
|
40
38
|
CATEGORY_PATTERN = get_special_script_tag_pattern(SpecialScriptTag.CATEGORY)
|
|
41
39
|
DEPRECATED_PATTERN = get_script_tag_pattern(ScriptTag.DEPRECATED)
|
|
42
40
|
ENTERPRISE_FEED_CHECK_PATTERN = re.compile(
|
|
@@ -84,9 +82,7 @@ def get_scripts(directory: Path) -> list[Script]:
|
|
|
84
82
|
dependencies = extract_dependencies(content)
|
|
85
83
|
category = extract_category(content)
|
|
86
84
|
deprecated = bool(DEPRECATED_PATTERN.search(content))
|
|
87
|
-
scripts.append(
|
|
88
|
-
Script(name, feed, dependencies, category, deprecated)
|
|
89
|
-
)
|
|
85
|
+
scripts.append(Script(name, feed, dependencies, category, deprecated))
|
|
90
86
|
except Exception as e:
|
|
91
87
|
logger.error(f"Error processing {path}: {e}")
|
|
92
88
|
|
|
@@ -105,20 +101,16 @@ def extract_dependencies(content: str) -> list[Dependency]:
|
|
|
105
101
|
dependencies = []
|
|
106
102
|
|
|
107
103
|
if_blocks = [
|
|
108
|
-
(match.start(), match.end())
|
|
109
|
-
for match in ENTERPRISE_FEED_CHECK_PATTERN.finditer(content)
|
|
104
|
+
(match.start(), match.end()) for match in ENTERPRISE_FEED_CHECK_PATTERN.finditer(content)
|
|
110
105
|
]
|
|
111
106
|
|
|
112
107
|
for match in DEPENDENCY_PATTERN.finditer(content):
|
|
113
108
|
start, end = match.span()
|
|
114
109
|
is_enterprise_feed = any(
|
|
115
|
-
start >= block_start and end <= block_end
|
|
116
|
-
for block_start, block_end in if_blocks
|
|
110
|
+
start >= block_start and end <= block_end for block_start, block_end in if_blocks
|
|
117
111
|
)
|
|
118
112
|
dep_list = split_dependencies(match.group("value"))
|
|
119
|
-
dependencies.extend(
|
|
120
|
-
Dependency(dep, is_enterprise_feed) for dep in dep_list
|
|
121
|
-
)
|
|
113
|
+
dependencies.extend(Dependency(dep, is_enterprise_feed) for dep in dep_list)
|
|
122
114
|
|
|
123
115
|
return dependencies
|
|
124
116
|
|
|
@@ -42,9 +42,7 @@ KB_ITEMS_PATTERN = re.compile(r"set_kb_item\(.+\);")
|
|
|
42
42
|
|
|
43
43
|
|
|
44
44
|
def load_transition_oid_mapping(transition_file: Path) -> dict[str, str]:
|
|
45
|
-
spec = importlib.util.spec_from_file_location(
|
|
46
|
-
"transition_layer", transition_file
|
|
47
|
-
)
|
|
45
|
+
spec = importlib.util.spec_from_file_location("transition_layer", transition_file)
|
|
48
46
|
transition_layer = importlib.util.module_from_spec(spec)
|
|
49
47
|
spec.loader.exec_module(transition_layer)
|
|
50
48
|
|
|
@@ -151,9 +149,7 @@ def find_replacement_oid(
|
|
|
151
149
|
file.content,
|
|
152
150
|
)
|
|
153
151
|
if not oid_match:
|
|
154
|
-
raise ValueError(
|
|
155
|
-
f"No OID found in {file.name}. Cannot map to replacement OID."
|
|
156
|
-
)
|
|
152
|
+
raise ValueError(f"No OID found in {file.name}. Cannot map to replacement OID.")
|
|
157
153
|
oid = oid_match.group("value")
|
|
158
154
|
replacement_oid = oid_mapping.get(oid)
|
|
159
155
|
if not replacement_oid:
|
|
@@ -181,9 +177,7 @@ def deprecate(
|
|
|
181
177
|
output_path.mkdir(parents=True, exist_ok=True)
|
|
182
178
|
for file in to_deprecate:
|
|
183
179
|
if re.findall(KB_ITEMS_PATTERN, file.content):
|
|
184
|
-
logger.warning(
|
|
185
|
-
f"Unable to deprecate {file.name}. There are still KB keys remaining."
|
|
186
|
-
)
|
|
180
|
+
logger.warning(f"Unable to deprecate {file.name}. There are still KB keys remaining.")
|
|
187
181
|
continue
|
|
188
182
|
|
|
189
183
|
replacement_oid = find_replacement_oid(file, oid_mapping)
|
|
@@ -19,9 +19,7 @@ def parse_args() -> Namespace:
|
|
|
19
19
|
type=directory_type_existing,
|
|
20
20
|
help="directory that should be linted",
|
|
21
21
|
)
|
|
22
|
-
parser.add_argument(
|
|
23
|
-
"--ignore-file", type=file_type_existing, help="path to ignore file"
|
|
24
|
-
)
|
|
22
|
+
parser.add_argument("--ignore-file", type=file_type_existing, help="path to ignore file")
|
|
25
23
|
parser.add_argument(
|
|
26
24
|
"--gen-ignore-entries",
|
|
27
25
|
action="store_true",
|
|
@@ -35,9 +33,7 @@ def create_exclusions(ignore_file: Path) -> set[Path]:
|
|
|
35
33
|
return set()
|
|
36
34
|
|
|
37
35
|
with open(ignore_file, "r", encoding="utf-8") as file:
|
|
38
|
-
return {
|
|
39
|
-
Path(line.strip()) for line in file if not re.match(r"^\s*#", line)
|
|
40
|
-
}
|
|
36
|
+
return {Path(line.strip()) for line in file if not re.match(r"^\s*#", line)}
|
|
41
37
|
|
|
42
38
|
|
|
43
39
|
def check_extensions(args: Namespace) -> List[Path]:
|
|
@@ -77,10 +73,7 @@ def main() -> int:
|
|
|
77
73
|
print(file.relative_to(args.dir))
|
|
78
74
|
return 0
|
|
79
75
|
|
|
80
|
-
print(
|
|
81
|
-
f"{len(unwanted_files)} "
|
|
82
|
-
"Files with unwanted file extension were found:"
|
|
83
|
-
)
|
|
76
|
+
print(f"{len(unwanted_files)} " "Files with unwanted file extension were found:")
|
|
84
77
|
for file in unwanted_files:
|
|
85
78
|
print(file)
|
|
86
79
|
return 1
|
|
@@ -48,9 +48,7 @@ def update(nasl_file: Path, terminal: Terminal):
|
|
|
48
48
|
)
|
|
49
49
|
|
|
50
50
|
if not match_last_modification_any_value:
|
|
51
|
-
terminal.warning(
|
|
52
|
-
f'Ignoring "{nasl_file}" because it is missing a last_modification tag.'
|
|
53
|
-
)
|
|
51
|
+
terminal.warning(f'Ignoring "{nasl_file}" because it is missing a last_modification tag.')
|
|
54
52
|
return
|
|
55
53
|
|
|
56
54
|
now = datetime.datetime.now(datetime.timezone.utc)
|
|
@@ -71,9 +69,7 @@ def update(nasl_file: Path, terminal: Terminal):
|
|
|
71
69
|
string=file_content,
|
|
72
70
|
)
|
|
73
71
|
if not match_script_version:
|
|
74
|
-
terminal.warning(
|
|
75
|
-
f'Ignoring "{nasl_file}" because it is missing a script_version.'
|
|
76
|
-
)
|
|
72
|
+
terminal.warning(f'Ignoring "{nasl_file}" because it is missing a script_version.')
|
|
77
73
|
return
|
|
78
74
|
|
|
79
75
|
# get that date formatted correctly:
|
|
@@ -89,9 +85,7 @@ def update(nasl_file: Path, terminal: Terminal):
|
|
|
89
85
|
|
|
90
86
|
|
|
91
87
|
def parse_args(args: Sequence[str] = None) -> Namespace:
|
|
92
|
-
parser = ArgumentParser(
|
|
93
|
-
description="Update script_version and last_modification tags"
|
|
94
|
-
)
|
|
88
|
+
parser = ArgumentParser(description="Update script_version and last_modification tags")
|
|
95
89
|
what_group = parser.add_mutually_exclusive_group(required=True)
|
|
96
90
|
what_group.add_argument(
|
|
97
91
|
"--files",
|