RepoAuditor 0.2.21__tar.gz → 0.2.23__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.
- {repoauditor-0.2.21 → repoauditor-0.2.23}/PKG-INFO +1 -1
- {repoauditor-0.2.21 → repoauditor-0.2.23}/pyproject.toml +2 -2
- {repoauditor-0.2.21 → repoauditor-0.2.23}/src/RepoAuditor/CommandLineProcessor.py +128 -63
- repoauditor-0.2.23/src/RepoAuditor/Display.py +165 -0
- {repoauditor-0.2.21 → repoauditor-0.2.23}/src/RepoAuditor/EntryPoint.py +1 -1
- {repoauditor-0.2.21 → repoauditor-0.2.23}/src/RepoAuditor/ExecuteModules.py +73 -177
- {repoauditor-0.2.21 → repoauditor-0.2.23}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionQuery.py +54 -51
- repoauditor-0.2.23/src/RepoAuditor/Plugins/GitHub/StandardQuery.py +248 -0
- {repoauditor-0.2.21 → repoauditor-0.2.23}/src/RepoAuditor/__init__.py +1 -1
- {repoauditor-0.2.21 → repoauditor-0.2.23}/tests/ExecuteModules_UnitTest.py +1 -0
- {repoauditor-0.2.21 → repoauditor-0.2.23}/tests/Plugins/GitHub_EndToEndTest.py +2 -31
- {repoauditor-0.2.21 → repoauditor-0.2.23}/tests/Plugins/utilities.py +36 -2
- repoauditor-0.2.21/src/RepoAuditor/Plugins/GitHub/StandardQuery.py +0 -245
- {repoauditor-0.2.21 → repoauditor-0.2.23}/.copier-answers.yml +0 -0
- {repoauditor-0.2.21 → repoauditor-0.2.23}/.github/CODEOWNERS +0 -0
- {repoauditor-0.2.21 → repoauditor-0.2.23}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {repoauditor-0.2.21 → repoauditor-0.2.23}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {repoauditor-0.2.21 → repoauditor-0.2.23}/.github/ISSUE_TEMPLATE/custom.md +0 -0
- {repoauditor-0.2.21 → repoauditor-0.2.23}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {repoauditor-0.2.21 → repoauditor-0.2.23}/.github/actions/release_impl/action.yml +0 -0
- {repoauditor-0.2.21 → repoauditor-0.2.23}/.github/pull_request_template.md +0 -0
- {repoauditor-0.2.21 → repoauditor-0.2.23}/.github/release_sources.yaml +0 -0
- {repoauditor-0.2.21 → repoauditor-0.2.23}/.github/workflows/CICD.yml +0 -0
- {repoauditor-0.2.21 → repoauditor-0.2.23}/.github/workflows/CICD_impl.yml +0 -0
- {repoauditor-0.2.21 → repoauditor-0.2.23}/.github/workflows/codeql.yml +0 -0
- {repoauditor-0.2.21 → repoauditor-0.2.23}/.gitignore +0 -0
- {repoauditor-0.2.21 → repoauditor-0.2.23}/.pre-commit-config.yaml +0 -0
- {repoauditor-0.2.21 → repoauditor-0.2.23}/.python-version +0 -0
- {repoauditor-0.2.21 → repoauditor-0.2.23}/CODE_OF_CONDUCT.md +0 -0
- {repoauditor-0.2.21 → repoauditor-0.2.23}/CONTRIBUTING.md +0 -0
- {repoauditor-0.2.21 → repoauditor-0.2.23}/DEVELOPMENT.md +0 -0
- {repoauditor-0.2.21 → repoauditor-0.2.23}/GOVERNANCE.md +0 -0
- {repoauditor-0.2.21 → repoauditor-0.2.23}/LICENSE +0 -0
- {repoauditor-0.2.21 → repoauditor-0.2.23}/MAINTAINERS.md +0 -0
- {repoauditor-0.2.21 → repoauditor-0.2.23}/README.md +0 -0
- {repoauditor-0.2.21 → repoauditor-0.2.23}/SECURITY.md +0 -0
- {repoauditor-0.2.21 → repoauditor-0.2.23}/minisign_key.pub +0 -0
- {repoauditor-0.2.21 → repoauditor-0.2.23}/src/AutoGitSemVer.yaml +0 -0
- {repoauditor-0.2.21 → repoauditor-0.2.23}/src/RepoAuditor/Impl/ParallelSequentialProcessor.py +0 -0
- {repoauditor-0.2.21 → repoauditor-0.2.23}/src/RepoAuditor/Impl/__init__.py +0 -0
- {repoauditor-0.2.21 → repoauditor-0.2.23}/src/RepoAuditor/Module.py +0 -0
- {repoauditor-0.2.21 → repoauditor-0.2.23}/src/RepoAuditor/Plugin.py +0 -0
- {repoauditor-0.2.21 → repoauditor-0.2.23}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/AllowDeletions.py +0 -0
- {repoauditor-0.2.21 → repoauditor-0.2.23}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/AllowForcePushes.py +0 -0
- {repoauditor-0.2.21 → repoauditor-0.2.23}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/DismissStalePullRequestApprovals.py +0 -0
- {repoauditor-0.2.21 → repoauditor-0.2.23}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/DoNotAllowBypassSettings.py +0 -0
- {repoauditor-0.2.21 → repoauditor-0.2.23}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/EnsureStatusChecks.py +0 -0
- {repoauditor-0.2.21 → repoauditor-0.2.23}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/Impl/ClassicEnableRequirementImpl.py +0 -0
- {repoauditor-0.2.21 → repoauditor-0.2.23}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/Impl/ClassicValueRequirementImpl.py +0 -0
- {repoauditor-0.2.21 → repoauditor-0.2.23}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/Impl/__init__.py +0 -0
- {repoauditor-0.2.21 → repoauditor-0.2.23}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/RequireApprovalMostRecentPush.py +0 -0
- {repoauditor-0.2.21 → repoauditor-0.2.23}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/RequireApprovals.py +0 -0
- {repoauditor-0.2.21 → repoauditor-0.2.23}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/RequireCodeOwnerReview.py +0 -0
- {repoauditor-0.2.21 → repoauditor-0.2.23}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/RequireConversationResolution.py +0 -0
- {repoauditor-0.2.21 → repoauditor-0.2.23}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/RequireLinearHistory.py +0 -0
- {repoauditor-0.2.21 → repoauditor-0.2.23}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/RequirePullRequests.py +0 -0
- {repoauditor-0.2.21 → repoauditor-0.2.23}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/RequireSignedCommits.py +0 -0
- {repoauditor-0.2.21 → repoauditor-0.2.23}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/RequireStatusChecksToPass.py +0 -0
- {repoauditor-0.2.21 → repoauditor-0.2.23}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/RequireUpToDateBranches.py +0 -0
- {repoauditor-0.2.21 → repoauditor-0.2.23}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/__init__.py +0 -0
- {repoauditor-0.2.21 → repoauditor-0.2.23}/src/RepoAuditor/Plugins/GitHub/DefaultBranchQuery.py +0 -0
- {repoauditor-0.2.21 → repoauditor-0.2.23}/src/RepoAuditor/Plugins/GitHub/DefaultBranchQueryRequirements/Protected.py +0 -0
- {repoauditor-0.2.21 → repoauditor-0.2.23}/src/RepoAuditor/Plugins/GitHub/DefaultBranchQueryRequirements/__init__.py +0 -0
- {repoauditor-0.2.21 → repoauditor-0.2.23}/src/RepoAuditor/Plugins/GitHub/Impl/Common.py +0 -0
- {repoauditor-0.2.21 → repoauditor-0.2.23}/src/RepoAuditor/Plugins/GitHub/Impl/EnableRequirementImpl.py +0 -0
- {repoauditor-0.2.21 → repoauditor-0.2.23}/src/RepoAuditor/Plugins/GitHub/Impl/ValueRequirementImpl.py +0 -0
- {repoauditor-0.2.21 → repoauditor-0.2.23}/src/RepoAuditor/Plugins/GitHub/Impl/__init__.py +0 -0
- {repoauditor-0.2.21 → repoauditor-0.2.23}/src/RepoAuditor/Plugins/GitHub/Module.py +0 -0
- {repoauditor-0.2.21 → repoauditor-0.2.23}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/AutoMerge.py +0 -0
- {repoauditor-0.2.21 → repoauditor-0.2.23}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/DefaultBranch.py +0 -0
- {repoauditor-0.2.21 → repoauditor-0.2.23}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/DeleteHeadBranches.py +0 -0
- {repoauditor-0.2.21 → repoauditor-0.2.23}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/DependabotSecurityUpdates.py +0 -0
- {repoauditor-0.2.21 → repoauditor-0.2.23}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/Description.py +0 -0
- {repoauditor-0.2.21 → repoauditor-0.2.23}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/Impl/StandardEnableRequirementImpl.py +0 -0
- {repoauditor-0.2.21 → repoauditor-0.2.23}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/Impl/StandardValueRequirementImpl.py +0 -0
- {repoauditor-0.2.21 → repoauditor-0.2.23}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/Impl/__init__.py +0 -0
- {repoauditor-0.2.21 → repoauditor-0.2.23}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/License.py +0 -0
- {repoauditor-0.2.21 → repoauditor-0.2.23}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/MergeCommit.py +0 -0
- {repoauditor-0.2.21 → repoauditor-0.2.23}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/MergeCommitMessage.py +0 -0
- {repoauditor-0.2.21 → repoauditor-0.2.23}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/Private.py +0 -0
- {repoauditor-0.2.21 → repoauditor-0.2.23}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/RebaseMergeCommit.py +0 -0
- {repoauditor-0.2.21 → repoauditor-0.2.23}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/SecretScanning.py +0 -0
- {repoauditor-0.2.21 → repoauditor-0.2.23}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/SecretScanningPushProtection.py +0 -0
- {repoauditor-0.2.21 → repoauditor-0.2.23}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/SquashCommitMerge.py +0 -0
- {repoauditor-0.2.21 → repoauditor-0.2.23}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/SquashMergeCommitMessage.py +0 -0
- {repoauditor-0.2.21 → repoauditor-0.2.23}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/SuggestUpdatingPullRequestBranches.py +0 -0
- {repoauditor-0.2.21 → repoauditor-0.2.23}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/SupportDiscussions.py +0 -0
- {repoauditor-0.2.21 → repoauditor-0.2.23}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/SupportIssues.py +0 -0
- {repoauditor-0.2.21 → repoauditor-0.2.23}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/SupportProjects.py +0 -0
- {repoauditor-0.2.21 → repoauditor-0.2.23}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/SupportWikis.py +0 -0
- {repoauditor-0.2.21 → repoauditor-0.2.23}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/TemplateRepository.py +0 -0
- {repoauditor-0.2.21 → repoauditor-0.2.23}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/WebCommitSignoff.py +0 -0
- {repoauditor-0.2.21 → repoauditor-0.2.23}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/__init__.py +0 -0
- {repoauditor-0.2.21 → repoauditor-0.2.23}/src/RepoAuditor/Plugins/GitHub/__init__.py +0 -0
- {repoauditor-0.2.21 → repoauditor-0.2.23}/src/RepoAuditor/Plugins/GitHubBase/Module.py +0 -0
- {repoauditor-0.2.21 → repoauditor-0.2.23}/src/RepoAuditor/Plugins/GitHubBase/__init__.py +0 -0
- {repoauditor-0.2.21 → repoauditor-0.2.23}/src/RepoAuditor/Plugins/GitHubCustomization/CustomizationQuery.py +0 -0
- {repoauditor-0.2.21 → repoauditor-0.2.23}/src/RepoAuditor/Plugins/GitHubCustomization/Module.py +0 -0
- {repoauditor-0.2.21 → repoauditor-0.2.23}/src/RepoAuditor/Plugins/GitHubCustomization/__init__.py +0 -0
- {repoauditor-0.2.21 → repoauditor-0.2.23}/src/RepoAuditor/Plugins/GitHubCustomizationPlugin.py +0 -0
- {repoauditor-0.2.21 → repoauditor-0.2.23}/src/RepoAuditor/Plugins/GitHubPlugin.py +0 -0
- {repoauditor-0.2.21 → repoauditor-0.2.23}/src/RepoAuditor/Plugins/__init__.py +0 -0
- {repoauditor-0.2.21 → repoauditor-0.2.23}/src/RepoAuditor/Query.py +0 -0
- {repoauditor-0.2.21 → repoauditor-0.2.23}/src/RepoAuditor/Requirement.py +0 -0
- {repoauditor-0.2.21 → repoauditor-0.2.23}/src/RepoAuditor/py.typed +0 -0
- {repoauditor-0.2.21 → repoauditor-0.2.23}/tests/CommandLineProcessor_UnitTest.py +0 -0
- {repoauditor-0.2.21 → repoauditor-0.2.23}/tests/EntryPoint_UnitTest.py +0 -0
- {repoauditor-0.2.21 → repoauditor-0.2.23}/tests/Module_UnitTest.py +0 -0
- {repoauditor-0.2.21 → repoauditor-0.2.23}/tests/Plugin_UnitTest.py +0 -0
- {repoauditor-0.2.21 → repoauditor-0.2.23}/tests/Plugins/GitHubCustomization_UnitTest.py +0 -0
- {repoauditor-0.2.21 → repoauditor-0.2.23}/tests/Plugins/GitHubModule_UnitTest.py +0 -0
- {repoauditor-0.2.21 → repoauditor-0.2.23}/tests/Plugins/__snapshots__/GitHub_EndToEndTest.ambr +0 -0
- {repoauditor-0.2.21 → repoauditor-0.2.23}/tests/Query_UnitTest.py +0 -0
- {repoauditor-0.2.21 → repoauditor-0.2.23}/tests/Requirement_UnitTest.py +0 -0
- {repoauditor-0.2.21 → repoauditor-0.2.23}/tests/__snapshots__/ExecuteModules_UnitTest.ambr +0 -0
- {repoauditor-0.2.21 → repoauditor-0.2.23}/uv.lock +0 -0
|
@@ -76,7 +76,7 @@ exclude = ["tests/**"]
|
|
|
76
76
|
# ...however, we current experience failures in the rulesets commented out below.
|
|
77
77
|
select = [
|
|
78
78
|
"AIR",
|
|
79
|
-
|
|
79
|
+
"ERA",
|
|
80
80
|
"FAST",
|
|
81
81
|
"YTT",
|
|
82
82
|
"ANN",
|
|
@@ -119,7 +119,7 @@ select = [
|
|
|
119
119
|
"PTH",
|
|
120
120
|
"FLY",
|
|
121
121
|
"I",
|
|
122
|
-
|
|
122
|
+
"C90",
|
|
123
123
|
"NPY",
|
|
124
124
|
"PD",
|
|
125
125
|
"N",
|
|
@@ -36,38 +36,15 @@ class CommandLineProcessor:
|
|
|
36
36
|
], # actual type is dict[str, TyperEx.TypeDefinitionItemType]
|
|
37
37
|
) -> dict[str, Any]: ...
|
|
38
38
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
# | Public Data
|
|
42
|
-
# |
|
|
43
|
-
# ----------------------------------------------------------------------
|
|
44
|
-
module_infos: list[ModuleInfo]
|
|
45
|
-
warnings_as_error_module_names: set[str]
|
|
46
|
-
ignore_warnings_module_names: set[str]
|
|
47
|
-
single_threaded: bool = field(kw_only=True)
|
|
48
|
-
|
|
49
|
-
# ----------------------------------------------------------------------
|
|
50
|
-
# |
|
|
51
|
-
# | Public Methods
|
|
52
|
-
# |
|
|
53
|
-
# ----------------------------------------------------------------------
|
|
54
|
-
@classmethod
|
|
55
|
-
def Create(
|
|
56
|
-
cls,
|
|
57
|
-
get_dynamic_args_func: "CommandLineProcessor.GetDynamicArgsFunc",
|
|
39
|
+
@staticmethod
|
|
40
|
+
def _GetModuleMap(
|
|
58
41
|
modules: list[Module],
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
ignore_all_warnings: bool = False,
|
|
66
|
-
single_threaded: bool = False,
|
|
67
|
-
argument_separator: str = "-",
|
|
68
|
-
) -> "CommandLineProcessor":
|
|
69
|
-
"""Factor method to construct a CommandLineProcessor object."""
|
|
70
|
-
# Convert modules into a lookup map
|
|
42
|
+
argument_separator: str,
|
|
43
|
+
) -> dict[str, Module]:
|
|
44
|
+
"""Convert modules into a lookup map.
|
|
45
|
+
|
|
46
|
+
Returns a dict of module names mapped to the corresponding module.
|
|
47
|
+
"""
|
|
71
48
|
module_map: dict[str, Module] = {}
|
|
72
49
|
|
|
73
50
|
for module in modules:
|
|
@@ -75,16 +52,26 @@ class CommandLineProcessor:
|
|
|
75
52
|
msg = f"The module name '{module.name}' contains '{argument_separator}', which should be used as an argument separator."
|
|
76
53
|
raise ValueError(msg)
|
|
77
54
|
|
|
78
|
-
|
|
79
|
-
if
|
|
55
|
+
prev_added_module = module_map.get(module.name, None)
|
|
56
|
+
if prev_added_module is not None:
|
|
80
57
|
msg = f"The module '{module.name}' has already been defined."
|
|
81
58
|
raise ValueError(msg)
|
|
82
59
|
|
|
83
60
|
module_map[module.name] = module
|
|
84
61
|
|
|
85
|
-
|
|
62
|
+
return module_map
|
|
86
63
|
|
|
87
|
-
|
|
64
|
+
@staticmethod
|
|
65
|
+
def _ProcessIncludes(
|
|
66
|
+
module_map: dict[str, Module],
|
|
67
|
+
includes: list[str],
|
|
68
|
+
argument_separator: str,
|
|
69
|
+
) -> tuple[set[str], dict[str, set[str]]]:
|
|
70
|
+
"""Process the modules and requirements to include.
|
|
71
|
+
|
|
72
|
+
Returns both the set of names of the included modules as well as
|
|
73
|
+
the dictionary of module names mapped to the set of included requirement names.
|
|
74
|
+
"""
|
|
88
75
|
included_modules: set[str] = set()
|
|
89
76
|
included_requirements: dict[str, set[str]] = {}
|
|
90
77
|
|
|
@@ -103,16 +90,19 @@ class CommandLineProcessor:
|
|
|
103
90
|
argument_separator.join(parts[1:])
|
|
104
91
|
)
|
|
105
92
|
|
|
106
|
-
|
|
93
|
+
return included_modules, included_requirements
|
|
107
94
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
95
|
+
@staticmethod
|
|
96
|
+
def _ProcessExcludes(
|
|
97
|
+
module_map: dict[str, Module],
|
|
98
|
+
excludes: list[str],
|
|
99
|
+
argument_separator: str,
|
|
100
|
+
) -> dict[str, set[str]]:
|
|
101
|
+
"""Process the modules and requirements to exclude.
|
|
114
102
|
|
|
115
|
-
|
|
103
|
+
Returns both the set of names of the excluded modules as well as
|
|
104
|
+
the dictionary of module names mapped to the set of excluded requirement names.
|
|
105
|
+
"""
|
|
116
106
|
excluded_requirements: dict[str, set[str]] = {}
|
|
117
107
|
|
|
118
108
|
for exclude in excludes:
|
|
@@ -130,27 +120,20 @@ class CommandLineProcessor:
|
|
|
130
120
|
argument_separator.join(parts[1:])
|
|
131
121
|
)
|
|
132
122
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
# Add / Remove the requirements for each module
|
|
136
|
-
for module_name, module in list(module_map.items()):
|
|
137
|
-
module.ProcessRequirements(
|
|
138
|
-
included_requirements.get(module_name, set()),
|
|
139
|
-
excluded_requirements.get(module_name, set()),
|
|
140
|
-
)
|
|
123
|
+
return excluded_requirements
|
|
141
124
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
warnings_as_error_module_names = {module.name for module in module_map.values()}
|
|
150
|
-
if ignore_all_warnings:
|
|
151
|
-
ignore_warnings_module_names = {module.name for module in module_map.values()}
|
|
125
|
+
@staticmethod
|
|
126
|
+
def _ProcessDynamicArguments(
|
|
127
|
+
module_map: dict[str, Module],
|
|
128
|
+
argument_separator: str,
|
|
129
|
+
get_dynamic_args_func: "CommandLineProcessor.GetDynamicArgsFunc",
|
|
130
|
+
) -> dict[str, dict[str, Any]]:
|
|
131
|
+
"""Process the passed in dynamic arguments.
|
|
152
132
|
|
|
153
|
-
|
|
133
|
+
Returns a dictionary of module names to a corresponding dictionary
|
|
134
|
+
of argument names to values.
|
|
135
|
+
"""
|
|
136
|
+
# First we create the type definitions
|
|
154
137
|
dynamic_arg_definitions: dict[str, Any] = {}
|
|
155
138
|
|
|
156
139
|
for module in module_map.values():
|
|
@@ -166,7 +149,7 @@ class CommandLineProcessor:
|
|
|
166
149
|
f"{module.name}{argument_separator}{requirement.name}{argument_separator}{key}"
|
|
167
150
|
] = value
|
|
168
151
|
|
|
169
|
-
#
|
|
152
|
+
# Now we process the definitions to get the dynamic arguments
|
|
170
153
|
dynamic_args: dict[str, dict[str, Any]] = {}
|
|
171
154
|
|
|
172
155
|
for key, value in get_dynamic_args_func(dynamic_arg_definitions).items():
|
|
@@ -185,6 +168,88 @@ class CommandLineProcessor:
|
|
|
185
168
|
{},
|
|
186
169
|
)[argument_separator.join(parts[2:])] = value
|
|
187
170
|
|
|
171
|
+
return dynamic_args
|
|
172
|
+
|
|
173
|
+
# ----------------------------------------------------------------------
|
|
174
|
+
# |
|
|
175
|
+
# | Public Data
|
|
176
|
+
# |
|
|
177
|
+
# ----------------------------------------------------------------------
|
|
178
|
+
module_infos: list[ModuleInfo]
|
|
179
|
+
warnings_as_error_module_names: set[str]
|
|
180
|
+
ignore_warnings_module_names: set[str]
|
|
181
|
+
single_threaded: bool = field(kw_only=True)
|
|
182
|
+
|
|
183
|
+
# ----------------------------------------------------------------------
|
|
184
|
+
# |
|
|
185
|
+
# | Public Methods
|
|
186
|
+
# |
|
|
187
|
+
# ----------------------------------------------------------------------
|
|
188
|
+
@classmethod
|
|
189
|
+
def Create(
|
|
190
|
+
cls,
|
|
191
|
+
get_dynamic_args_func: "CommandLineProcessor.GetDynamicArgsFunc",
|
|
192
|
+
modules: list[Module],
|
|
193
|
+
includes: list[str],
|
|
194
|
+
excludes: list[str],
|
|
195
|
+
warnings_as_error_module_names: set[str],
|
|
196
|
+
ignore_warnings_module_names: set[str],
|
|
197
|
+
*,
|
|
198
|
+
all_warnings_as_error: bool = False,
|
|
199
|
+
ignore_all_warnings: bool = False,
|
|
200
|
+
single_threaded: bool = False,
|
|
201
|
+
argument_separator: str = "-",
|
|
202
|
+
) -> "CommandLineProcessor":
|
|
203
|
+
"""Factor method to construct a CommandLineProcessor object."""
|
|
204
|
+
# Convert modules into a lookup map
|
|
205
|
+
module_map: dict[str, Module] = cls._GetModuleMap(modules, argument_separator)
|
|
206
|
+
|
|
207
|
+
del modules
|
|
208
|
+
|
|
209
|
+
# Process includes
|
|
210
|
+
included_modules, included_requirements = cls._ProcessIncludes(
|
|
211
|
+
module_map, includes, argument_separator
|
|
212
|
+
)
|
|
213
|
+
|
|
214
|
+
del includes
|
|
215
|
+
|
|
216
|
+
for module_name, module in list(module_map.items()):
|
|
217
|
+
if module.requires_explicit_include and module_name not in included_modules:
|
|
218
|
+
module_map.pop(module_name)
|
|
219
|
+
continue
|
|
220
|
+
|
|
221
|
+
del included_modules
|
|
222
|
+
|
|
223
|
+
# Process excludes
|
|
224
|
+
excluded_requirements: dict[str, set[str]] = cls._ProcessExcludes(
|
|
225
|
+
module_map, excludes, argument_separator
|
|
226
|
+
)
|
|
227
|
+
|
|
228
|
+
del excludes
|
|
229
|
+
|
|
230
|
+
# Add / Remove the requirements for each module
|
|
231
|
+
for module_name, module in list(module_map.items()):
|
|
232
|
+
module.ProcessRequirements(
|
|
233
|
+
included_requirements.get(module_name, set()),
|
|
234
|
+
excluded_requirements.get(module_name, set()),
|
|
235
|
+
)
|
|
236
|
+
|
|
237
|
+
if module.GetNumRequirements() == 0:
|
|
238
|
+
module_map.pop(module_name)
|
|
239
|
+
|
|
240
|
+
del included_requirements
|
|
241
|
+
del excluded_requirements
|
|
242
|
+
|
|
243
|
+
if all_warnings_as_error:
|
|
244
|
+
warnings_as_error_module_names = {module.name for module in module_map.values()}
|
|
245
|
+
if ignore_all_warnings:
|
|
246
|
+
ignore_warnings_module_names = {module.name for module in module_map.values()}
|
|
247
|
+
|
|
248
|
+
# Process the dynamic info
|
|
249
|
+
dynamic_args: dict[str, dict[str, Any]] = cls._ProcessDynamicArguments(
|
|
250
|
+
module_map, argument_separator, get_dynamic_args_func
|
|
251
|
+
)
|
|
252
|
+
|
|
188
253
|
module_infos: list[ModuleInfo] = []
|
|
189
254
|
|
|
190
255
|
for module_name, module in module_map.items():
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
# -------------------------------------------------------------------------------
|
|
2
|
+
# |
|
|
3
|
+
# | Copyright (c) 2024 Scientific Software Engineering Center at Georgia Tech
|
|
4
|
+
# | Distributed under the MIT License.
|
|
5
|
+
# |
|
|
6
|
+
# -------------------------------------------------------------------------------
|
|
7
|
+
"""Contains functionality to display the results of executing modules."""
|
|
8
|
+
|
|
9
|
+
import textwrap
|
|
10
|
+
from typing import Optional
|
|
11
|
+
|
|
12
|
+
from dbrownell_Common.Streams.DoneManager import DoneManager # type: ignore[import-untyped]
|
|
13
|
+
from dbrownell_Common import TextwrapEx # type: ignore[import-untyped]
|
|
14
|
+
from rich import print as rich_print
|
|
15
|
+
from rich.console import Group
|
|
16
|
+
from rich.panel import Panel
|
|
17
|
+
|
|
18
|
+
from .Module import EvaluateResult, Module
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def GetInternalPanelContent(
|
|
22
|
+
dm: DoneManager,
|
|
23
|
+
results: list[Module.EvaluateInfo],
|
|
24
|
+
display_resolution: bool,
|
|
25
|
+
display_rationale: bool,
|
|
26
|
+
num_success: int,
|
|
27
|
+
num_warning: int,
|
|
28
|
+
num_error: int,
|
|
29
|
+
num_does_not_apply: int,
|
|
30
|
+
num_requirements: int,
|
|
31
|
+
) -> list[Panel | str]:
|
|
32
|
+
"""Get the content for each result to be displayed inside the internal panel."""
|
|
33
|
+
internal_content: list[Panel | str] = []
|
|
34
|
+
|
|
35
|
+
module = results[0].module
|
|
36
|
+
|
|
37
|
+
if module.description:
|
|
38
|
+
internal_content.append(f"{module.description.strip()}\n")
|
|
39
|
+
|
|
40
|
+
internal_content.append(
|
|
41
|
+
textwrap.dedent(
|
|
42
|
+
f"""\
|
|
43
|
+
Successful: {num_success} ({(num_success / num_requirements):.02%})
|
|
44
|
+
Warnings: {num_warning} ({(num_warning / num_requirements):.02%})
|
|
45
|
+
Errors: {num_error} ({(num_error / num_requirements):.02%})
|
|
46
|
+
Skipped: {num_does_not_apply} ({(num_does_not_apply / num_requirements):.02%})
|
|
47
|
+
""",
|
|
48
|
+
),
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
for result in results:
|
|
52
|
+
if not dm.is_verbose and result.result in [
|
|
53
|
+
EvaluateResult.Success,
|
|
54
|
+
EvaluateResult.DoesNotApply,
|
|
55
|
+
]:
|
|
56
|
+
continue
|
|
57
|
+
|
|
58
|
+
if result.result == EvaluateResult.Success:
|
|
59
|
+
border_color = "green"
|
|
60
|
+
elif result.result == EvaluateResult.Warning:
|
|
61
|
+
border_color = "yellow"
|
|
62
|
+
elif result.result == EvaluateResult.Error:
|
|
63
|
+
border_color = "red"
|
|
64
|
+
elif result.result == EvaluateResult.DoesNotApply:
|
|
65
|
+
border_color = ""
|
|
66
|
+
else:
|
|
67
|
+
raise RuntimeError(result.result) # pragma: no cover
|
|
68
|
+
|
|
69
|
+
content: list[str] = []
|
|
70
|
+
|
|
71
|
+
if result.requirement.description:
|
|
72
|
+
content.append(f"{result.requirement.description.strip()}\n")
|
|
73
|
+
|
|
74
|
+
if result.context:
|
|
75
|
+
content.append(f"{result.result.name.upper()}: {result.context.strip()}\n")
|
|
76
|
+
|
|
77
|
+
if display_resolution and result.resolution:
|
|
78
|
+
content.append(
|
|
79
|
+
textwrap.dedent(
|
|
80
|
+
"""\
|
|
81
|
+
Resolution
|
|
82
|
+
----------
|
|
83
|
+
{}
|
|
84
|
+
""",
|
|
85
|
+
).format(TextwrapEx.Indent(result.resolution.strip(), 2, skip_first_line=True)),
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
if display_rationale and result.rationale:
|
|
89
|
+
content.append(
|
|
90
|
+
textwrap.dedent(
|
|
91
|
+
"""\
|
|
92
|
+
Rationale
|
|
93
|
+
---------
|
|
94
|
+
{}
|
|
95
|
+
""",
|
|
96
|
+
).format(TextwrapEx.Indent(result.rationale.strip(), 2, skip_first_line=True)),
|
|
97
|
+
)
|
|
98
|
+
|
|
99
|
+
internal_content.append(
|
|
100
|
+
Panel(
|
|
101
|
+
Group(*content),
|
|
102
|
+
title=f"[{result.result.name}] {result.requirement.name}",
|
|
103
|
+
title_align="left",
|
|
104
|
+
border_style=border_color,
|
|
105
|
+
padding=(1, 1, 0, 1) if content else 0,
|
|
106
|
+
),
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
return internal_content
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
# ----------------------------------------------------------------------
|
|
113
|
+
def DisplayResults(
|
|
114
|
+
dm: DoneManager,
|
|
115
|
+
all_results: list[list[Module.EvaluateInfo]],
|
|
116
|
+
*,
|
|
117
|
+
display_resolution: bool,
|
|
118
|
+
display_rationale: bool,
|
|
119
|
+
panel_width: Optional[int] = None,
|
|
120
|
+
) -> None:
|
|
121
|
+
"""Display the results of executing the modules."""
|
|
122
|
+
for results in all_results:
|
|
123
|
+
assert results
|
|
124
|
+
module = results[0].module
|
|
125
|
+
|
|
126
|
+
num_success = 0
|
|
127
|
+
num_warning = 0
|
|
128
|
+
num_error = 0
|
|
129
|
+
num_does_not_apply = 0
|
|
130
|
+
|
|
131
|
+
for result in results:
|
|
132
|
+
if result.result == EvaluateResult.Success:
|
|
133
|
+
num_success += 1
|
|
134
|
+
elif result.result == EvaluateResult.Warning:
|
|
135
|
+
num_warning += 1
|
|
136
|
+
elif result.result == EvaluateResult.Error:
|
|
137
|
+
num_error += 1
|
|
138
|
+
elif result.result == EvaluateResult.DoesNotApply:
|
|
139
|
+
num_does_not_apply += 1
|
|
140
|
+
else:
|
|
141
|
+
raise RuntimeError(result.result) # pragma: no cover
|
|
142
|
+
|
|
143
|
+
num_requirements = module.GetNumRequirements()
|
|
144
|
+
assert num_requirements
|
|
145
|
+
|
|
146
|
+
internal_content: list[Panel | str] = GetInternalPanelContent(
|
|
147
|
+
dm,
|
|
148
|
+
results,
|
|
149
|
+
display_resolution,
|
|
150
|
+
display_rationale,
|
|
151
|
+
num_success=num_success,
|
|
152
|
+
num_warning=num_warning,
|
|
153
|
+
num_error=num_error,
|
|
154
|
+
num_does_not_apply=num_does_not_apply,
|
|
155
|
+
num_requirements=num_requirements,
|
|
156
|
+
)
|
|
157
|
+
|
|
158
|
+
rich_print(
|
|
159
|
+
Panel(
|
|
160
|
+
Group(*internal_content),
|
|
161
|
+
padding=1 if internal_content else 0,
|
|
162
|
+
title=results[0].module.name,
|
|
163
|
+
width=panel_width,
|
|
164
|
+
),
|
|
165
|
+
)
|
|
@@ -23,7 +23,7 @@ from typer.core import TyperGroup # type: ignore [import-untyped]
|
|
|
23
23
|
|
|
24
24
|
from RepoAuditor import APP_NAME, __version__
|
|
25
25
|
from RepoAuditor.CommandLineProcessor import CommandLineProcessor, Module
|
|
26
|
-
from RepoAuditor.
|
|
26
|
+
from RepoAuditor.Display import DisplayResults
|
|
27
27
|
from RepoAuditor import Plugin
|
|
28
28
|
|
|
29
29
|
|