RepoAuditor 0.2.24__tar.gz → 0.2.26__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.
Files changed (127) hide show
  1. {repoauditor-0.2.24 → repoauditor-0.2.26}/PKG-INFO +1 -1
  2. {repoauditor-0.2.24 → repoauditor-0.2.26}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/SecretScanning.py +3 -3
  3. {repoauditor-0.2.24 → repoauditor-0.2.26}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/SecretScanningPushProtection.py +1 -1
  4. repoauditor-0.2.26/src/RepoAuditor/Plugins/GitHubCustomization/CustomizationQuery.py +51 -0
  5. repoauditor-0.2.26/src/RepoAuditor/Plugins/GitHubCustomization/Impl/ExistsRequirementImpl.py +102 -0
  6. {repoauditor-0.2.24 → repoauditor-0.2.26}/src/RepoAuditor/Plugins/GitHubCustomization/Module.py +5 -2
  7. repoauditor-0.2.26/src/RepoAuditor/Plugins/GitHubCustomization/Requirements/CodeOwners.py +56 -0
  8. repoauditor-0.2.26/src/RepoAuditor/Plugins/GitHubCustomization/Requirements/Contributing.py +53 -0
  9. repoauditor-0.2.26/src/RepoAuditor/Plugins/GitHubCustomization/Requirements/IssueTemplates.py +33 -0
  10. repoauditor-0.2.26/src/RepoAuditor/Plugins/GitHubCustomization/Requirements/PullRequestTemplates.py +35 -0
  11. repoauditor-0.2.26/src/RepoAuditor/Plugins/GitHubCustomization/Requirements/SecurityPolicy.py +53 -0
  12. {repoauditor-0.2.24 → repoauditor-0.2.26}/src/RepoAuditor/Plugins/GitHubCustomizationPlugin.py +1 -2
  13. repoauditor-0.2.26/src/RepoAuditor/Plugins/__init__.py +0 -0
  14. {repoauditor-0.2.24 → repoauditor-0.2.26}/src/RepoAuditor/__init__.py +1 -1
  15. repoauditor-0.2.26/src/RepoAuditor/py.typed +0 -0
  16. repoauditor-0.2.26/tests/Plugins/GitHubCustomization_EndToEndTest.py +96 -0
  17. {repoauditor-0.2.24 → repoauditor-0.2.26}/tests/Plugins/GitHubCustomization_UnitTest.py +33 -12
  18. repoauditor-0.2.26/tests/Plugins/__snapshots__/GitHubCustomization_EndToEndTest.ambr +146 -0
  19. {repoauditor-0.2.24 → repoauditor-0.2.26}/tests/Plugins/__snapshots__/GitHub_EndToEndTest.ambr +6 -6
  20. repoauditor-0.2.24/src/RepoAuditor/Plugins/GitHubCustomization/CustomizationQuery.py +0 -20
  21. {repoauditor-0.2.24 → repoauditor-0.2.26}/.copier-answers.yml +0 -0
  22. {repoauditor-0.2.24 → repoauditor-0.2.26}/.github/CODEOWNERS +0 -0
  23. {repoauditor-0.2.24 → repoauditor-0.2.26}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  24. {repoauditor-0.2.24 → repoauditor-0.2.26}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  25. {repoauditor-0.2.24 → repoauditor-0.2.26}/.github/ISSUE_TEMPLATE/custom.md +0 -0
  26. {repoauditor-0.2.24 → repoauditor-0.2.26}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  27. {repoauditor-0.2.24 → repoauditor-0.2.26}/.github/actions/release_impl/action.yml +0 -0
  28. {repoauditor-0.2.24 → repoauditor-0.2.26}/.github/pull_request_template.md +0 -0
  29. {repoauditor-0.2.24 → repoauditor-0.2.26}/.github/release_sources.yaml +0 -0
  30. {repoauditor-0.2.24 → repoauditor-0.2.26}/.github/workflows/CICD.yml +0 -0
  31. {repoauditor-0.2.24 → repoauditor-0.2.26}/.github/workflows/CICD_impl.yml +0 -0
  32. {repoauditor-0.2.24 → repoauditor-0.2.26}/.github/workflows/EndToEnd.yml +0 -0
  33. {repoauditor-0.2.24 → repoauditor-0.2.26}/.github/workflows/codeql.yml +0 -0
  34. {repoauditor-0.2.24 → repoauditor-0.2.26}/.gitignore +0 -0
  35. {repoauditor-0.2.24 → repoauditor-0.2.26}/.pre-commit-config.yaml +0 -0
  36. {repoauditor-0.2.24 → repoauditor-0.2.26}/.python-version +0 -0
  37. {repoauditor-0.2.24 → repoauditor-0.2.26}/CODE_OF_CONDUCT.md +0 -0
  38. {repoauditor-0.2.24 → repoauditor-0.2.26}/CONTRIBUTING.md +0 -0
  39. {repoauditor-0.2.24 → repoauditor-0.2.26}/DEVELOPMENT.md +0 -0
  40. {repoauditor-0.2.24 → repoauditor-0.2.26}/GOVERNANCE.md +0 -0
  41. {repoauditor-0.2.24 → repoauditor-0.2.26}/LICENSE +0 -0
  42. {repoauditor-0.2.24 → repoauditor-0.2.26}/MAINTAINERS.md +0 -0
  43. {repoauditor-0.2.24 → repoauditor-0.2.26}/README.md +0 -0
  44. {repoauditor-0.2.24 → repoauditor-0.2.26}/SECURITY.md +0 -0
  45. {repoauditor-0.2.24 → repoauditor-0.2.26}/minisign_key.pub +0 -0
  46. {repoauditor-0.2.24 → repoauditor-0.2.26}/pyproject.toml +0 -0
  47. {repoauditor-0.2.24 → repoauditor-0.2.26}/src/AutoGitSemVer.yaml +0 -0
  48. {repoauditor-0.2.24 → repoauditor-0.2.26}/src/RepoAuditor/CommandLineProcessor.py +0 -0
  49. {repoauditor-0.2.24 → repoauditor-0.2.26}/src/RepoAuditor/Display.py +0 -0
  50. {repoauditor-0.2.24 → repoauditor-0.2.26}/src/RepoAuditor/EntryPoint.py +0 -0
  51. {repoauditor-0.2.24 → repoauditor-0.2.26}/src/RepoAuditor/ExecuteModules.py +0 -0
  52. {repoauditor-0.2.24 → repoauditor-0.2.26}/src/RepoAuditor/Impl/ParallelSequentialProcessor.py +0 -0
  53. {repoauditor-0.2.24 → repoauditor-0.2.26}/src/RepoAuditor/Impl/__init__.py +0 -0
  54. {repoauditor-0.2.24 → repoauditor-0.2.26}/src/RepoAuditor/Module.py +0 -0
  55. {repoauditor-0.2.24 → repoauditor-0.2.26}/src/RepoAuditor/Plugin.py +0 -0
  56. {repoauditor-0.2.24 → repoauditor-0.2.26}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionQuery.py +0 -0
  57. {repoauditor-0.2.24 → repoauditor-0.2.26}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/AllowDeletions.py +0 -0
  58. {repoauditor-0.2.24 → repoauditor-0.2.26}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/AllowForcePushes.py +0 -0
  59. {repoauditor-0.2.24 → repoauditor-0.2.26}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/DismissStalePullRequestApprovals.py +0 -0
  60. {repoauditor-0.2.24 → repoauditor-0.2.26}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/DoNotAllowBypassSettings.py +0 -0
  61. {repoauditor-0.2.24 → repoauditor-0.2.26}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/EnsureStatusChecks.py +0 -0
  62. {repoauditor-0.2.24 → repoauditor-0.2.26}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/Impl/ClassicEnableRequirementImpl.py +0 -0
  63. {repoauditor-0.2.24 → repoauditor-0.2.26}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/Impl/ClassicValueRequirementImpl.py +0 -0
  64. {repoauditor-0.2.24 → repoauditor-0.2.26}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/Impl/__init__.py +0 -0
  65. {repoauditor-0.2.24 → repoauditor-0.2.26}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/RequireApprovalMostRecentPush.py +0 -0
  66. {repoauditor-0.2.24 → repoauditor-0.2.26}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/RequireApprovals.py +0 -0
  67. {repoauditor-0.2.24 → repoauditor-0.2.26}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/RequireCodeOwnerReview.py +0 -0
  68. {repoauditor-0.2.24 → repoauditor-0.2.26}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/RequireConversationResolution.py +0 -0
  69. {repoauditor-0.2.24 → repoauditor-0.2.26}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/RequireLinearHistory.py +0 -0
  70. {repoauditor-0.2.24 → repoauditor-0.2.26}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/RequirePullRequests.py +0 -0
  71. {repoauditor-0.2.24 → repoauditor-0.2.26}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/RequireSignedCommits.py +0 -0
  72. {repoauditor-0.2.24 → repoauditor-0.2.26}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/RequireStatusChecksToPass.py +0 -0
  73. {repoauditor-0.2.24 → repoauditor-0.2.26}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/RequireUpToDateBranches.py +0 -0
  74. {repoauditor-0.2.24 → repoauditor-0.2.26}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/__init__.py +0 -0
  75. {repoauditor-0.2.24 → repoauditor-0.2.26}/src/RepoAuditor/Plugins/GitHub/DefaultBranchQuery.py +0 -0
  76. {repoauditor-0.2.24 → repoauditor-0.2.26}/src/RepoAuditor/Plugins/GitHub/DefaultBranchQueryRequirements/Protected.py +0 -0
  77. {repoauditor-0.2.24 → repoauditor-0.2.26}/src/RepoAuditor/Plugins/GitHub/DefaultBranchQueryRequirements/__init__.py +0 -0
  78. {repoauditor-0.2.24 → repoauditor-0.2.26}/src/RepoAuditor/Plugins/GitHub/Impl/Common.py +0 -0
  79. {repoauditor-0.2.24 → repoauditor-0.2.26}/src/RepoAuditor/Plugins/GitHub/Impl/EnableRequirementImpl.py +0 -0
  80. {repoauditor-0.2.24 → repoauditor-0.2.26}/src/RepoAuditor/Plugins/GitHub/Impl/ValueRequirementImpl.py +0 -0
  81. {repoauditor-0.2.24 → repoauditor-0.2.26}/src/RepoAuditor/Plugins/GitHub/Impl/__init__.py +0 -0
  82. {repoauditor-0.2.24 → repoauditor-0.2.26}/src/RepoAuditor/Plugins/GitHub/Module.py +0 -0
  83. {repoauditor-0.2.24 → repoauditor-0.2.26}/src/RepoAuditor/Plugins/GitHub/StandardQuery.py +0 -0
  84. {repoauditor-0.2.24 → repoauditor-0.2.26}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/AutoMerge.py +0 -0
  85. {repoauditor-0.2.24 → repoauditor-0.2.26}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/DefaultBranch.py +0 -0
  86. {repoauditor-0.2.24 → repoauditor-0.2.26}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/DeleteHeadBranches.py +0 -0
  87. {repoauditor-0.2.24 → repoauditor-0.2.26}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/DependabotSecurityUpdates.py +0 -0
  88. {repoauditor-0.2.24 → repoauditor-0.2.26}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/Description.py +0 -0
  89. {repoauditor-0.2.24 → repoauditor-0.2.26}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/Impl/StandardEnableRequirementImpl.py +0 -0
  90. {repoauditor-0.2.24 → repoauditor-0.2.26}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/Impl/StandardValueRequirementImpl.py +0 -0
  91. {repoauditor-0.2.24 → repoauditor-0.2.26}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/Impl/__init__.py +0 -0
  92. {repoauditor-0.2.24 → repoauditor-0.2.26}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/License.py +0 -0
  93. {repoauditor-0.2.24 → repoauditor-0.2.26}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/MergeCommit.py +0 -0
  94. {repoauditor-0.2.24 → repoauditor-0.2.26}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/MergeCommitMessage.py +0 -0
  95. {repoauditor-0.2.24 → repoauditor-0.2.26}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/Private.py +0 -0
  96. {repoauditor-0.2.24 → repoauditor-0.2.26}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/RebaseMergeCommit.py +0 -0
  97. {repoauditor-0.2.24 → repoauditor-0.2.26}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/SquashCommitMerge.py +0 -0
  98. {repoauditor-0.2.24 → repoauditor-0.2.26}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/SquashMergeCommitMessage.py +0 -0
  99. {repoauditor-0.2.24 → repoauditor-0.2.26}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/SuggestUpdatingPullRequestBranches.py +0 -0
  100. {repoauditor-0.2.24 → repoauditor-0.2.26}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/SupportDiscussions.py +0 -0
  101. {repoauditor-0.2.24 → repoauditor-0.2.26}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/SupportIssues.py +0 -0
  102. {repoauditor-0.2.24 → repoauditor-0.2.26}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/SupportProjects.py +0 -0
  103. {repoauditor-0.2.24 → repoauditor-0.2.26}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/SupportWikis.py +0 -0
  104. {repoauditor-0.2.24 → repoauditor-0.2.26}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/TemplateRepository.py +0 -0
  105. {repoauditor-0.2.24 → repoauditor-0.2.26}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/WebCommitSignoff.py +0 -0
  106. {repoauditor-0.2.24 → repoauditor-0.2.26}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/__init__.py +0 -0
  107. {repoauditor-0.2.24 → repoauditor-0.2.26}/src/RepoAuditor/Plugins/GitHub/__init__.py +0 -0
  108. {repoauditor-0.2.24 → repoauditor-0.2.26}/src/RepoAuditor/Plugins/GitHubBase/Module.py +0 -0
  109. {repoauditor-0.2.24 → repoauditor-0.2.26}/src/RepoAuditor/Plugins/GitHubBase/__init__.py +0 -0
  110. {repoauditor-0.2.24/src/RepoAuditor/Plugins/GitHubCustomization → repoauditor-0.2.26/src/RepoAuditor/Plugins/GitHubCustomization/Impl}/__init__.py +0 -0
  111. {repoauditor-0.2.24/src/RepoAuditor/Plugins → repoauditor-0.2.26/src/RepoAuditor/Plugins/GitHubCustomization/Requirements}/__init__.py +0 -0
  112. /repoauditor-0.2.24/src/RepoAuditor/py.typed → /repoauditor-0.2.26/src/RepoAuditor/Plugins/GitHubCustomization/__init__.py +0 -0
  113. {repoauditor-0.2.24 → repoauditor-0.2.26}/src/RepoAuditor/Plugins/GitHubPlugin.py +0 -0
  114. {repoauditor-0.2.24 → repoauditor-0.2.26}/src/RepoAuditor/Query.py +0 -0
  115. {repoauditor-0.2.24 → repoauditor-0.2.26}/src/RepoAuditor/Requirement.py +0 -0
  116. {repoauditor-0.2.24 → repoauditor-0.2.26}/tests/CommandLineProcessor_UnitTest.py +0 -0
  117. {repoauditor-0.2.24 → repoauditor-0.2.26}/tests/EntryPoint_UnitTest.py +0 -0
  118. {repoauditor-0.2.24 → repoauditor-0.2.26}/tests/ExecuteModules_UnitTest.py +0 -0
  119. {repoauditor-0.2.24 → repoauditor-0.2.26}/tests/Module_UnitTest.py +0 -0
  120. {repoauditor-0.2.24 → repoauditor-0.2.26}/tests/Plugin_UnitTest.py +0 -0
  121. {repoauditor-0.2.24 → repoauditor-0.2.26}/tests/Plugins/GitHubModule_UnitTest.py +0 -0
  122. {repoauditor-0.2.24 → repoauditor-0.2.26}/tests/Plugins/GitHub_EndToEndTest.py +0 -0
  123. {repoauditor-0.2.24 → repoauditor-0.2.26}/tests/Plugins/utilities.py +0 -0
  124. {repoauditor-0.2.24 → repoauditor-0.2.26}/tests/Query_UnitTest.py +0 -0
  125. {repoauditor-0.2.24 → repoauditor-0.2.26}/tests/Requirement_UnitTest.py +0 -0
  126. {repoauditor-0.2.24 → repoauditor-0.2.26}/tests/__snapshots__/ExecuteModules_UnitTest.ambr +0 -0
  127. {repoauditor-0.2.24 → repoauditor-0.2.26}/uv.lock +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: RepoAuditor
3
- Version: 0.2.24
3
+ Version: 0.2.26
4
4
  Summary: Add your description here
5
5
  Project-URL: Homepage, https://github.com/gt-sse-center/RepoAuditor
6
6
  Project-URL: Documentation, https://github.com/gt-sse-center/RepoAuditor
@@ -24,12 +24,12 @@ class SecretScanning(StandardEnableRequirementImpl):
24
24
  True,
25
25
  "false",
26
26
  "settings/security_analysis",
27
- "Secret scanning",
28
- "Secret scanning",
27
+ "Secret Protection",
28
+ "Secret protection",
29
29
  _GetValue,
30
30
  textwrap.dedent(
31
31
  """\
32
- The default behavior is to enable secret scanning.
32
+ The default behavior is to enable secret protection.
33
33
 
34
34
  Reasons for this Default
35
35
  ------------------------
@@ -24,7 +24,7 @@ class SecretScanningPushProtection(StandardEnableRequirementImpl):
24
24
  True,
25
25
  "false",
26
26
  "settings/security_analysis",
27
- "Secret scanning",
27
+ "Secret Protection",
28
28
  "Push protection",
29
29
  _GetValue,
30
30
  textwrap.dedent(
@@ -0,0 +1,51 @@
1
+ # -------------------------------------------------------------------------------
2
+ # |
3
+ # | Copyright (c) 2024 Scientific Software Engineering Center at Georgia Tech
4
+ # | Distributed under the MIT License.
5
+ # |
6
+ # -------------------------------------------------------------------------------
7
+ """Contains the CustomizationQuery object."""
8
+
9
+ from typing import Any, Optional
10
+
11
+ from dbrownell_Common.Types import override # type: ignore[import-untyped]
12
+
13
+ from RepoAuditor.Query import ExecutionStyle, Query
14
+ from RepoAuditor.Plugins.GitHubCustomization.Requirements.CodeOwners import CodeOwners
15
+ from RepoAuditor.Plugins.GitHubCustomization.Requirements.Contributing import Contributing
16
+ from RepoAuditor.Plugins.GitHubCustomization.Requirements.IssueTemplates import IssueTemplates
17
+ from RepoAuditor.Plugins.GitHubCustomization.Requirements.PullRequestTemplates import PullRequestTemplate
18
+ from RepoAuditor.Plugins.GitHubCustomization.Requirements.SecurityPolicy import SecurityPolicy
19
+
20
+
21
+ class CustomizationQuery(Query):
22
+ """Query with requirements that check for GitHub customization files."""
23
+
24
+ def __init__(self) -> None:
25
+ super().__init__(
26
+ "CustomizationQuery",
27
+ ExecutionStyle.Parallel,
28
+ [
29
+ CodeOwners(),
30
+ Contributing(),
31
+ IssueTemplates(),
32
+ PullRequestTemplate(),
33
+ SecurityPolicy(),
34
+ ],
35
+ )
36
+
37
+ # ----------------------------------------------------------------------
38
+ @override
39
+ def GetData(
40
+ self,
41
+ module_data: dict[str, Any],
42
+ ) -> Optional[dict[str, Any]]:
43
+ """Get the data from an API session."""
44
+ response = module_data["session"].get("")
45
+
46
+ response.raise_for_status()
47
+ response = response.json()
48
+
49
+ module_data["standard"] = response
50
+
51
+ return module_data
@@ -0,0 +1,102 @@
1
+ # -------------------------------------------------------------------------------
2
+ # |
3
+ # | Copyright (c) 2024 Scientific Software Engineering Center at Georgia Tech
4
+ # | Distributed under the MIT License.
5
+ # |
6
+ # -------------------------------------------------------------------------------
7
+ """Contains the ExistsRequirementImpl object."""
8
+
9
+ from typing import Any
10
+ from collections.abc import Sequence
11
+
12
+ import typer
13
+
14
+ from dbrownell_Common.TyperEx import TypeDefinitionItemType # type: ignore[import-untyped]
15
+ from dbrownell_Common.Types import override # type: ignore[import-untyped]
16
+
17
+ from RepoAuditor.Requirement import EvaluateResult, ExecutionStyle, Requirement
18
+
19
+
20
+ # ----------------------------------------------------------------------
21
+ class ExistsRequirementImpl(Requirement):
22
+ """Object that implements check if a file exists."""
23
+
24
+ # ----------------------------------------------------------------------
25
+ def __init__(
26
+ self,
27
+ name: str,
28
+ dynamic_arg_name: str,
29
+ github_file: str,
30
+ possible_locations: Sequence[str],
31
+ resolution: str,
32
+ rationale: str,
33
+ *,
34
+ requires_explicit_include: bool = False,
35
+ ) -> None:
36
+ super().__init__(
37
+ name,
38
+ f"Validates that {github_file} file exists.",
39
+ ExecutionStyle.Parallel,
40
+ resolution,
41
+ rationale,
42
+ requires_explicit_include=requires_explicit_include,
43
+ )
44
+
45
+ self.dynamic_arg_name = dynamic_arg_name
46
+ self.github_file = github_file
47
+ self.possible_locations = possible_locations
48
+
49
+ # ----------------------------------------------------------------------
50
+ @override
51
+ def GetDynamicArgDefinitions(self) -> dict[str, TypeDefinitionItemType]:
52
+ """Get the definitions for the arguments to this requirement."""
53
+ return {
54
+ self.dynamic_arg_name: (
55
+ bool,
56
+ typer.Option(
57
+ False,
58
+ help=f"Ensures that the customization file {self.github_file} exists.",
59
+ ),
60
+ ),
61
+ }
62
+
63
+ # ----------------------------------------------------------------------
64
+ @override
65
+ def _EvaluateImpl(
66
+ self,
67
+ query_data: dict[str, Any],
68
+ requirement_args: dict[str, Any],
69
+ ) -> Requirement.EvaluateImplResult:
70
+ if requirement_args[self.dynamic_arg_name]:
71
+ for location in self.possible_locations:
72
+ # Query for file location
73
+ response = query_data["session"].get(f"contents/{location}")
74
+
75
+ # If location is found, response will have status code 200
76
+ if response.status_code == 200:
77
+ response_json = response.json()
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):
90
+ return Requirement.EvaluateImplResult(
91
+ EvaluateResult.Success, f"File {self.github_file} found at {location}"
92
+ )
93
+
94
+ return Requirement.EvaluateImplResult(
95
+ EvaluateResult.Error,
96
+ f"No {self.github_file} file found.",
97
+ provide_resolution=True,
98
+ provide_rationale=True,
99
+ )
100
+
101
+ # Requirement flag not set so DoesNotApply
102
+ return Requirement.EvaluateImplResult(EvaluateResult.DoesNotApply, None)
@@ -11,6 +11,7 @@ from dbrownell_Common.Types import override
11
11
 
12
12
  from RepoAuditor.Module import ExecutionStyle
13
13
  from RepoAuditor.Plugins.GitHubBase.Module import GitHubBaseModule
14
+ from RepoAuditor.Plugins.GitHubCustomization.CustomizationQuery import CustomizationQuery
14
15
 
15
16
 
16
17
  class GitHubCustomizationModule(GitHubBaseModule):
@@ -21,8 +22,10 @@ class GitHubCustomizationModule(GitHubBaseModule):
21
22
  "GitHubCustomization",
22
23
  "Validates GitHub repository customization files.",
23
24
  ExecutionStyle.Parallel,
24
- [], # Empty query list for now
25
- requires_explicit_include=False,
25
+ [
26
+ CustomizationQuery(),
27
+ ],
28
+ requires_explicit_include=True,
26
29
  )
27
30
 
28
31
  @override
@@ -0,0 +1,56 @@
1
+ # -------------------------------------------------------------------------------
2
+ # |
3
+ # | Copyright (c) 2024 Scientific Software Engineering Center at Georgia Tech
4
+ # | Distributed under the MIT License.
5
+ # |
6
+ # -------------------------------------------------------------------------------
7
+ """Contains the CodeOwners requirement."""
8
+
9
+ import textwrap
10
+
11
+ from RepoAuditor.Plugins.GitHubCustomization.Impl.ExistsRequirementImpl import ExistsRequirementImpl
12
+
13
+
14
+ class CodeOwners(ExistsRequirementImpl):
15
+ """Validates that CODEOWNERS file is configured."""
16
+
17
+ def __init__(self) -> None:
18
+ super().__init__(
19
+ "CodeOwners",
20
+ "exists",
21
+ "CODEOWNERS",
22
+ [
23
+ # Upper case variants
24
+ ".github/CODEOWNERS",
25
+ "docs/CODEOWNERS",
26
+ "CODEOWNERS",
27
+ # Lower case variants
28
+ ".github/codeowners",
29
+ "docs/codeowners",
30
+ "codeowners",
31
+ ],
32
+ textwrap.dedent(
33
+ """\
34
+ 1) Create a CODEOWNERS file in one of these locations:
35
+ - .github/CODEOWNERS
36
+ - docs/CODEOWNERS
37
+ - CODEOWNERS
38
+
39
+ Example CODEOWNERS file format:
40
+ # Syntax example:
41
+ # directory/ @username
42
+ # *.js @username
43
+ # /docs/ @username @username2
44
+ """
45
+ ),
46
+ textwrap.dedent(
47
+ """\
48
+ CODEOWNERS files define who is responsible for code review.
49
+
50
+ Benefits:
51
+ - Automatic reviewer assignment
52
+ - Clear code ownership
53
+ - Streamlined review process
54
+ """
55
+ ),
56
+ )
@@ -0,0 +1,53 @@
1
+ # -------------------------------------------------------------------------------
2
+ # |
3
+ # | Copyright (c) 2024 Scientific Software Engineering Center at Georgia Tech
4
+ # | Distributed under the MIT License.
5
+ # |
6
+ # -------------------------------------------------------------------------------
7
+ """Contains the Contributing requirement."""
8
+
9
+ import textwrap
10
+
11
+ from RepoAuditor.Plugins.GitHubCustomization.Impl.ExistsRequirementImpl import ExistsRequirementImpl
12
+
13
+
14
+ class Contributing(ExistsRequirementImpl):
15
+ """Validates that a contributing guide is configured."""
16
+
17
+ def __init__(self) -> None:
18
+ super().__init__(
19
+ "Contributing",
20
+ "exists",
21
+ "CONTRIBUTING",
22
+ [
23
+ # Upper case variants
24
+ ".github/CONTRIBUTING.md",
25
+ "docs/CONTRIBUTING.md",
26
+ "CONTRIBUTING.md",
27
+ # Lower case variants
28
+ ".github/contributing.md",
29
+ "docs/contributing.md",
30
+ "contributing.md",
31
+ ],
32
+ textwrap.dedent(
33
+ """\
34
+ 1) Create a contributing guide in one of these locations:
35
+ - .github/CONTRIBUTING.md
36
+ - docs/CONTRIBUTING.md
37
+ - CONTRIBUTING.md
38
+
39
+ Example template can be found at:
40
+ https://github.com/nayafia/contributing-template/blob/master/CONTRIBUTING-template.md
41
+ """
42
+ ),
43
+ textwrap.dedent(
44
+ """\
45
+ Contributing guides help new contributors understand how to participate.
46
+
47
+ Benefits:
48
+ - Clear contribution process
49
+ - Consistent code quality
50
+ - Better community engagement
51
+ """
52
+ ),
53
+ )
@@ -0,0 +1,33 @@
1
+ # -------------------------------------------------------------------------------
2
+ # |
3
+ # | Copyright (c) 2024 Scientific Software Engineering Center at Georgia Tech
4
+ # | Distributed under the MIT License.
5
+ # |
6
+ # -------------------------------------------------------------------------------
7
+ """Contains the IssueTemplates requirement."""
8
+
9
+ from RepoAuditor.Plugins.GitHubCustomization.Impl.ExistsRequirementImpl import ExistsRequirementImpl
10
+
11
+
12
+ class IssueTemplates(ExistsRequirementImpl):
13
+ """Requirement that checks for the presence of issue templates."""
14
+
15
+ def __init__(self) -> None:
16
+ super().__init__(
17
+ "IssueTemplates",
18
+ "exists",
19
+ "ISSUE_TEMPLATES",
20
+ [
21
+ ".github/ISSUE_TEMPLATE.md",
22
+ "docs/ISSUE_TEMPLATE.md",
23
+ "ISSUE_TEMPLATE.md",
24
+ "docs/issue_template.md",
25
+ ".github/issue_template.md",
26
+ "issue_template.md",
27
+ # Directories
28
+ ".github/ISSUE_TEMPLATE",
29
+ ".github/issue_template",
30
+ ],
31
+ "Add issue templates to your repository in the .github/ISSUE_TEMPLATE directory.",
32
+ "Issue templates help contributors create high-quality issues by providing a structured format.",
33
+ )
@@ -0,0 +1,35 @@
1
+ # -------------------------------------------------------------------------------
2
+ # |
3
+ # | Copyright (c) 2024 Scientific Software Engineering Center at Georgia Tech
4
+ # | Distributed under the MIT License.
5
+ # |
6
+ # -------------------------------------------------------------------------------
7
+ """Contains the PullRequestTemplate requirement."""
8
+
9
+ from RepoAuditor.Plugins.GitHubCustomization.Impl.ExistsRequirementImpl import ExistsRequirementImpl
10
+
11
+
12
+ class PullRequestTemplate(ExistsRequirementImpl):
13
+ """Validates that a pull request template is configured."""
14
+
15
+ def __init__(self) -> None:
16
+ super().__init__(
17
+ "PullRequestTemplate",
18
+ "exists",
19
+ "PULL_REQUESTS_TEMPLATE",
20
+ [
21
+ # Upper case variants
22
+ ".github/PULL_REQUEST_TEMPLATE.md",
23
+ "docs/PULL_REQUEST_TEMPLATE.md",
24
+ "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
+ # Directory with multiple templates
30
+ ".github/PULL_REQUEST_TEMPLATE",
31
+ ".github/pull_request_template",
32
+ ],
33
+ "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
+ "Pull request templates help standardize code contributions and expedite the review process by ensuring consistent PR format.",
35
+ )
@@ -0,0 +1,53 @@
1
+ # -------------------------------------------------------------------------------
2
+ # |
3
+ # | Copyright (c) 2024 Scientific Software Engineering Center at Georgia Tech
4
+ # | Distributed under the MIT License.
5
+ # |
6
+ # -------------------------------------------------------------------------------
7
+ """Contains the SecurityPolicy requirement."""
8
+
9
+ import textwrap
10
+
11
+ from RepoAuditor.Plugins.GitHubCustomization.Impl.ExistsRequirementImpl import ExistsRequirementImpl
12
+
13
+
14
+ class SecurityPolicy(ExistsRequirementImpl):
15
+ """Validates that a security policy is configured."""
16
+
17
+ def __init__(self) -> None:
18
+ super().__init__(
19
+ "SecurityPolicy",
20
+ "exists",
21
+ "SECURITY",
22
+ [
23
+ # Upper case variants
24
+ ".github/SECURITY.md",
25
+ "docs/SECURITY.md",
26
+ "SECURITY.md",
27
+ # Lower case variants
28
+ ".github/security.md",
29
+ "docs/security.md",
30
+ "security.md",
31
+ ],
32
+ textwrap.dedent(
33
+ """\
34
+ 1) Create a security policy file in one of these locations:
35
+ - .github/SECURITY.md
36
+ - docs/SECURITY.md
37
+ - SECURITY.md
38
+
39
+ Example policy can be found at:
40
+ https://github.com/gt-sse-center/RepoAuditor/blob/main/SECURITY.md
41
+ """
42
+ ),
43
+ textwrap.dedent(
44
+ """\
45
+ Security policies help users report vulnerabilities responsibly.
46
+
47
+ Benefits:
48
+ - Clear security reporting process
49
+ - Responsible disclosure guidelines
50
+ - Better security management
51
+ """
52
+ ),
53
+ )
@@ -10,8 +10,7 @@ import pluggy
10
10
 
11
11
  from RepoAuditor import APP_NAME
12
12
  from RepoAuditor.Module import Module
13
-
14
- from .GitHubCustomization.Module import GitHubCustomizationModule
13
+ from RepoAuditor.Plugins.GitHubCustomization.Module import GitHubCustomizationModule
15
14
 
16
15
 
17
16
  # ----------------------------------------------------------------------
File without changes
@@ -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.24"
6
+ __version__ = "0.2.26"
File without changes
@@ -0,0 +1,96 @@
1
+ # -------------------------------------------------------------------------------
2
+ # |
3
+ # | Copyright (c) 2024 Scientific Software Engineering Center at Georgia Tech
4
+ # | Distributed under the MIT License.
5
+ # |
6
+ # -------------------------------------------------------------------------------
7
+ """End-to-end tests for the GitHubCustomization plugin."""
8
+
9
+ import pytest
10
+ from pathlib import Path
11
+
12
+ from dbrownell_Common.TestHelpers.StreamTestHelpers import (
13
+ InitializeStreamCapabilities,
14
+ )
15
+ from typer.testing import CliRunner
16
+
17
+ from RepoAuditor.EntryPoint import app
18
+
19
+ from utilities import ScrubDurationGithuburlAndSpaces, GetGithubUrl, CheckPATFileExists
20
+
21
+ # ----------------------------------------------------------------------
22
+ pytest.fixture(InitializeStreamCapabilities(), scope="session", autouse=True)
23
+
24
+
25
+ # ----------------------------------------------------------------------
26
+ class TestCustomization:
27
+ """End-to-end tests for customization files in a GitHub repository."""
28
+
29
+ # ----------------------------------------------------------------------
30
+ def test_CodeOwners(self, pat_args, snapshot):
31
+ """Test if a CODEOWNERS file exists in the repository."""
32
+ result = CliRunner().invoke(app, pat_args + ["--GitHubCustomization-CodeOwners-exists"])
33
+
34
+ assert result.exit_code == 0, result.output
35
+ assert ScrubDurationGithuburlAndSpaces(result.stdout) == snapshot
36
+
37
+ def test_NoCodeOwners(self, pat_args, snapshot):
38
+ """Test if a CODEOWNERS file does not exist in the repository."""
39
+ # TODO: How to test if CodeOwners file doesn't exist without updating repo?
40
+ result = CliRunner().invoke(app, pat_args)
41
+
42
+ assert result.exit_code == 0, result.output
43
+ # assert ScrubDurationGithuburlAndSpaces(result.stdout) == snapshot
44
+
45
+ def test_Contributing(self, pat_args, snapshot):
46
+ """Test if a CONTRIBUTING.md file exists in the repository."""
47
+ result = CliRunner().invoke(app, pat_args + ["--GitHubCustomization-Contributing-exists"])
48
+
49
+ assert result.exit_code == 0, result.output
50
+ assert ScrubDurationGithuburlAndSpaces(result.stdout) == snapshot
51
+
52
+ def test_IssueTemplate(self, pat_args, snapshot):
53
+ """Test if an Issue template file (e.g. ISSUE_TEMPLATE.md) exists in the repository."""
54
+ result = CliRunner().invoke(app, pat_args + ["--GitHubCustomization-IssueTemplates-exists"])
55
+
56
+ assert result.exit_code == 0, result.output
57
+ assert ScrubDurationGithuburlAndSpaces(result.stdout) == snapshot
58
+
59
+ def test_PullRequestTemplate(self, pat_args, snapshot):
60
+ """Test if a Pull Request template file (e.g. PULL_REQUEST_TEMPLATE.md) exists in the repository."""
61
+ result = CliRunner().invoke(app, pat_args + ["--GitHubCustomization-PullRequestTemplate-exists"])
62
+
63
+ assert result.exit_code == 0, result.output
64
+ assert ScrubDurationGithuburlAndSpaces(result.stdout) == snapshot
65
+
66
+ def test_SecurityPolicy(self, pat_args, snapshot):
67
+ """Test if a Security policy file (e.g. SECURITY.md) exists in the repository."""
68
+ result = CliRunner().invoke(app, pat_args + ["--GitHubCustomization-SecurityPolicy-exists"])
69
+
70
+ assert result.exit_code == 0, result.output
71
+ assert ScrubDurationGithuburlAndSpaces(result.stdout) == snapshot
72
+
73
+
74
+ # ----------------------------------------------------------------------
75
+ # ----------------------------------------------------------------------
76
+ # ----------------------------------------------------------------------
77
+ @pytest.fixture
78
+ def args() -> list[str]:
79
+ return [
80
+ "--include",
81
+ "GitHubCustomization",
82
+ "--GitHubCustomization-url",
83
+ GetGithubUrl(),
84
+ ]
85
+
86
+
87
+ # ----------------------------------------------------------------------
88
+ @pytest.fixture
89
+ def pat_args(args) -> list[str]:
90
+ _github_pat_filename = (Path(__file__).parent / "github_pat.txt").resolve()
91
+ CheckPATFileExists(_github_pat_filename)
92
+
93
+ with _github_pat_filename.open() as f:
94
+ pat_value = f.read().strip()
95
+
96
+ return args + ["--GitHubCustomization-pat", pat_value]
@@ -7,8 +7,8 @@
7
7
  """Unit tests for the GitHub Customization Plugin"""
8
8
 
9
9
  import sys
10
- import pytest
11
10
  import pluggy
11
+ from pathlib import Path
12
12
 
13
13
  from RepoAuditor import APP_NAME
14
14
  from RepoAuditor.Plugins.GitHubCustomizationPlugin import GetModule
@@ -54,17 +54,38 @@ def test_plugin_registration():
54
54
 
55
55
 
56
56
  # ----------------------------------------------------------------------
57
- def test_module_initialization():
58
- """Test that the module initializes correctly."""
59
- module = GetModule()
60
-
61
- assert module is not None
62
- assert module.name == "GitHubCustomization"
63
- # Comment out checks that would fail with minimal implementation
64
- # assert module.execution_style.name == "Parallel"
65
- # assert len(module.queries) == 1
66
- # assert isinstance(module.queries[0], CustomizationQuery)
67
- # assert module.requires_explicit_include is False
57
+ class TestGitHubCustomizationModule:
58
+ """Unit tests for the GitHubCustomizaton module."""
59
+
60
+ def test_Construct(self):
61
+ """Test that the module initializes correctly."""
62
+ module = GetModule()
63
+
64
+ assert module is not None
65
+ assert module.name == "GitHubCustomization"
66
+ # Comment out checks that would fail with minimal implementation
67
+ # assert module.execution_style.name == "Parallel"
68
+ # assert len(module.queries) == 1
69
+ # assert isinstance(module.queries[0], CustomizationQuery)
70
+ # assert module.requires_explicit_include is False
71
+
72
+ def test_GetDynamicArgDefinitions(self):
73
+ """Test GetDynamicArgDefinitions method."""
74
+ module = GetModule()
75
+ dynamic_args = module.GetDynamicArgDefinitions()
76
+ # dynamic_args should be empty dict
77
+ assert dynamic_args.keys() == {"url": "", "pat": "", "branch": ""}.keys()
78
+
79
+ def test_GenerateInitialData(self):
80
+ """Test GenerateInitialData method."""
81
+ dynamic_args = {
82
+ "url": "https://github.com/gt-sse-center/RepoAuditor",
83
+ "pat": Path(__file__).parent / "dummy_github_pat.txt",
84
+ }
85
+ module = GetModule()
86
+ updated_dynamic_args = module.GenerateInitialData(dynamic_args)
87
+ # Currently no change in dynamic_args
88
+ assert updated_dynamic_args == dynamic_args
68
89
 
69
90
 
70
91
  # ----------------------------------------------------------------------