RepoAuditor 0.2.28__tar.gz → 0.2.30__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.28 → repoauditor-0.2.30}/PKG-INFO +1 -1
- {repoauditor-0.2.28 → repoauditor-0.2.30}/pyproject.toml +1 -1
- {repoauditor-0.2.28 → repoauditor-0.2.30}/src/RepoAuditor/CommandLineProcessor.py +4 -2
- {repoauditor-0.2.28 → repoauditor-0.2.30}/src/RepoAuditor/EntryPoint.py +1 -1
- {repoauditor-0.2.28 → repoauditor-0.2.30}/src/RepoAuditor/Impl/ParallelSequentialProcessor.py +2 -2
- {repoauditor-0.2.28 → repoauditor-0.2.30}/src/RepoAuditor/Module.py +3 -0
- {repoauditor-0.2.28 → repoauditor-0.2.30}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionQuery.py +2 -1
- {repoauditor-0.2.28 → repoauditor-0.2.30}/src/RepoAuditor/Plugins/GitHub/Impl/EnableRequirementImpl.py +1 -1
- {repoauditor-0.2.28 → repoauditor-0.2.30}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/Impl/StandardEnableRequirementImpl.py +1 -1
- {repoauditor-0.2.28 → repoauditor-0.2.30}/src/RepoAuditor/Plugins/GitHubBase/Module.py +2 -1
- {repoauditor-0.2.28 → repoauditor-0.2.30}/src/RepoAuditor/Plugins/GitHubCustomization/CustomizationQuery.py +17 -5
- {repoauditor-0.2.28 → repoauditor-0.2.30}/src/RepoAuditor/Plugins/GitHubCustomization/Impl/ExistsRequirementImpl.py +14 -18
- {repoauditor-0.2.28 → repoauditor-0.2.30}/src/RepoAuditor/Plugins/GitHubCustomization/Module.py +0 -8
- {repoauditor-0.2.28 → repoauditor-0.2.30}/src/RepoAuditor/Plugins/GitHubCustomization/Requirements/CodeOwners.py +0 -5
- {repoauditor-0.2.28 → repoauditor-0.2.30}/src/RepoAuditor/Plugins/GitHubCustomization/Requirements/Contributing.py +0 -5
- {repoauditor-0.2.28 → repoauditor-0.2.30}/src/RepoAuditor/Plugins/GitHubCustomization/Requirements/IssueTemplates.py +0 -4
- {repoauditor-0.2.28 → repoauditor-0.2.30}/src/RepoAuditor/Plugins/GitHubCustomization/Requirements/PullRequestTemplates.py +0 -6
- {repoauditor-0.2.28 → repoauditor-0.2.30}/src/RepoAuditor/Plugins/GitHubCustomization/Requirements/SecurityPolicy.py +0 -5
- {repoauditor-0.2.28 → repoauditor-0.2.30}/src/RepoAuditor/Plugins/GitHubRulesets/Impl/EnableRulesetRequirementImpl.py +1 -1
- {repoauditor-0.2.28 → repoauditor-0.2.30}/src/RepoAuditor/Query.py +8 -0
- {repoauditor-0.2.28 → repoauditor-0.2.30}/src/RepoAuditor/__init__.py +1 -1
- {repoauditor-0.2.28 → repoauditor-0.2.30}/tests/Plugins/GitHubCustomization_EndToEndTest.py +72 -5
- repoauditor-0.2.30/tests/Plugins/__snapshots__/GitHubCustomization_EndToEndTest.ambr +403 -0
- repoauditor-0.2.28/tests/Plugins/__snapshots__/GitHubCustomization_EndToEndTest.ambr +0 -146
- {repoauditor-0.2.28 → repoauditor-0.2.30}/.copier-answers.yml +0 -0
- {repoauditor-0.2.28 → repoauditor-0.2.30}/.github/CODEOWNERS +0 -0
- {repoauditor-0.2.28 → repoauditor-0.2.30}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {repoauditor-0.2.28 → repoauditor-0.2.30}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {repoauditor-0.2.28 → repoauditor-0.2.30}/.github/ISSUE_TEMPLATE/custom.md +0 -0
- {repoauditor-0.2.28 → repoauditor-0.2.30}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {repoauditor-0.2.28 → repoauditor-0.2.30}/.github/actions/release_impl/action.yml +0 -0
- {repoauditor-0.2.28 → repoauditor-0.2.30}/.github/pull_request_template.md +0 -0
- {repoauditor-0.2.28 → repoauditor-0.2.30}/.github/release_sources.yaml +0 -0
- {repoauditor-0.2.28 → repoauditor-0.2.30}/.github/workflows/CICD.yml +0 -0
- {repoauditor-0.2.28 → repoauditor-0.2.30}/.github/workflows/CICD_impl.yml +0 -0
- {repoauditor-0.2.28 → repoauditor-0.2.30}/.github/workflows/EndToEnd.yml +0 -0
- {repoauditor-0.2.28 → repoauditor-0.2.30}/.github/workflows/codeql.yml +0 -0
- {repoauditor-0.2.28 → repoauditor-0.2.30}/.gitignore +0 -0
- {repoauditor-0.2.28 → repoauditor-0.2.30}/.pre-commit-config.yaml +0 -0
- {repoauditor-0.2.28 → repoauditor-0.2.30}/.python-version +0 -0
- {repoauditor-0.2.28 → repoauditor-0.2.30}/CODE_OF_CONDUCT.md +0 -0
- {repoauditor-0.2.28 → repoauditor-0.2.30}/CONTRIBUTING.md +0 -0
- {repoauditor-0.2.28 → repoauditor-0.2.30}/DEVELOPMENT.md +0 -0
- {repoauditor-0.2.28 → repoauditor-0.2.30}/GOVERNANCE.md +0 -0
- {repoauditor-0.2.28 → repoauditor-0.2.30}/LICENSE +0 -0
- {repoauditor-0.2.28 → repoauditor-0.2.30}/MAINTAINERS.md +0 -0
- {repoauditor-0.2.28 → repoauditor-0.2.30}/README.md +0 -0
- {repoauditor-0.2.28 → repoauditor-0.2.30}/SECURITY.md +0 -0
- {repoauditor-0.2.28 → repoauditor-0.2.30}/minisign_key.pub +0 -0
- {repoauditor-0.2.28 → repoauditor-0.2.30}/src/AutoGitSemVer.yaml +0 -0
- {repoauditor-0.2.28 → repoauditor-0.2.30}/src/RepoAuditor/Display.py +0 -0
- {repoauditor-0.2.28 → repoauditor-0.2.30}/src/RepoAuditor/ExecuteModules.py +0 -0
- {repoauditor-0.2.28 → repoauditor-0.2.30}/src/RepoAuditor/Impl/__init__.py +0 -0
- {repoauditor-0.2.28 → repoauditor-0.2.30}/src/RepoAuditor/Plugin.py +0 -0
- {repoauditor-0.2.28 → repoauditor-0.2.30}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/AllowDeletions.py +0 -0
- {repoauditor-0.2.28 → repoauditor-0.2.30}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/AllowForcePushes.py +0 -0
- {repoauditor-0.2.28 → repoauditor-0.2.30}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/DismissStalePullRequestApprovals.py +0 -0
- {repoauditor-0.2.28 → repoauditor-0.2.30}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/DoNotAllowBypassSettings.py +0 -0
- {repoauditor-0.2.28 → repoauditor-0.2.30}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/EnsureStatusChecks.py +0 -0
- {repoauditor-0.2.28 → repoauditor-0.2.30}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/Impl/ClassicEnableRequirementImpl.py +0 -0
- {repoauditor-0.2.28 → repoauditor-0.2.30}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/Impl/ClassicValueRequirementImpl.py +0 -0
- {repoauditor-0.2.28 → repoauditor-0.2.30}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/Impl/__init__.py +0 -0
- {repoauditor-0.2.28 → repoauditor-0.2.30}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/RequireApprovalMostRecentPush.py +0 -0
- {repoauditor-0.2.28 → repoauditor-0.2.30}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/RequireApprovals.py +0 -0
- {repoauditor-0.2.28 → repoauditor-0.2.30}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/RequireCodeOwnerReview.py +0 -0
- {repoauditor-0.2.28 → repoauditor-0.2.30}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/RequireConversationResolution.py +0 -0
- {repoauditor-0.2.28 → repoauditor-0.2.30}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/RequireLinearHistory.py +0 -0
- {repoauditor-0.2.28 → repoauditor-0.2.30}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/RequirePullRequests.py +0 -0
- {repoauditor-0.2.28 → repoauditor-0.2.30}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/RequireSignedCommits.py +0 -0
- {repoauditor-0.2.28 → repoauditor-0.2.30}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/RequireStatusChecksToPass.py +0 -0
- {repoauditor-0.2.28 → repoauditor-0.2.30}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/RequireUpToDateBranches.py +0 -0
- {repoauditor-0.2.28 → repoauditor-0.2.30}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/__init__.py +0 -0
- {repoauditor-0.2.28 → repoauditor-0.2.30}/src/RepoAuditor/Plugins/GitHub/DefaultBranchQuery.py +0 -0
- {repoauditor-0.2.28 → repoauditor-0.2.30}/src/RepoAuditor/Plugins/GitHub/DefaultBranchQueryRequirements/Protected.py +0 -0
- {repoauditor-0.2.28 → repoauditor-0.2.30}/src/RepoAuditor/Plugins/GitHub/DefaultBranchQueryRequirements/__init__.py +0 -0
- {repoauditor-0.2.28 → repoauditor-0.2.30}/src/RepoAuditor/Plugins/GitHub/Impl/Common.py +0 -0
- {repoauditor-0.2.28 → repoauditor-0.2.30}/src/RepoAuditor/Plugins/GitHub/Impl/ValueRequirementImpl.py +0 -0
- {repoauditor-0.2.28 → repoauditor-0.2.30}/src/RepoAuditor/Plugins/GitHub/Impl/__init__.py +0 -0
- {repoauditor-0.2.28 → repoauditor-0.2.30}/src/RepoAuditor/Plugins/GitHub/Module.py +0 -0
- {repoauditor-0.2.28 → repoauditor-0.2.30}/src/RepoAuditor/Plugins/GitHub/StandardQuery.py +0 -0
- {repoauditor-0.2.28 → repoauditor-0.2.30}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/AutoMerge.py +0 -0
- {repoauditor-0.2.28 → repoauditor-0.2.30}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/DefaultBranch.py +0 -0
- {repoauditor-0.2.28 → repoauditor-0.2.30}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/DeleteHeadBranches.py +0 -0
- {repoauditor-0.2.28 → repoauditor-0.2.30}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/DependabotSecurityUpdates.py +0 -0
- {repoauditor-0.2.28 → repoauditor-0.2.30}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/Description.py +0 -0
- {repoauditor-0.2.28 → repoauditor-0.2.30}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/Impl/StandardValueRequirementImpl.py +0 -0
- {repoauditor-0.2.28 → repoauditor-0.2.30}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/Impl/__init__.py +0 -0
- {repoauditor-0.2.28 → repoauditor-0.2.30}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/License.py +0 -0
- {repoauditor-0.2.28 → repoauditor-0.2.30}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/MergeCommit.py +0 -0
- {repoauditor-0.2.28 → repoauditor-0.2.30}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/MergeCommitMessage.py +0 -0
- {repoauditor-0.2.28 → repoauditor-0.2.30}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/Private.py +0 -0
- {repoauditor-0.2.28 → repoauditor-0.2.30}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/RebaseMergeCommit.py +0 -0
- {repoauditor-0.2.28 → repoauditor-0.2.30}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/SecretScanning.py +0 -0
- {repoauditor-0.2.28 → repoauditor-0.2.30}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/SecretScanningPushProtection.py +0 -0
- {repoauditor-0.2.28 → repoauditor-0.2.30}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/SquashCommitMerge.py +0 -0
- {repoauditor-0.2.28 → repoauditor-0.2.30}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/SquashMergeCommitMessage.py +0 -0
- {repoauditor-0.2.28 → repoauditor-0.2.30}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/SuggestUpdatingPullRequestBranches.py +0 -0
- {repoauditor-0.2.28 → repoauditor-0.2.30}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/SupportDiscussions.py +0 -0
- {repoauditor-0.2.28 → repoauditor-0.2.30}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/SupportIssues.py +0 -0
- {repoauditor-0.2.28 → repoauditor-0.2.30}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/SupportProjects.py +0 -0
- {repoauditor-0.2.28 → repoauditor-0.2.30}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/SupportWikis.py +0 -0
- {repoauditor-0.2.28 → repoauditor-0.2.30}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/TemplateRepository.py +0 -0
- {repoauditor-0.2.28 → repoauditor-0.2.30}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/WebCommitSignoff.py +0 -0
- {repoauditor-0.2.28 → repoauditor-0.2.30}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/__init__.py +0 -0
- {repoauditor-0.2.28 → repoauditor-0.2.30}/src/RepoAuditor/Plugins/GitHub/__init__.py +0 -0
- {repoauditor-0.2.28 → repoauditor-0.2.30}/src/RepoAuditor/Plugins/GitHubBase/__init__.py +0 -0
- {repoauditor-0.2.28 → repoauditor-0.2.30}/src/RepoAuditor/Plugins/GitHubCustomization/Impl/__init__.py +0 -0
- {repoauditor-0.2.28 → repoauditor-0.2.30}/src/RepoAuditor/Plugins/GitHubCustomization/Requirements/__init__.py +0 -0
- {repoauditor-0.2.28 → repoauditor-0.2.30}/src/RepoAuditor/Plugins/GitHubCustomization/__init__.py +0 -0
- {repoauditor-0.2.28 → repoauditor-0.2.30}/src/RepoAuditor/Plugins/GitHubCustomizationPlugin.py +0 -0
- {repoauditor-0.2.28 → repoauditor-0.2.30}/src/RepoAuditor/Plugins/GitHubPlugin.py +0 -0
- {repoauditor-0.2.28 → repoauditor-0.2.30}/src/RepoAuditor/Plugins/GitHubRulesets/Impl/__init__.py +0 -0
- {repoauditor-0.2.28 → repoauditor-0.2.30}/src/RepoAuditor/Plugins/GitHubRulesets/Module.py +0 -0
- {repoauditor-0.2.28 → repoauditor-0.2.30}/src/RepoAuditor/Plugins/GitHubRulesets/Requirements/RequirePullRequests.py +0 -0
- {repoauditor-0.2.28 → repoauditor-0.2.30}/src/RepoAuditor/Plugins/GitHubRulesets/Requirements/RequireSignedCommits.py +0 -0
- {repoauditor-0.2.28 → repoauditor-0.2.30}/src/RepoAuditor/Plugins/GitHubRulesets/Requirements/RequireStatusChecks.py +0 -0
- {repoauditor-0.2.28 → repoauditor-0.2.30}/src/RepoAuditor/Plugins/GitHubRulesets/Requirements/__init__.py +0 -0
- {repoauditor-0.2.28 → repoauditor-0.2.30}/src/RepoAuditor/Plugins/GitHubRulesets/RulesetQuery.py +0 -0
- {repoauditor-0.2.28 → repoauditor-0.2.30}/src/RepoAuditor/Plugins/GitHubRulesets/__init__.py +0 -0
- {repoauditor-0.2.28 → repoauditor-0.2.30}/src/RepoAuditor/Plugins/GitHubRulesetsPlugin.py +0 -0
- {repoauditor-0.2.28 → repoauditor-0.2.30}/src/RepoAuditor/Plugins/__init__.py +0 -0
- {repoauditor-0.2.28 → repoauditor-0.2.30}/src/RepoAuditor/Requirement.py +0 -0
- {repoauditor-0.2.28 → repoauditor-0.2.30}/src/RepoAuditor/py.typed +0 -0
- {repoauditor-0.2.28 → repoauditor-0.2.30}/tests/CommandLineProcessor_UnitTest.py +0 -0
- {repoauditor-0.2.28 → repoauditor-0.2.30}/tests/EntryPoint_UnitTest.py +0 -0
- {repoauditor-0.2.28 → repoauditor-0.2.30}/tests/ExecuteModules_UnitTest.py +0 -0
- {repoauditor-0.2.28 → repoauditor-0.2.30}/tests/Module_UnitTest.py +0 -0
- {repoauditor-0.2.28 → repoauditor-0.2.30}/tests/Plugin_UnitTest.py +0 -0
- {repoauditor-0.2.28 → repoauditor-0.2.30}/tests/Plugins/GitHubCustomization_UnitTest.py +0 -0
- {repoauditor-0.2.28 → repoauditor-0.2.30}/tests/Plugins/GitHubModule_UnitTest.py +0 -0
- {repoauditor-0.2.28 → repoauditor-0.2.30}/tests/Plugins/GitHubRuleset_EndToEndTest.py +0 -0
- {repoauditor-0.2.28 → repoauditor-0.2.30}/tests/Plugins/GitHubRuleset_UnitTest.py +0 -0
- {repoauditor-0.2.28 → repoauditor-0.2.30}/tests/Plugins/GitHub_EndToEndTest.py +0 -0
- {repoauditor-0.2.28 → repoauditor-0.2.30}/tests/Plugins/__snapshots__/GitHubRuleset_EndToEndTest.ambr +0 -0
- {repoauditor-0.2.28 → repoauditor-0.2.30}/tests/Plugins/__snapshots__/GitHub_EndToEndTest.ambr +0 -0
- {repoauditor-0.2.28 → repoauditor-0.2.30}/tests/Plugins/utilities.py +0 -0
- {repoauditor-0.2.28 → repoauditor-0.2.30}/tests/Query_UnitTest.py +0 -0
- {repoauditor-0.2.28 → repoauditor-0.2.30}/tests/Requirement_UnitTest.py +0 -0
- {repoauditor-0.2.28 → repoauditor-0.2.30}/tests/__snapshots__/ExecuteModules_UnitTest.ambr +0 -0
- {repoauditor-0.2.28 → repoauditor-0.2.30}/uv.lock +0 -0
|
@@ -152,15 +152,17 @@ class CommandLineProcessor:
|
|
|
152
152
|
# Now we process the definitions to get the dynamic arguments
|
|
153
153
|
dynamic_args: dict[str, dict[str, Any]] = {}
|
|
154
154
|
|
|
155
|
+
num_acceptable_dynamic_args_parts = 2
|
|
156
|
+
|
|
155
157
|
for key, value in get_dynamic_args_func(dynamic_arg_definitions).items():
|
|
156
158
|
parts = key.split(argument_separator)
|
|
157
|
-
assert len(parts) >=
|
|
159
|
+
assert len(parts) >= num_acceptable_dynamic_args_parts
|
|
158
160
|
|
|
159
161
|
if parts[0] not in module_map:
|
|
160
162
|
msg = f"'{parts[0]}' is not a recognized module name."
|
|
161
163
|
raise ValueError(msg)
|
|
162
164
|
|
|
163
|
-
if len(parts) ==
|
|
165
|
+
if len(parts) == num_acceptable_dynamic_args_parts:
|
|
164
166
|
dynamic_args.setdefault(parts[0], {})[parts[1]] = value
|
|
165
167
|
else:
|
|
166
168
|
dynamic_args.setdefault(parts[0], {}).setdefault(None, {}).setdefault( # type: ignore[call-overload]
|
|
@@ -182,7 +182,7 @@ def _VersionCallback(value: bool) -> None: # noqa: FBT001
|
|
|
182
182
|
epilog=_HelpEpilog(),
|
|
183
183
|
no_args_is_help=False,
|
|
184
184
|
)
|
|
185
|
-
def EntryPoint(
|
|
185
|
+
def EntryPoint( # noqa: PLR0913
|
|
186
186
|
ctx: typer.Context,
|
|
187
187
|
version: Annotated[ # noqa: ARG001, FBT002
|
|
188
188
|
bool,
|
{repoauditor-0.2.28 → repoauditor-0.2.30}/src/RepoAuditor/Impl/ParallelSequentialProcessor.py
RENAMED
|
@@ -37,9 +37,9 @@ def ParallelSequentialProcessor(
|
|
|
37
37
|
) -> list[OutputType]:
|
|
38
38
|
"""Process a list of items in parallel and/or sequentially."""
|
|
39
39
|
if dm is None:
|
|
40
|
-
with DoneManager.Create(StreamDecorator(None), "", line_prefix="") as
|
|
40
|
+
with DoneManager.Create(StreamDecorator(None), "", line_prefix="") as _dm:
|
|
41
41
|
return _Impl(
|
|
42
|
-
|
|
42
|
+
_dm,
|
|
43
43
|
items,
|
|
44
44
|
calculate_result_func,
|
|
45
45
|
max_num_threads,
|
|
@@ -61,6 +61,7 @@ RESPONSE:
|
|
|
61
61
|
|
|
62
62
|
from typing import Any, Optional
|
|
63
63
|
|
|
64
|
+
import requests
|
|
64
65
|
from dbrownell_Common.Types import override # type: ignore[import-untyped]
|
|
65
66
|
|
|
66
67
|
from RepoAuditor.Query import ExecutionStyle, Query
|
|
@@ -149,7 +150,7 @@ class ClassicBranchProtectionQuery(Query):
|
|
|
149
150
|
# and then see if rule sets are in use if the classic information is not found.
|
|
150
151
|
response = module_data["session"].get(f"/branches/{module_data['branch']}/protection")
|
|
151
152
|
|
|
152
|
-
if response.status_code ==
|
|
153
|
+
if response.status_code == requests.codes.NOT_FOUND:
|
|
153
154
|
# Does this branch use rule sets?
|
|
154
155
|
ruleset_response = module_data["session"].get(f"rules/branches/{module_data['branch']}")
|
|
155
156
|
|
|
@@ -24,7 +24,7 @@ class EnableRequirementImpl(Requirement):
|
|
|
24
24
|
"""Object that implements settings that can be enabled/disabled."""
|
|
25
25
|
|
|
26
26
|
# ----------------------------------------------------------------------
|
|
27
|
-
def __init__(
|
|
27
|
+
def __init__( # noqa: PLR0913
|
|
28
28
|
self,
|
|
29
29
|
name: str,
|
|
30
30
|
default_value: bool, # noqa: FBT001
|
|
@@ -19,7 +19,7 @@ class StandardEnableRequirementImpl(EnableRequirementImpl):
|
|
|
19
19
|
"""Implementation of requirement for standard enables of GitHub settings."""
|
|
20
20
|
|
|
21
21
|
# ----------------------------------------------------------------------
|
|
22
|
-
def __init__(
|
|
22
|
+
def __init__( # noqa: PLR0913
|
|
23
23
|
self,
|
|
24
24
|
name: str,
|
|
25
25
|
default_value: bool, # noqa: FBT001
|
|
@@ -104,7 +104,8 @@ class _GitHubSession(requests.Session):
|
|
|
104
104
|
url_parts = urlparse(github_url)
|
|
105
105
|
path_parts = url_parts.path.split("/")
|
|
106
106
|
|
|
107
|
-
|
|
107
|
+
# The URL should be of the form <github_server>/<username>/<repo>
|
|
108
|
+
if len(path_parts) != 3: # noqa: PLR2004
|
|
108
109
|
msg = f"'{github_url}' is not a valid GitHub repository URL."
|
|
109
110
|
raise ValueError(msg)
|
|
110
111
|
|
|
@@ -7,6 +7,8 @@
|
|
|
7
7
|
"""Contains the CustomizationQuery object."""
|
|
8
8
|
|
|
9
9
|
from typing import Any, Optional
|
|
10
|
+
from tempfile import TemporaryDirectory
|
|
11
|
+
from git import Repo
|
|
10
12
|
|
|
11
13
|
from dbrownell_Common.Types import override # type: ignore[import-untyped]
|
|
12
14
|
|
|
@@ -40,12 +42,22 @@ class CustomizationQuery(Query):
|
|
|
40
42
|
self,
|
|
41
43
|
module_data: dict[str, Any],
|
|
42
44
|
) -> Optional[dict[str, Any]]:
|
|
43
|
-
"""Get the data
|
|
44
|
-
response = module_data["session"].get("")
|
|
45
|
+
"""Get the repo data."""
|
|
45
46
|
|
|
46
|
-
|
|
47
|
-
|
|
47
|
+
# Clone the GitHub repository to a temp directory
|
|
48
|
+
github_url = module_data["url"]
|
|
49
|
+
branch = module_data.get("branch", "main")
|
|
50
|
+
temp_repo_dir = TemporaryDirectory()
|
|
51
|
+
Repo.clone_from(github_url, temp_repo_dir.name, branch=branch)
|
|
48
52
|
|
|
49
|
-
|
|
53
|
+
# Record the path and the temp directory for later cleanup
|
|
54
|
+
module_data["repo_dir"] = temp_repo_dir
|
|
50
55
|
|
|
51
56
|
return module_data
|
|
57
|
+
|
|
58
|
+
@override
|
|
59
|
+
def Cleanup(self, module_data: dict[str, Any]) -> None:
|
|
60
|
+
"""Clean up the cloned repository."""
|
|
61
|
+
repo_dir = module_data["repo_dir"]
|
|
62
|
+
repo_dir.cleanup()
|
|
63
|
+
del module_data
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
# -------------------------------------------------------------------------------
|
|
7
7
|
"""Contains the ExistsRequirementImpl object."""
|
|
8
8
|
|
|
9
|
+
from pathlib import Path
|
|
9
10
|
from typing import Any
|
|
10
11
|
from collections.abc import Sequence
|
|
11
12
|
|
|
@@ -69,28 +70,23 @@ class ExistsRequirementImpl(Requirement):
|
|
|
69
70
|
) -> Requirement.EvaluateImplResult:
|
|
70
71
|
if requirement_args[self.dynamic_arg_name]:
|
|
71
72
|
for location in self.possible_locations:
|
|
72
|
-
#
|
|
73
|
-
|
|
73
|
+
# Get full file path in temporary repo directory and check if it exists
|
|
74
|
+
# This checks both upper case and lower case variants
|
|
75
|
+
full_file_path = Path(query_data["repo_dir"].name) / Path(location)
|
|
74
76
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
# If response is a list, we have a directory
|
|
79
|
-
if isinstance(response_json, list):
|
|
80
|
-
for file in response_json:
|
|
81
|
-
# Check if there are any template files (.md or .yml)
|
|
82
|
-
if ".md" in file["path"] or ".yml" in file["path"]:
|
|
83
|
-
return Requirement.EvaluateImplResult(
|
|
84
|
-
EvaluateResult.Success,
|
|
85
|
-
f"File {self.github_file} found in directory {location}",
|
|
86
|
-
)
|
|
87
|
-
|
|
88
|
-
# If response is a dict, we have a single file
|
|
89
|
-
elif isinstance(response_json, dict):
|
|
77
|
+
if full_file_path.exists():
|
|
78
|
+
# If full_file_path is a directory, check if it isn't empty
|
|
79
|
+
if full_file_path.is_dir() and any(full_file_path.iterdir()):
|
|
90
80
|
return Requirement.EvaluateImplResult(
|
|
91
|
-
EvaluateResult.Success,
|
|
81
|
+
EvaluateResult.Success,
|
|
82
|
+
f"File found in {self.github_file} directory of the repository",
|
|
92
83
|
)
|
|
93
84
|
|
|
85
|
+
return Requirement.EvaluateImplResult(
|
|
86
|
+
EvaluateResult.Success,
|
|
87
|
+
f"{self.github_file} found in repository",
|
|
88
|
+
)
|
|
89
|
+
|
|
94
90
|
return Requirement.EvaluateImplResult(
|
|
95
91
|
EvaluateResult.Error,
|
|
96
92
|
f"No {self.github_file} file found.",
|
{repoauditor-0.2.28 → repoauditor-0.2.30}/src/RepoAuditor/Plugins/GitHubCustomization/Module.py
RENAMED
|
@@ -6,9 +6,6 @@
|
|
|
6
6
|
# -------------------------------------------------------------------------------
|
|
7
7
|
"""Contains the GitHubCustomizationModule object."""
|
|
8
8
|
|
|
9
|
-
from typing import Any
|
|
10
|
-
from dbrownell_Common.Types import override
|
|
11
|
-
|
|
12
9
|
from RepoAuditor.Module import ExecutionStyle
|
|
13
10
|
from RepoAuditor.Plugins.GitHubBase.Module import GitHubBaseModule
|
|
14
11
|
from RepoAuditor.Plugins.GitHubCustomization.CustomizationQuery import CustomizationQuery
|
|
@@ -27,8 +24,3 @@ class GitHubCustomizationModule(GitHubBaseModule):
|
|
|
27
24
|
],
|
|
28
25
|
requires_explicit_include=True,
|
|
29
26
|
)
|
|
30
|
-
|
|
31
|
-
@override
|
|
32
|
-
def Cleanup(self, dynamic_args: dict[str, Any]) -> None:
|
|
33
|
-
"""Clean up any resources created during execution."""
|
|
34
|
-
# No resources to clean up in the minimal implementation
|
|
@@ -20,14 +20,9 @@ class CodeOwners(ExistsRequirementImpl):
|
|
|
20
20
|
"exists",
|
|
21
21
|
"CODEOWNERS",
|
|
22
22
|
[
|
|
23
|
-
# Upper case variants
|
|
24
23
|
".github/CODEOWNERS",
|
|
25
24
|
"docs/CODEOWNERS",
|
|
26
25
|
"CODEOWNERS",
|
|
27
|
-
# Lower case variants
|
|
28
|
-
".github/codeowners",
|
|
29
|
-
"docs/codeowners",
|
|
30
|
-
"codeowners",
|
|
31
26
|
],
|
|
32
27
|
textwrap.dedent(
|
|
33
28
|
"""\
|
|
@@ -20,14 +20,9 @@ class Contributing(ExistsRequirementImpl):
|
|
|
20
20
|
"exists",
|
|
21
21
|
"CONTRIBUTING",
|
|
22
22
|
[
|
|
23
|
-
# Upper case variants
|
|
24
23
|
".github/CONTRIBUTING.md",
|
|
25
24
|
"docs/CONTRIBUTING.md",
|
|
26
25
|
"CONTRIBUTING.md",
|
|
27
|
-
# Lower case variants
|
|
28
|
-
".github/contributing.md",
|
|
29
|
-
"docs/contributing.md",
|
|
30
|
-
"contributing.md",
|
|
31
26
|
],
|
|
32
27
|
textwrap.dedent(
|
|
33
28
|
"""\
|
|
@@ -21,12 +21,8 @@ class IssueTemplates(ExistsRequirementImpl):
|
|
|
21
21
|
".github/ISSUE_TEMPLATE.md",
|
|
22
22
|
"docs/ISSUE_TEMPLATE.md",
|
|
23
23
|
"ISSUE_TEMPLATE.md",
|
|
24
|
-
"docs/issue_template.md",
|
|
25
|
-
".github/issue_template.md",
|
|
26
|
-
"issue_template.md",
|
|
27
24
|
# Directories
|
|
28
25
|
".github/ISSUE_TEMPLATE",
|
|
29
|
-
".github/issue_template",
|
|
30
26
|
],
|
|
31
27
|
"Add issue templates to your repository in the .github/ISSUE_TEMPLATE directory.",
|
|
32
28
|
"Issue templates help contributors create high-quality issues by providing a structured format.",
|
|
@@ -18,17 +18,11 @@ class PullRequestTemplate(ExistsRequirementImpl):
|
|
|
18
18
|
"exists",
|
|
19
19
|
"PULL_REQUESTS_TEMPLATE",
|
|
20
20
|
[
|
|
21
|
-
# Upper case variants
|
|
22
21
|
".github/PULL_REQUEST_TEMPLATE.md",
|
|
23
22
|
"docs/PULL_REQUEST_TEMPLATE.md",
|
|
24
23
|
"PULL_REQUEST_TEMPLATE.md",
|
|
25
|
-
# Lower case variants
|
|
26
|
-
".github/pull_request_template.md",
|
|
27
|
-
"docs/pull_request_template.md",
|
|
28
|
-
"pull_request_template.md",
|
|
29
24
|
# Directory with multiple templates
|
|
30
25
|
".github/PULL_REQUEST_TEMPLATE",
|
|
31
|
-
".github/pull_request_template",
|
|
32
26
|
],
|
|
33
27
|
"Create a pull request template file in one of these locations: .github/PULL_REQUEST_TEMPLATE.md, .github/pull_request_template.md, docs/PULL_REQUEST_TEMPLATE.md, or PULL_REQUEST_TEMPLATE.md",
|
|
34
28
|
"Pull request templates help standardize code contributions and expedite the review process by ensuring consistent PR format.",
|
|
@@ -20,14 +20,9 @@ class SecurityPolicy(ExistsRequirementImpl):
|
|
|
20
20
|
"exists",
|
|
21
21
|
"SECURITY",
|
|
22
22
|
[
|
|
23
|
-
# Upper case variants
|
|
24
23
|
".github/SECURITY.md",
|
|
25
24
|
"docs/SECURITY.md",
|
|
26
25
|
"SECURITY.md",
|
|
27
|
-
# Lower case variants
|
|
28
|
-
".github/security.md",
|
|
29
|
-
"docs/security.md",
|
|
30
|
-
"security.md",
|
|
31
26
|
],
|
|
32
27
|
textwrap.dedent(
|
|
33
28
|
"""\
|
|
@@ -20,7 +20,7 @@ class EnableRulesetRequirementImpl(EnableRequirementImpl):
|
|
|
20
20
|
"""Object that implements ruleset settings that can be enabled/disabled."""
|
|
21
21
|
|
|
22
22
|
# ----------------------------------------------------------------------
|
|
23
|
-
def __init__(
|
|
23
|
+
def __init__( # noqa: PLR0913
|
|
24
24
|
self,
|
|
25
25
|
name: str,
|
|
26
26
|
default_value: bool, # noqa: FBT001
|
|
@@ -129,6 +129,14 @@ class Query(ABC):
|
|
|
129
129
|
max_num_threads=max_num_threads,
|
|
130
130
|
)
|
|
131
131
|
|
|
132
|
+
# ----------------------------------------------------------------------
|
|
133
|
+
def Cleanup(
|
|
134
|
+
self,
|
|
135
|
+
module_data: dict[str, Any],
|
|
136
|
+
) -> None:
|
|
137
|
+
"""Clean up any resources created during execution."""
|
|
138
|
+
del module_data
|
|
139
|
+
|
|
132
140
|
|
|
133
141
|
# ----------------------------------------------------------------------
|
|
134
142
|
class StatusInfo:
|
|
@@ -3,4 +3,4 @@ APP_NAME = "RepoAuditor"
|
|
|
3
3
|
# Note that this value will be overwritten by calls to `python ../../Build.py update_version` based
|
|
4
4
|
# on changes observed in the git repository. The default value below will be used until the value
|
|
5
5
|
# here is explicitly updated by the Continuous Integration system.
|
|
6
|
-
__version__ = "0.2.
|
|
6
|
+
__version__ = "0.2.30"
|
|
@@ -36,11 +36,18 @@ class TestCustomization:
|
|
|
36
36
|
|
|
37
37
|
def test_NoCodeOwners(self, pat_args, snapshot):
|
|
38
38
|
"""Test if a CODEOWNERS file does not exist in the repository."""
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
39
|
+
result = CliRunner().invoke(
|
|
40
|
+
app,
|
|
41
|
+
pat_args
|
|
42
|
+
+ [
|
|
43
|
+
"--GitHubCustomization-CodeOwners-exists",
|
|
44
|
+
"--GitHubCustomization-branch",
|
|
45
|
+
"test-GitHubCustomization",
|
|
46
|
+
],
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
assert result.exit_code == -1, result.output
|
|
50
|
+
assert ScrubDurationGithuburlAndSpaces(result.stdout) == snapshot
|
|
44
51
|
|
|
45
52
|
def test_Contributing(self, pat_args, snapshot):
|
|
46
53
|
"""Test if a CONTRIBUTING.md file exists in the repository."""
|
|
@@ -49,6 +56,21 @@ class TestCustomization:
|
|
|
49
56
|
assert result.exit_code == 0, result.output
|
|
50
57
|
assert ScrubDurationGithuburlAndSpaces(result.stdout) == snapshot
|
|
51
58
|
|
|
59
|
+
def test_NoContributing(self, pat_args, snapshot):
|
|
60
|
+
"""Test if a CONTRIBUTING file does not exist in the repository."""
|
|
61
|
+
result = CliRunner().invoke(
|
|
62
|
+
app,
|
|
63
|
+
pat_args
|
|
64
|
+
+ [
|
|
65
|
+
"--GitHubCustomization-Contributing-exists",
|
|
66
|
+
"--GitHubCustomization-branch",
|
|
67
|
+
"test-GitHubCustomization",
|
|
68
|
+
],
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
assert result.exit_code == -1, result.output
|
|
72
|
+
assert ScrubDurationGithuburlAndSpaces(result.stdout) == snapshot
|
|
73
|
+
|
|
52
74
|
def test_IssueTemplate(self, pat_args, snapshot):
|
|
53
75
|
"""Test if an Issue template file (e.g. ISSUE_TEMPLATE.md) exists in the repository."""
|
|
54
76
|
result = CliRunner().invoke(app, pat_args + ["--GitHubCustomization-IssueTemplates-exists"])
|
|
@@ -56,6 +78,21 @@ class TestCustomization:
|
|
|
56
78
|
assert result.exit_code == 0, result.output
|
|
57
79
|
assert ScrubDurationGithuburlAndSpaces(result.stdout) == snapshot
|
|
58
80
|
|
|
81
|
+
def test_NoIssueTemplate(self, pat_args, snapshot):
|
|
82
|
+
"""Test if no Issue template file exists in the repository."""
|
|
83
|
+
result = CliRunner().invoke(
|
|
84
|
+
app,
|
|
85
|
+
pat_args
|
|
86
|
+
+ [
|
|
87
|
+
"--GitHubCustomization-IssueTemplates-exists",
|
|
88
|
+
"--GitHubCustomization-branch",
|
|
89
|
+
"test-GitHubCustomization",
|
|
90
|
+
],
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
assert result.exit_code == -1, result.output
|
|
94
|
+
assert ScrubDurationGithuburlAndSpaces(result.stdout) == snapshot
|
|
95
|
+
|
|
59
96
|
def test_PullRequestTemplate(self, pat_args, snapshot):
|
|
60
97
|
"""Test if a Pull Request template file (e.g. PULL_REQUEST_TEMPLATE.md) exists in the repository."""
|
|
61
98
|
result = CliRunner().invoke(app, pat_args + ["--GitHubCustomization-PullRequestTemplate-exists"])
|
|
@@ -63,6 +100,21 @@ class TestCustomization:
|
|
|
63
100
|
assert result.exit_code == 0, result.output
|
|
64
101
|
assert ScrubDurationGithuburlAndSpaces(result.stdout) == snapshot
|
|
65
102
|
|
|
103
|
+
def test_NoPullRequestTemplate(self, pat_args, snapshot):
|
|
104
|
+
"""Test if no Pull Request template file exists in the repository."""
|
|
105
|
+
result = CliRunner().invoke(
|
|
106
|
+
app,
|
|
107
|
+
pat_args
|
|
108
|
+
+ [
|
|
109
|
+
"--GitHubCustomization-PullRequestTemplate-exists",
|
|
110
|
+
"--GitHubCustomization-branch",
|
|
111
|
+
"test-GitHubCustomization",
|
|
112
|
+
],
|
|
113
|
+
)
|
|
114
|
+
|
|
115
|
+
assert result.exit_code == -1, result.output
|
|
116
|
+
assert ScrubDurationGithuburlAndSpaces(result.stdout) == snapshot
|
|
117
|
+
|
|
66
118
|
def test_SecurityPolicy(self, pat_args, snapshot):
|
|
67
119
|
"""Test if a Security policy file (e.g. SECURITY.md) exists in the repository."""
|
|
68
120
|
result = CliRunner().invoke(app, pat_args + ["--GitHubCustomization-SecurityPolicy-exists"])
|
|
@@ -70,6 +122,21 @@ class TestCustomization:
|
|
|
70
122
|
assert result.exit_code == 0, result.output
|
|
71
123
|
assert ScrubDurationGithuburlAndSpaces(result.stdout) == snapshot
|
|
72
124
|
|
|
125
|
+
def test_NoSecurityPolicy(self, pat_args, snapshot):
|
|
126
|
+
"""Test if no Security policy file exists in the repository."""
|
|
127
|
+
result = CliRunner().invoke(
|
|
128
|
+
app,
|
|
129
|
+
pat_args
|
|
130
|
+
+ [
|
|
131
|
+
"--GitHubCustomization-SecurityPolicy-exists",
|
|
132
|
+
"--GitHubCustomization-branch",
|
|
133
|
+
"test-GitHubCustomization",
|
|
134
|
+
],
|
|
135
|
+
)
|
|
136
|
+
|
|
137
|
+
assert result.exit_code == -1, result.output
|
|
138
|
+
assert ScrubDurationGithuburlAndSpaces(result.stdout) == snapshot
|
|
139
|
+
|
|
73
140
|
|
|
74
141
|
# ----------------------------------------------------------------------
|
|
75
142
|
# ----------------------------------------------------------------------
|