RepoAuditor 0.2.23__tar.gz → 0.2.25__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.23 → repoauditor-0.2.25}/.github/workflows/CICD.yml +0 -1
  2. {repoauditor-0.2.23 → repoauditor-0.2.25}/.github/workflows/CICD_impl.yml +1 -24
  3. repoauditor-0.2.25/.github/workflows/EndToEnd.yml +48 -0
  4. {repoauditor-0.2.23 → repoauditor-0.2.25}/PKG-INFO +1 -1
  5. {repoauditor-0.2.23 → repoauditor-0.2.25}/pyproject.toml +2 -1
  6. {repoauditor-0.2.23 → repoauditor-0.2.25}/src/RepoAuditor/Display.py +2 -2
  7. {repoauditor-0.2.23 → repoauditor-0.2.25}/src/RepoAuditor/EntryPoint.py +9 -9
  8. {repoauditor-0.2.23 → repoauditor-0.2.25}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/EnsureStatusChecks.py +1 -1
  9. {repoauditor-0.2.23 → repoauditor-0.2.25}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/Impl/ClassicEnableRequirementImpl.py +1 -1
  10. {repoauditor-0.2.23 → repoauditor-0.2.25}/src/RepoAuditor/Plugins/GitHub/DefaultBranchQueryRequirements/Protected.py +1 -1
  11. {repoauditor-0.2.23 → repoauditor-0.2.25}/src/RepoAuditor/Plugins/GitHub/Impl/EnableRequirementImpl.py +1 -1
  12. {repoauditor-0.2.23 → repoauditor-0.2.25}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/Description.py +1 -1
  13. {repoauditor-0.2.23 → repoauditor-0.2.25}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/Impl/StandardEnableRequirementImpl.py +1 -1
  14. {repoauditor-0.2.23 → repoauditor-0.2.25}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/Private.py +1 -1
  15. repoauditor-0.2.25/src/RepoAuditor/Plugins/GitHubCustomization/CustomizationQuery.py +51 -0
  16. repoauditor-0.2.25/src/RepoAuditor/Plugins/GitHubCustomization/Impl/ExistsRequirementImpl.py +102 -0
  17. {repoauditor-0.2.23 → repoauditor-0.2.25}/src/RepoAuditor/Plugins/GitHubCustomization/Module.py +5 -2
  18. repoauditor-0.2.25/src/RepoAuditor/Plugins/GitHubCustomization/Requirements/CodeOwners.py +56 -0
  19. repoauditor-0.2.25/src/RepoAuditor/Plugins/GitHubCustomization/Requirements/Contributing.py +53 -0
  20. repoauditor-0.2.25/src/RepoAuditor/Plugins/GitHubCustomization/Requirements/IssueTemplates.py +33 -0
  21. repoauditor-0.2.25/src/RepoAuditor/Plugins/GitHubCustomization/Requirements/PullRequestTemplates.py +35 -0
  22. repoauditor-0.2.25/src/RepoAuditor/Plugins/GitHubCustomization/Requirements/SecurityPolicy.py +53 -0
  23. {repoauditor-0.2.23 → repoauditor-0.2.25}/src/RepoAuditor/Plugins/GitHubCustomizationPlugin.py +1 -2
  24. repoauditor-0.2.25/src/RepoAuditor/Plugins/__init__.py +0 -0
  25. {repoauditor-0.2.23 → repoauditor-0.2.25}/src/RepoAuditor/__init__.py +1 -1
  26. repoauditor-0.2.25/src/RepoAuditor/py.typed +0 -0
  27. repoauditor-0.2.25/tests/Plugins/GitHubCustomization_EndToEndTest.py +96 -0
  28. {repoauditor-0.2.23 → repoauditor-0.2.25}/tests/Plugins/GitHubCustomization_UnitTest.py +33 -12
  29. {repoauditor-0.2.23 → repoauditor-0.2.25}/tests/Plugins/GitHub_EndToEndTest.py +3 -4
  30. repoauditor-0.2.25/tests/Plugins/__snapshots__/GitHubCustomization_EndToEndTest.ambr +146 -0
  31. repoauditor-0.2.23/src/RepoAuditor/Plugins/GitHubCustomization/CustomizationQuery.py +0 -20
  32. {repoauditor-0.2.23 → repoauditor-0.2.25}/.copier-answers.yml +0 -0
  33. {repoauditor-0.2.23 → repoauditor-0.2.25}/.github/CODEOWNERS +0 -0
  34. {repoauditor-0.2.23 → repoauditor-0.2.25}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  35. {repoauditor-0.2.23 → repoauditor-0.2.25}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  36. {repoauditor-0.2.23 → repoauditor-0.2.25}/.github/ISSUE_TEMPLATE/custom.md +0 -0
  37. {repoauditor-0.2.23 → repoauditor-0.2.25}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  38. {repoauditor-0.2.23 → repoauditor-0.2.25}/.github/actions/release_impl/action.yml +0 -0
  39. {repoauditor-0.2.23 → repoauditor-0.2.25}/.github/pull_request_template.md +0 -0
  40. {repoauditor-0.2.23 → repoauditor-0.2.25}/.github/release_sources.yaml +0 -0
  41. {repoauditor-0.2.23 → repoauditor-0.2.25}/.github/workflows/codeql.yml +0 -0
  42. {repoauditor-0.2.23 → repoauditor-0.2.25}/.gitignore +0 -0
  43. {repoauditor-0.2.23 → repoauditor-0.2.25}/.pre-commit-config.yaml +0 -0
  44. {repoauditor-0.2.23 → repoauditor-0.2.25}/.python-version +0 -0
  45. {repoauditor-0.2.23 → repoauditor-0.2.25}/CODE_OF_CONDUCT.md +0 -0
  46. {repoauditor-0.2.23 → repoauditor-0.2.25}/CONTRIBUTING.md +0 -0
  47. {repoauditor-0.2.23 → repoauditor-0.2.25}/DEVELOPMENT.md +0 -0
  48. {repoauditor-0.2.23 → repoauditor-0.2.25}/GOVERNANCE.md +0 -0
  49. {repoauditor-0.2.23 → repoauditor-0.2.25}/LICENSE +0 -0
  50. {repoauditor-0.2.23 → repoauditor-0.2.25}/MAINTAINERS.md +0 -0
  51. {repoauditor-0.2.23 → repoauditor-0.2.25}/README.md +0 -0
  52. {repoauditor-0.2.23 → repoauditor-0.2.25}/SECURITY.md +0 -0
  53. {repoauditor-0.2.23 → repoauditor-0.2.25}/minisign_key.pub +0 -0
  54. {repoauditor-0.2.23 → repoauditor-0.2.25}/src/AutoGitSemVer.yaml +0 -0
  55. {repoauditor-0.2.23 → repoauditor-0.2.25}/src/RepoAuditor/CommandLineProcessor.py +0 -0
  56. {repoauditor-0.2.23 → repoauditor-0.2.25}/src/RepoAuditor/ExecuteModules.py +0 -0
  57. {repoauditor-0.2.23 → repoauditor-0.2.25}/src/RepoAuditor/Impl/ParallelSequentialProcessor.py +0 -0
  58. {repoauditor-0.2.23 → repoauditor-0.2.25}/src/RepoAuditor/Impl/__init__.py +0 -0
  59. {repoauditor-0.2.23 → repoauditor-0.2.25}/src/RepoAuditor/Module.py +0 -0
  60. {repoauditor-0.2.23 → repoauditor-0.2.25}/src/RepoAuditor/Plugin.py +0 -0
  61. {repoauditor-0.2.23 → repoauditor-0.2.25}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionQuery.py +0 -0
  62. {repoauditor-0.2.23 → repoauditor-0.2.25}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/AllowDeletions.py +0 -0
  63. {repoauditor-0.2.23 → repoauditor-0.2.25}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/AllowForcePushes.py +0 -0
  64. {repoauditor-0.2.23 → repoauditor-0.2.25}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/DismissStalePullRequestApprovals.py +0 -0
  65. {repoauditor-0.2.23 → repoauditor-0.2.25}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/DoNotAllowBypassSettings.py +0 -0
  66. {repoauditor-0.2.23 → repoauditor-0.2.25}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/Impl/ClassicValueRequirementImpl.py +0 -0
  67. {repoauditor-0.2.23 → repoauditor-0.2.25}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/Impl/__init__.py +0 -0
  68. {repoauditor-0.2.23 → repoauditor-0.2.25}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/RequireApprovalMostRecentPush.py +0 -0
  69. {repoauditor-0.2.23 → repoauditor-0.2.25}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/RequireApprovals.py +0 -0
  70. {repoauditor-0.2.23 → repoauditor-0.2.25}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/RequireCodeOwnerReview.py +0 -0
  71. {repoauditor-0.2.23 → repoauditor-0.2.25}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/RequireConversationResolution.py +0 -0
  72. {repoauditor-0.2.23 → repoauditor-0.2.25}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/RequireLinearHistory.py +0 -0
  73. {repoauditor-0.2.23 → repoauditor-0.2.25}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/RequirePullRequests.py +0 -0
  74. {repoauditor-0.2.23 → repoauditor-0.2.25}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/RequireSignedCommits.py +0 -0
  75. {repoauditor-0.2.23 → repoauditor-0.2.25}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/RequireStatusChecksToPass.py +0 -0
  76. {repoauditor-0.2.23 → repoauditor-0.2.25}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/RequireUpToDateBranches.py +0 -0
  77. {repoauditor-0.2.23 → repoauditor-0.2.25}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/__init__.py +0 -0
  78. {repoauditor-0.2.23 → repoauditor-0.2.25}/src/RepoAuditor/Plugins/GitHub/DefaultBranchQuery.py +0 -0
  79. {repoauditor-0.2.23 → repoauditor-0.2.25}/src/RepoAuditor/Plugins/GitHub/DefaultBranchQueryRequirements/__init__.py +0 -0
  80. {repoauditor-0.2.23 → repoauditor-0.2.25}/src/RepoAuditor/Plugins/GitHub/Impl/Common.py +0 -0
  81. {repoauditor-0.2.23 → repoauditor-0.2.25}/src/RepoAuditor/Plugins/GitHub/Impl/ValueRequirementImpl.py +0 -0
  82. {repoauditor-0.2.23 → repoauditor-0.2.25}/src/RepoAuditor/Plugins/GitHub/Impl/__init__.py +0 -0
  83. {repoauditor-0.2.23 → repoauditor-0.2.25}/src/RepoAuditor/Plugins/GitHub/Module.py +0 -0
  84. {repoauditor-0.2.23 → repoauditor-0.2.25}/src/RepoAuditor/Plugins/GitHub/StandardQuery.py +0 -0
  85. {repoauditor-0.2.23 → repoauditor-0.2.25}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/AutoMerge.py +0 -0
  86. {repoauditor-0.2.23 → repoauditor-0.2.25}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/DefaultBranch.py +0 -0
  87. {repoauditor-0.2.23 → repoauditor-0.2.25}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/DeleteHeadBranches.py +0 -0
  88. {repoauditor-0.2.23 → repoauditor-0.2.25}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/DependabotSecurityUpdates.py +0 -0
  89. {repoauditor-0.2.23 → repoauditor-0.2.25}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/Impl/StandardValueRequirementImpl.py +0 -0
  90. {repoauditor-0.2.23 → repoauditor-0.2.25}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/Impl/__init__.py +0 -0
  91. {repoauditor-0.2.23 → repoauditor-0.2.25}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/License.py +0 -0
  92. {repoauditor-0.2.23 → repoauditor-0.2.25}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/MergeCommit.py +0 -0
  93. {repoauditor-0.2.23 → repoauditor-0.2.25}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/MergeCommitMessage.py +0 -0
  94. {repoauditor-0.2.23 → repoauditor-0.2.25}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/RebaseMergeCommit.py +0 -0
  95. {repoauditor-0.2.23 → repoauditor-0.2.25}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/SecretScanning.py +0 -0
  96. {repoauditor-0.2.23 → repoauditor-0.2.25}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/SecretScanningPushProtection.py +0 -0
  97. {repoauditor-0.2.23 → repoauditor-0.2.25}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/SquashCommitMerge.py +0 -0
  98. {repoauditor-0.2.23 → repoauditor-0.2.25}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/SquashMergeCommitMessage.py +0 -0
  99. {repoauditor-0.2.23 → repoauditor-0.2.25}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/SuggestUpdatingPullRequestBranches.py +0 -0
  100. {repoauditor-0.2.23 → repoauditor-0.2.25}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/SupportDiscussions.py +0 -0
  101. {repoauditor-0.2.23 → repoauditor-0.2.25}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/SupportIssues.py +0 -0
  102. {repoauditor-0.2.23 → repoauditor-0.2.25}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/SupportProjects.py +0 -0
  103. {repoauditor-0.2.23 → repoauditor-0.2.25}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/SupportWikis.py +0 -0
  104. {repoauditor-0.2.23 → repoauditor-0.2.25}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/TemplateRepository.py +0 -0
  105. {repoauditor-0.2.23 → repoauditor-0.2.25}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/WebCommitSignoff.py +0 -0
  106. {repoauditor-0.2.23 → repoauditor-0.2.25}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/__init__.py +0 -0
  107. {repoauditor-0.2.23 → repoauditor-0.2.25}/src/RepoAuditor/Plugins/GitHub/__init__.py +0 -0
  108. {repoauditor-0.2.23 → repoauditor-0.2.25}/src/RepoAuditor/Plugins/GitHubBase/Module.py +0 -0
  109. {repoauditor-0.2.23 → repoauditor-0.2.25}/src/RepoAuditor/Plugins/GitHubBase/__init__.py +0 -0
  110. {repoauditor-0.2.23/src/RepoAuditor/Plugins/GitHubCustomization → repoauditor-0.2.25/src/RepoAuditor/Plugins/GitHubCustomization/Impl}/__init__.py +0 -0
  111. {repoauditor-0.2.23/src/RepoAuditor/Plugins → repoauditor-0.2.25/src/RepoAuditor/Plugins/GitHubCustomization/Requirements}/__init__.py +0 -0
  112. /repoauditor-0.2.23/src/RepoAuditor/py.typed → /repoauditor-0.2.25/src/RepoAuditor/Plugins/GitHubCustomization/__init__.py +0 -0
  113. {repoauditor-0.2.23 → repoauditor-0.2.25}/src/RepoAuditor/Plugins/GitHubPlugin.py +0 -0
  114. {repoauditor-0.2.23 → repoauditor-0.2.25}/src/RepoAuditor/Query.py +0 -0
  115. {repoauditor-0.2.23 → repoauditor-0.2.25}/src/RepoAuditor/Requirement.py +0 -0
  116. {repoauditor-0.2.23 → repoauditor-0.2.25}/tests/CommandLineProcessor_UnitTest.py +0 -0
  117. {repoauditor-0.2.23 → repoauditor-0.2.25}/tests/EntryPoint_UnitTest.py +0 -0
  118. {repoauditor-0.2.23 → repoauditor-0.2.25}/tests/ExecuteModules_UnitTest.py +0 -0
  119. {repoauditor-0.2.23 → repoauditor-0.2.25}/tests/Module_UnitTest.py +0 -0
  120. {repoauditor-0.2.23 → repoauditor-0.2.25}/tests/Plugin_UnitTest.py +0 -0
  121. {repoauditor-0.2.23 → repoauditor-0.2.25}/tests/Plugins/GitHubModule_UnitTest.py +0 -0
  122. {repoauditor-0.2.23 → repoauditor-0.2.25}/tests/Plugins/__snapshots__/GitHub_EndToEndTest.ambr +0 -0
  123. {repoauditor-0.2.23 → repoauditor-0.2.25}/tests/Plugins/utilities.py +0 -0
  124. {repoauditor-0.2.23 → repoauditor-0.2.25}/tests/Query_UnitTest.py +0 -0
  125. {repoauditor-0.2.23 → repoauditor-0.2.25}/tests/Requirement_UnitTest.py +0 -0
  126. {repoauditor-0.2.23 → repoauditor-0.2.25}/tests/__snapshots__/ExecuteModules_UnitTest.ambr +0 -0
  127. {repoauditor-0.2.23 → repoauditor-0.2.25}/uv.lock +0 -0
@@ -36,4 +36,3 @@ jobs:
36
36
  MINISIGN_PRIVATE_KEY: ${{ secrets.MINISIGN_PRIVATE_KEY }}
37
37
  PYPI_PUBLISH_TOKEN: ${{ secrets.PYPI_PUBLISH_TOKEN }}
38
38
  COVERAGE_BADGE_GIST_TOKEN: ${{ secrets.COVERAGE_BADGE_GIST_TOKEN }}
39
- TESTING_GITHUB_PAT: ${{ secrets.TESTING_GITHUB_PAT }}
@@ -41,10 +41,6 @@ on:
41
41
  required: false
42
42
  description: "Token used to access the Gist used to store coverage badge information. Code coverage information will not be persisted if this value is missing."
43
43
 
44
- TESTING_GITHUB_PAT:
45
- required: true
46
- description: "GitHub PAT used by tests to access the repository. This value is required."
47
-
48
44
  jobs:
49
45
  # ----------------------------------------------------------------------
50
46
  validate:
@@ -70,30 +66,11 @@ jobs:
70
66
  python-version: ${{ matrix.python_version }}
71
67
  enable-cache: true
72
68
 
73
- # Ensure that the github PAT is available for the tests
74
- - name: Create github_pat.txt
75
- run: |
76
- echo ${{ secrets.TESTING_GITHUB_PAT }} > tests/Plugins/github_pat.txt
77
-
78
- - name: Environment Variables (!Windows)
79
- shell: bash
80
- if: ${{ ! startsWith(matrix.os, 'windows') }}
81
- run: |
82
- echo "GITHUB_CI_OPERATING_SYSTEM=${{ matrix.os }}" >> $GITHUB_ENV
83
- echo "GITHUB_CI_PYTHON_VERSION=${{ matrix.python_version }}" >> $GITHUB_ENV
84
-
85
- - name: Environment Variables (Windows)
86
- shell: cmd
87
- if: ${{ startsWith(matrix.os, 'windows') }}
88
- run: |
89
- echo GITHUB_CI_OPERATING_SYSTEM=${{ matrix.os }} >> %GITHUB_ENV%
90
- echo GITHUB_CI_PYTHON_VERSION=${{ matrix.python_version }} >> %GITHUB_ENV%
91
-
92
69
  - name: Run pre-commit scripts
93
70
  run: uv run pre-commit run --verbose
94
71
 
95
72
  - name: Validate Tests
96
- run: uv run pytest
73
+ run: uv run pytest -k 'not EndToEndTest' --cov-fail-under=80.0
97
74
  env:
98
75
  COVERAGE_FILE: .coverage.${{ matrix.os }}.${{ matrix.python_version }}
99
76
 
@@ -0,0 +1,48 @@
1
+ name: "End To End Tests"
2
+ run-name: EndToEnd ${{ github.run_number }} [${{ github.actor }}] on ${{ github.ref_name }}
3
+
4
+ on:
5
+ schedule:
6
+ - cron: '0 * * * *' # Once every hour
7
+ workflow_dispatch:
8
+
9
+ jobs:
10
+ validate:
11
+ strategy:
12
+ fail-fast: false
13
+
14
+ matrix:
15
+ # Since the system under test here is the GitHub API, it is sufficient to test using only a single OS.
16
+ os: ["ubuntu-latest"]
17
+ # Similar to OS, we only test the lowest and highest supported versions.
18
+ python_version: ["3.10", "3.13"]
19
+
20
+ name: Validate
21
+ runs-on: ${{ matrix.os }}
22
+
23
+ permissions:
24
+ contents: read
25
+
26
+ steps:
27
+ - uses: actions/checkout@v4
28
+
29
+ - name: Install uv and python
30
+ uses: astral-sh/setup-uv@v5
31
+ with:
32
+ python-version: ${{ matrix.python_version }}
33
+ enable-cache: true
34
+
35
+ # Ensure that the github PAT is available for the tests
36
+ # GitHub PAT used by tests to access the repository.
37
+ - name: Create github_pat.txt
38
+ run: |
39
+ echo ${{ secrets.TESTING_GITHUB_PAT }} > tests/Plugins/github_pat.txt
40
+
41
+ - name: Environment Variables
42
+ shell: bash
43
+ run: |
44
+ echo "GITHUB_CI_OPERATING_SYSTEM=${{ matrix.os }}" >> $GITHUB_ENV
45
+ echo "GITHUB_CI_PYTHON_VERSION=${{ matrix.python_version }}" >> $GITHUB_ENV
46
+
47
+ - name: Validate Tests
48
+ run: uv run pytest -k EndToEndTest --no-cov
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: RepoAuditor
3
- Version: 0.2.23
3
+ Version: 0.2.25
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
@@ -83,7 +83,7 @@ select = [
83
83
  "ASYNC",
84
84
  "S",
85
85
  "BLE",
86
- # "FBT", # 44
86
+ "FBT",
87
87
  "B",
88
88
  "A",
89
89
  "COM",
@@ -148,6 +148,7 @@ ignore = [
148
148
  "D107", # Missing docstring in `__init__` method
149
149
  "D202", # No blank lines allowed after function docstring
150
150
  "E501", # Line too long
151
+ "FBT003", # Boolean positional argument in function call
151
152
  "I001", # Import block is un-sorted or un-formatted
152
153
  "N802", # Function name `xxx` should be lowercase
153
154
  "N999", # Invalid module name
@@ -21,8 +21,8 @@ from .Module import EvaluateResult, Module
21
21
  def GetInternalPanelContent(
22
22
  dm: DoneManager,
23
23
  results: list[Module.EvaluateInfo],
24
- display_resolution: bool,
25
- display_rationale: bool,
24
+ display_resolution: bool, # noqa: FBT001
25
+ display_rationale: bool, # noqa: FBT001
26
26
  num_success: int,
27
27
  num_warning: int,
28
28
  num_error: int,
@@ -168,7 +168,7 @@ def _HelpEpilog() -> str:
168
168
 
169
169
 
170
170
  # ----------------------------------------------------------------------
171
- def _VersionCallback(value: bool) -> None:
171
+ def _VersionCallback(value: bool) -> None: # noqa: FBT001
172
172
  if value:
173
173
  sys.stdout.write(f"RepoAuditor v{__version__}\n")
174
174
  raise typer.Exit()
@@ -184,7 +184,7 @@ def _VersionCallback(value: bool) -> None:
184
184
  )
185
185
  def EntryPoint(
186
186
  ctx: typer.Context,
187
- version: Annotated[ # noqa: ARG001
187
+ version: Annotated[ # noqa: ARG001, FBT002
188
188
  bool,
189
189
  typer.Option(
190
190
  "--version",
@@ -221,38 +221,38 @@ def EntryPoint(
221
221
  help="Name of a module whose warnings should be ignored. This value can be provided multiple times.",
222
222
  ),
223
223
  ] = None,
224
- all_warnings_as_error: Annotated[
224
+ all_warnings_as_error: Annotated[ # noqa: FBT002
225
225
  bool, typer.Option("--all-warnings-as-error", help="Treat all warnings as errors.")
226
226
  ] = False,
227
- ignore_all_warnings: Annotated[
227
+ ignore_all_warnings: Annotated[ # noqa: FBT002
228
228
  bool, typer.Option("--ignore-all-warnings", help="Ignore all warnings.")
229
229
  ] = False,
230
- single_threaded: Annotated[
230
+ single_threaded: Annotated[ # noqa: FBT002
231
231
  bool,
232
232
  typer.Option("--single-threaded", help="Do not use multiple threads when evaluating requirements."),
233
233
  ] = False,
234
- no_resolution: Annotated[
234
+ no_resolution: Annotated[ # noqa: FBT002
235
235
  bool,
236
236
  typer.Option(
237
237
  "--no-resolution",
238
238
  help="Do not display resolution information for requirements that are not successful.",
239
239
  ),
240
240
  ] = False,
241
- no_rationale: Annotated[
241
+ no_rationale: Annotated[ # noqa: FBT002
242
242
  bool,
243
243
  typer.Option(
244
244
  "--no-rationale",
245
245
  help="Do not display rationale information for requirements that are not successful.",
246
246
  ),
247
247
  ] = False,
248
- verbose: Annotated[
248
+ verbose: Annotated[ # noqa: FBT002
249
249
  bool,
250
250
  typer.Option(
251
251
  "--verbose",
252
252
  help="Write verbose information to the terminal.",
253
253
  ),
254
254
  ] = False,
255
- debug: Annotated[
255
+ debug: Annotated[ # noqa: FBT002
256
256
  bool,
257
257
  typer.Option(
258
258
  "--debug",
@@ -61,7 +61,7 @@ class EnsureStatusChecks(Requirement):
61
61
  "disable": (
62
62
  bool,
63
63
  typer.Option(
64
- False,
64
+ default=False,
65
65
  help="If set, status checks will not be enforced.",
66
66
  ),
67
67
  ),
@@ -22,7 +22,7 @@ class ClassicEnableRequirementImpl(EnableRequirementImpl):
22
22
  def __init__(
23
23
  self,
24
24
  name: str,
25
- default_value: bool,
25
+ default_value: bool, # noqa: FBT001
26
26
  dynamic_arg_name: str,
27
27
  github_settings_section: str,
28
28
  github_settings_value: str,
@@ -60,7 +60,7 @@ class Protected(Requirement):
60
60
  "false": (
61
61
  bool,
62
62
  typer.Option(
63
- False,
63
+ default=False,
64
64
  help="Allow an unprotected mainline branch.",
65
65
  ),
66
66
  ),
@@ -27,7 +27,7 @@ class EnableRequirementImpl(Requirement):
27
27
  def __init__(
28
28
  self,
29
29
  name: str,
30
- default_value: bool,
30
+ default_value: bool, # noqa: FBT001
31
31
  dynamic_arg_name: str,
32
32
  github_settings_value: str,
33
33
  get_configuration_value_func: Callable[[dict[str, Any]], Optional[bool]],
@@ -60,7 +60,7 @@ class Description(Requirement):
60
60
  "allow-empty": (
61
61
  bool,
62
62
  typer.Option(
63
- False,
63
+ default=False,
64
64
  help="Allow an empty repository description.",
65
65
  ),
66
66
  ),
@@ -22,7 +22,7 @@ class StandardEnableRequirementImpl(EnableRequirementImpl):
22
22
  def __init__(
23
23
  self,
24
24
  name: str,
25
- default_value: bool,
25
+ default_value: bool, # noqa: FBT001
26
26
  dynamic_arg_name: str,
27
27
  github_settings_url_suffix: str,
28
28
  github_settings_section: str,
@@ -59,7 +59,7 @@ class Private(Requirement):
59
59
  "true": (
60
60
  bool,
61
61
  typer.Option(
62
- False,
62
+ default=False,
63
63
  help="Ensures that the repository's visibility is set to private.",
64
64
  ),
65
65
  ),
@@ -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
+ )