RepoAuditor 0.2.76__tar.gz → 0.2.77__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 (168) hide show
  1. {repoauditor-0.2.76 → repoauditor-0.2.77}/PKG-INFO +1 -1
  2. {repoauditor-0.2.76 → repoauditor-0.2.77}/src/RepoAuditor/Display.py +17 -2
  3. {repoauditor-0.2.76 → repoauditor-0.2.77}/src/RepoAuditor/EntryPoint.py +23 -12
  4. {repoauditor-0.2.76 → repoauditor-0.2.77}/src/RepoAuditor/__init__.py +1 -1
  5. {repoauditor-0.2.76 → repoauditor-0.2.77}/tests/Plugins/GitHub_EndToEndTest.py +11 -0
  6. {repoauditor-0.2.76 → repoauditor-0.2.77}/tests/Plugins/__snapshots__/GitHub_EndToEndTest.ambr +232 -0
  7. {repoauditor-0.2.76 → repoauditor-0.2.77}/.copier-answers.yml +0 -0
  8. {repoauditor-0.2.76 → repoauditor-0.2.77}/.github/CODEOWNERS +0 -0
  9. {repoauditor-0.2.76 → repoauditor-0.2.77}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  10. {repoauditor-0.2.76 → repoauditor-0.2.77}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  11. {repoauditor-0.2.76 → repoauditor-0.2.77}/.github/ISSUE_TEMPLATE/custom.md +0 -0
  12. {repoauditor-0.2.76 → repoauditor-0.2.77}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  13. {repoauditor-0.2.76 → repoauditor-0.2.77}/.github/actions/release_impl/action.yml +0 -0
  14. {repoauditor-0.2.76 → repoauditor-0.2.77}/.github/pull_request_template.md +0 -0
  15. {repoauditor-0.2.76 → repoauditor-0.2.77}/.github/release_sources.yaml +0 -0
  16. {repoauditor-0.2.76 → repoauditor-0.2.77}/.github/workflows/CICD.yml +0 -0
  17. {repoauditor-0.2.76 → repoauditor-0.2.77}/.github/workflows/CICD_impl.yml +0 -0
  18. {repoauditor-0.2.76 → repoauditor-0.2.77}/.github/workflows/EndToEnd.yml +0 -0
  19. {repoauditor-0.2.76 → repoauditor-0.2.77}/.github/workflows/codeql.yml +0 -0
  20. {repoauditor-0.2.76 → repoauditor-0.2.77}/.gitignore +0 -0
  21. {repoauditor-0.2.76 → repoauditor-0.2.77}/.pre-commit-config.yaml +0 -0
  22. {repoauditor-0.2.76 → repoauditor-0.2.77}/.python-version +0 -0
  23. {repoauditor-0.2.76 → repoauditor-0.2.77}/CODE_OF_CONDUCT.md +0 -0
  24. {repoauditor-0.2.76 → repoauditor-0.2.77}/CONTRIBUTING.md +0 -0
  25. {repoauditor-0.2.76 → repoauditor-0.2.77}/DEVELOPMENT.md +0 -0
  26. {repoauditor-0.2.76 → repoauditor-0.2.77}/GOVERNANCE.md +0 -0
  27. {repoauditor-0.2.76 → repoauditor-0.2.77}/LICENSE +0 -0
  28. {repoauditor-0.2.76 → repoauditor-0.2.77}/MAINTAINERS.md +0 -0
  29. {repoauditor-0.2.76 → repoauditor-0.2.77}/README.md +0 -0
  30. {repoauditor-0.2.76 → repoauditor-0.2.77}/SECURITY.md +0 -0
  31. {repoauditor-0.2.76 → repoauditor-0.2.77}/default_config.yaml +0 -0
  32. {repoauditor-0.2.76 → repoauditor-0.2.77}/minisign_key.pub +0 -0
  33. {repoauditor-0.2.76 → repoauditor-0.2.77}/pyproject.toml +0 -0
  34. {repoauditor-0.2.76 → repoauditor-0.2.77}/src/AutoGitSemVer.yaml +0 -0
  35. {repoauditor-0.2.76 → repoauditor-0.2.77}/src/RepoAuditor/CommandLineProcessor.py +0 -0
  36. {repoauditor-0.2.76 → repoauditor-0.2.77}/src/RepoAuditor/ExecuteModules.py +0 -0
  37. {repoauditor-0.2.76 → repoauditor-0.2.77}/src/RepoAuditor/Impl/ParallelSequentialProcessor.py +0 -0
  38. {repoauditor-0.2.76 → repoauditor-0.2.77}/src/RepoAuditor/Impl/__init__.py +0 -0
  39. {repoauditor-0.2.76 → repoauditor-0.2.77}/src/RepoAuditor/Module.py +0 -0
  40. {repoauditor-0.2.76 → repoauditor-0.2.77}/src/RepoAuditor/Plugin.py +0 -0
  41. {repoauditor-0.2.76 → repoauditor-0.2.77}/src/RepoAuditor/Plugins/CommunityStandards/CommunityStandardsQuery.py +0 -0
  42. {repoauditor-0.2.76 → repoauditor-0.2.77}/src/RepoAuditor/Plugins/CommunityStandards/Impl/ExistsRequirementImpl.py +0 -0
  43. {repoauditor-0.2.76 → repoauditor-0.2.77}/src/RepoAuditor/Plugins/CommunityStandards/Impl/__init__.py +0 -0
  44. {repoauditor-0.2.76 → repoauditor-0.2.77}/src/RepoAuditor/Plugins/CommunityStandards/Module.py +0 -0
  45. {repoauditor-0.2.76 → repoauditor-0.2.77}/src/RepoAuditor/Plugins/CommunityStandards/Requirements/CodeOfConduct.py +0 -0
  46. {repoauditor-0.2.76 → repoauditor-0.2.77}/src/RepoAuditor/Plugins/CommunityStandards/Requirements/CodeOwners.py +0 -0
  47. {repoauditor-0.2.76 → repoauditor-0.2.77}/src/RepoAuditor/Plugins/CommunityStandards/Requirements/Contributing.py +0 -0
  48. {repoauditor-0.2.76 → repoauditor-0.2.77}/src/RepoAuditor/Plugins/CommunityStandards/Requirements/IssueTemplates.py +0 -0
  49. {repoauditor-0.2.76 → repoauditor-0.2.77}/src/RepoAuditor/Plugins/CommunityStandards/Requirements/LicenseFile.py +0 -0
  50. {repoauditor-0.2.76 → repoauditor-0.2.77}/src/RepoAuditor/Plugins/CommunityStandards/Requirements/PullRequestTemplates.py +0 -0
  51. {repoauditor-0.2.76 → repoauditor-0.2.77}/src/RepoAuditor/Plugins/CommunityStandards/Requirements/ReadMe.py +0 -0
  52. {repoauditor-0.2.76 → repoauditor-0.2.77}/src/RepoAuditor/Plugins/CommunityStandards/Requirements/SecurityPolicy.py +0 -0
  53. {repoauditor-0.2.76 → repoauditor-0.2.77}/src/RepoAuditor/Plugins/CommunityStandards/Requirements/__init__.py +0 -0
  54. {repoauditor-0.2.76 → repoauditor-0.2.77}/src/RepoAuditor/Plugins/CommunityStandards/__init__.py +0 -0
  55. {repoauditor-0.2.76 → repoauditor-0.2.77}/src/RepoAuditor/Plugins/CommunityStandardsPlugin.py +0 -0
  56. {repoauditor-0.2.76 → repoauditor-0.2.77}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionQuery.py +0 -0
  57. {repoauditor-0.2.76 → repoauditor-0.2.77}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/AllowDeletions.py +0 -0
  58. {repoauditor-0.2.76 → repoauditor-0.2.77}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/AllowMainlineForcePushes.py +0 -0
  59. {repoauditor-0.2.76 → repoauditor-0.2.77}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/DismissStalePullRequestApprovals.py +0 -0
  60. {repoauditor-0.2.76 → repoauditor-0.2.77}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/DoNotAllowBypassSettings.py +0 -0
  61. {repoauditor-0.2.76 → repoauditor-0.2.77}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/EnsureStatusChecks.py +0 -0
  62. {repoauditor-0.2.76 → repoauditor-0.2.77}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/Impl/ClassicEnableRequirementImpl.py +0 -0
  63. {repoauditor-0.2.76 → repoauditor-0.2.77}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/Impl/ClassicValueRequirementImpl.py +0 -0
  64. {repoauditor-0.2.76 → repoauditor-0.2.77}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/Impl/__init__.py +0 -0
  65. {repoauditor-0.2.76 → repoauditor-0.2.77}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/RequireApprovalMostRecentPush.py +0 -0
  66. {repoauditor-0.2.76 → repoauditor-0.2.77}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/RequireApprovals.py +0 -0
  67. {repoauditor-0.2.76 → repoauditor-0.2.77}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/RequireCodeOwnerReview.py +0 -0
  68. {repoauditor-0.2.76 → repoauditor-0.2.77}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/RequireConversationResolution.py +0 -0
  69. {repoauditor-0.2.76 → repoauditor-0.2.77}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/RequireLinearHistory.py +0 -0
  70. {repoauditor-0.2.76 → repoauditor-0.2.77}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/RequirePullRequests.py +0 -0
  71. {repoauditor-0.2.76 → repoauditor-0.2.77}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/RequireSignedCommits.py +0 -0
  72. {repoauditor-0.2.76 → repoauditor-0.2.77}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/RequireStatusChecksToPass.py +0 -0
  73. {repoauditor-0.2.76 → repoauditor-0.2.77}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/RequireUpToDateBranches.py +0 -0
  74. {repoauditor-0.2.76 → repoauditor-0.2.77}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/__init__.py +0 -0
  75. {repoauditor-0.2.76 → repoauditor-0.2.77}/src/RepoAuditor/Plugins/GitHub/DefaultBranchQuery.py +0 -0
  76. {repoauditor-0.2.76 → repoauditor-0.2.77}/src/RepoAuditor/Plugins/GitHub/DefaultBranchRequirements/Protected.py +0 -0
  77. {repoauditor-0.2.76 → repoauditor-0.2.77}/src/RepoAuditor/Plugins/GitHub/DefaultBranchRequirements/__init__.py +0 -0
  78. {repoauditor-0.2.76 → repoauditor-0.2.77}/src/RepoAuditor/Plugins/GitHub/Impl/Common.py +0 -0
  79. {repoauditor-0.2.76 → repoauditor-0.2.77}/src/RepoAuditor/Plugins/GitHub/Impl/EnableRequirementImpl.py +0 -0
  80. {repoauditor-0.2.76 → repoauditor-0.2.77}/src/RepoAuditor/Plugins/GitHub/Impl/EnableRulesetRequirementImpl.py +0 -0
  81. {repoauditor-0.2.76 → repoauditor-0.2.77}/src/RepoAuditor/Plugins/GitHub/Impl/ValueRequirementImpl.py +0 -0
  82. {repoauditor-0.2.76 → repoauditor-0.2.77}/src/RepoAuditor/Plugins/GitHub/Impl/__init__.py +0 -0
  83. {repoauditor-0.2.76 → repoauditor-0.2.77}/src/RepoAuditor/Plugins/GitHub/Module.py +0 -0
  84. {repoauditor-0.2.76 → repoauditor-0.2.77}/src/RepoAuditor/Plugins/GitHub/RulesetQuery.py +0 -0
  85. {repoauditor-0.2.76 → repoauditor-0.2.77}/src/RepoAuditor/Plugins/GitHub/RulesetRequirements/RequirePullRequests.py +0 -0
  86. {repoauditor-0.2.76 → repoauditor-0.2.77}/src/RepoAuditor/Plugins/GitHub/RulesetRequirements/RequireSignedCommits.py +0 -0
  87. {repoauditor-0.2.76 → repoauditor-0.2.77}/src/RepoAuditor/Plugins/GitHub/RulesetRequirements/RequireStatusChecks.py +0 -0
  88. {repoauditor-0.2.76 → repoauditor-0.2.77}/src/RepoAuditor/Plugins/GitHub/RulesetRequirements/__init__.py +0 -0
  89. {repoauditor-0.2.76 → repoauditor-0.2.77}/src/RepoAuditor/Plugins/GitHub/StandardQuery.py +0 -0
  90. {repoauditor-0.2.76 → repoauditor-0.2.77}/src/RepoAuditor/Plugins/GitHub/StandardRequirements/AutoMerge.py +0 -0
  91. {repoauditor-0.2.76 → repoauditor-0.2.77}/src/RepoAuditor/Plugins/GitHub/StandardRequirements/DefaultBranch.py +0 -0
  92. {repoauditor-0.2.76 → repoauditor-0.2.77}/src/RepoAuditor/Plugins/GitHub/StandardRequirements/DeleteHeadBranches.py +0 -0
  93. {repoauditor-0.2.76 → repoauditor-0.2.77}/src/RepoAuditor/Plugins/GitHub/StandardRequirements/DependabotSecurityUpdates.py +0 -0
  94. {repoauditor-0.2.76 → repoauditor-0.2.77}/src/RepoAuditor/Plugins/GitHub/StandardRequirements/Description.py +0 -0
  95. {repoauditor-0.2.76 → repoauditor-0.2.77}/src/RepoAuditor/Plugins/GitHub/StandardRequirements/Impl/StandardEnableRequirementImpl.py +0 -0
  96. {repoauditor-0.2.76 → repoauditor-0.2.77}/src/RepoAuditor/Plugins/GitHub/StandardRequirements/Impl/StandardValueRequirementImpl.py +0 -0
  97. {repoauditor-0.2.76 → repoauditor-0.2.77}/src/RepoAuditor/Plugins/GitHub/StandardRequirements/Impl/__init__.py +0 -0
  98. {repoauditor-0.2.76 → repoauditor-0.2.77}/src/RepoAuditor/Plugins/GitHub/StandardRequirements/License.py +0 -0
  99. {repoauditor-0.2.76 → repoauditor-0.2.77}/src/RepoAuditor/Plugins/GitHub/StandardRequirements/MergeCommit.py +0 -0
  100. {repoauditor-0.2.76 → repoauditor-0.2.77}/src/RepoAuditor/Plugins/GitHub/StandardRequirements/MergeCommitMessage.py +0 -0
  101. {repoauditor-0.2.76 → repoauditor-0.2.77}/src/RepoAuditor/Plugins/GitHub/StandardRequirements/Private.py +0 -0
  102. {repoauditor-0.2.76 → repoauditor-0.2.77}/src/RepoAuditor/Plugins/GitHub/StandardRequirements/RebaseMergeCommit.py +0 -0
  103. {repoauditor-0.2.76 → repoauditor-0.2.77}/src/RepoAuditor/Plugins/GitHub/StandardRequirements/SecretScanning.py +0 -0
  104. {repoauditor-0.2.76 → repoauditor-0.2.77}/src/RepoAuditor/Plugins/GitHub/StandardRequirements/SecretScanningPushProtection.py +0 -0
  105. {repoauditor-0.2.76 → repoauditor-0.2.77}/src/RepoAuditor/Plugins/GitHub/StandardRequirements/SquashCommitMerge.py +0 -0
  106. {repoauditor-0.2.76 → repoauditor-0.2.77}/src/RepoAuditor/Plugins/GitHub/StandardRequirements/SquashMergeCommitMessage.py +0 -0
  107. {repoauditor-0.2.76 → repoauditor-0.2.77}/src/RepoAuditor/Plugins/GitHub/StandardRequirements/SuggestUpdatingPullRequestBranches.py +0 -0
  108. {repoauditor-0.2.76 → repoauditor-0.2.77}/src/RepoAuditor/Plugins/GitHub/StandardRequirements/SupportDiscussions.py +0 -0
  109. {repoauditor-0.2.76 → repoauditor-0.2.77}/src/RepoAuditor/Plugins/GitHub/StandardRequirements/SupportIssues.py +0 -0
  110. {repoauditor-0.2.76 → repoauditor-0.2.77}/src/RepoAuditor/Plugins/GitHub/StandardRequirements/SupportProjects.py +0 -0
  111. {repoauditor-0.2.76 → repoauditor-0.2.77}/src/RepoAuditor/Plugins/GitHub/StandardRequirements/SupportWikis.py +0 -0
  112. {repoauditor-0.2.76 → repoauditor-0.2.77}/src/RepoAuditor/Plugins/GitHub/StandardRequirements/TemplateRepository.py +0 -0
  113. {repoauditor-0.2.76 → repoauditor-0.2.77}/src/RepoAuditor/Plugins/GitHub/StandardRequirements/WebCommitSignoff.py +0 -0
  114. {repoauditor-0.2.76 → repoauditor-0.2.77}/src/RepoAuditor/Plugins/GitHub/StandardRequirements/__init__.py +0 -0
  115. {repoauditor-0.2.76 → repoauditor-0.2.77}/src/RepoAuditor/Plugins/GitHub/__init__.py +0 -0
  116. {repoauditor-0.2.76 → repoauditor-0.2.77}/src/RepoAuditor/Plugins/GitHubBase/Module.py +0 -0
  117. {repoauditor-0.2.76 → repoauditor-0.2.77}/src/RepoAuditor/Plugins/GitHubBase/__init__.py +0 -0
  118. {repoauditor-0.2.76 → repoauditor-0.2.77}/src/RepoAuditor/Plugins/GitHubPlugin.py +0 -0
  119. {repoauditor-0.2.76 → repoauditor-0.2.77}/src/RepoAuditor/Plugins/__init__.py +0 -0
  120. {repoauditor-0.2.76 → repoauditor-0.2.77}/src/RepoAuditor/Query.py +0 -0
  121. {repoauditor-0.2.76 → repoauditor-0.2.77}/src/RepoAuditor/Requirement.py +0 -0
  122. {repoauditor-0.2.76 → repoauditor-0.2.77}/src/RepoAuditor/py.typed +0 -0
  123. {repoauditor-0.2.76 → repoauditor-0.2.77}/tests/CommandLineProcessor_UnitTest.py +0 -0
  124. {repoauditor-0.2.76 → repoauditor-0.2.77}/tests/EntryPoint_UnitTest.py +0 -0
  125. {repoauditor-0.2.76 → repoauditor-0.2.77}/tests/ExecuteModules_UnitTest.py +0 -0
  126. {repoauditor-0.2.76 → repoauditor-0.2.77}/tests/Module_UnitTest.py +0 -0
  127. {repoauditor-0.2.76 → repoauditor-0.2.77}/tests/Plugin_UnitTest.py +0 -0
  128. {repoauditor-0.2.76 → repoauditor-0.2.77}/tests/Plugins/CommunityStandards/CommunityStandardsQuery_UnitTest.py +0 -0
  129. {repoauditor-0.2.76 → repoauditor-0.2.77}/tests/Plugins/CommunityStandards/ExistsRequirementImpl_UnitTest.py +0 -0
  130. {repoauditor-0.2.76 → repoauditor-0.2.77}/tests/Plugins/CommunityStandards/GitHubCommunityStandards_UnitTest.py +0 -0
  131. {repoauditor-0.2.76 → repoauditor-0.2.77}/tests/Plugins/CommunityStandards_EndToEndTest.py +0 -0
  132. {repoauditor-0.2.76 → repoauditor-0.2.77}/tests/Plugins/GitHubEnterprise_EndToEndTest.py +0 -0
  133. {repoauditor-0.2.76 → repoauditor-0.2.77}/tests/Plugins/GitHubModule/ClassicBranchProtectionQuery_UnitTest.py +0 -0
  134. {repoauditor-0.2.76 → repoauditor-0.2.77}/tests/Plugins/GitHubModule/ClassicBranchProtectionRequirements/DismissStalePullRequestApprovals_UnitTest.py +0 -0
  135. {repoauditor-0.2.76 → repoauditor-0.2.77}/tests/Plugins/GitHubModule/ClassicBranchProtectionRequirements/EnsureStatusChecks_UnitTest.py +0 -0
  136. {repoauditor-0.2.76 → repoauditor-0.2.77}/tests/Plugins/GitHubModule/ClassicBranchProtectionRequirements/RequireApprovalMostRecentPush_UnitTest.py +0 -0
  137. {repoauditor-0.2.76 → repoauditor-0.2.77}/tests/Plugins/GitHubModule/ClassicBranchProtectionRequirements/RequireApprovals_UnitTest.py +0 -0
  138. {repoauditor-0.2.76 → repoauditor-0.2.77}/tests/Plugins/GitHubModule/ClassicBranchProtectionRequirements/RequireCodeOwnerReview_UnitTest.py +0 -0
  139. {repoauditor-0.2.76 → repoauditor-0.2.77}/tests/Plugins/GitHubModule/ClassicBranchProtectionRequirements/RequireUpToDateBranches_UnitTest.py +0 -0
  140. {repoauditor-0.2.76 → repoauditor-0.2.77}/tests/Plugins/GitHubModule/ClassicValueRequirementImpl_UnitTest.py +0 -0
  141. {repoauditor-0.2.76 → repoauditor-0.2.77}/tests/Plugins/GitHubModule/DefaultBranchQueryRequirements/Protected_UnitTest.py +0 -0
  142. {repoauditor-0.2.76 → repoauditor-0.2.77}/tests/Plugins/GitHubModule/DefaultBranchQuery_UnitTest.py +0 -0
  143. {repoauditor-0.2.76 → repoauditor-0.2.77}/tests/Plugins/GitHubModule/EnableRulesetRequirementImpl_UnitTest.py +0 -0
  144. {repoauditor-0.2.76 → repoauditor-0.2.77}/tests/Plugins/GitHubModule/GitHubModule_UnitTest.py +0 -0
  145. {repoauditor-0.2.76 → repoauditor-0.2.77}/tests/Plugins/GitHubModule/GitHubSession_UnitTest.py +0 -0
  146. {repoauditor-0.2.76 → repoauditor-0.2.77}/tests/Plugins/GitHubModule/RulesetRequirements_UnitTest.py +0 -0
  147. {repoauditor-0.2.76 → repoauditor-0.2.77}/tests/Plugins/GitHubModule/RulsesetQuery_UnitTest.py +0 -0
  148. {repoauditor-0.2.76 → repoauditor-0.2.77}/tests/Plugins/GitHubModule/StandardQueryRequirements/DependabotSecurityUpdates_UnitTest.py +0 -0
  149. {repoauditor-0.2.76 → repoauditor-0.2.77}/tests/Plugins/GitHubModule/StandardQueryRequirements/Description_UnitTest.py +0 -0
  150. {repoauditor-0.2.76 → repoauditor-0.2.77}/tests/Plugins/GitHubModule/StandardQueryRequirements/License_UnitTest.py +0 -0
  151. {repoauditor-0.2.76 → repoauditor-0.2.77}/tests/Plugins/GitHubModule/StandardQueryRequirements/MergeCommitMessage_UnitTest.py +0 -0
  152. {repoauditor-0.2.76 → repoauditor-0.2.77}/tests/Plugins/GitHubModule/StandardQueryRequirements/Private_UnitTest.py +0 -0
  153. {repoauditor-0.2.76 → repoauditor-0.2.77}/tests/Plugins/GitHubModule/StandardQueryRequirements/SecretScanningPushProtection_UnitTest.py +0 -0
  154. {repoauditor-0.2.76 → repoauditor-0.2.77}/tests/Plugins/GitHubModule/StandardQueryRequirements/SecretScanning_UnitTest.py +0 -0
  155. {repoauditor-0.2.76 → repoauditor-0.2.77}/tests/Plugins/GitHubModule/StandardQueryRequirements/SquashMergeCommitMessage_UnitTest.py +0 -0
  156. {repoauditor-0.2.76 → repoauditor-0.2.77}/tests/Plugins/GitHubModule/StandardQuery_UnitTest.py +0 -0
  157. {repoauditor-0.2.76 → repoauditor-0.2.77}/tests/Plugins/GitHubModule/ValueRequrementImpl_UnitTest.py +0 -0
  158. {repoauditor-0.2.76 → repoauditor-0.2.77}/tests/Plugins/GitHubModule/fixtures.py +0 -0
  159. {repoauditor-0.2.76 → repoauditor-0.2.77}/tests/Plugins/__snapshots__/CommunityStandards_EndToEndTest.ambr +0 -0
  160. {repoauditor-0.2.76 → repoauditor-0.2.77}/tests/Plugins/__snapshots__/GitHubEnterprise_EndToEndTest.ambr +0 -0
  161. {repoauditor-0.2.76 → repoauditor-0.2.77}/tests/Plugins/conftest.py +0 -0
  162. {repoauditor-0.2.76 → repoauditor-0.2.77}/tests/Plugins/utilities.py +0 -0
  163. {repoauditor-0.2.76 → repoauditor-0.2.77}/tests/Query_UnitTest.py +0 -0
  164. {repoauditor-0.2.76 → repoauditor-0.2.77}/tests/Requirement_UnitTest.py +0 -0
  165. {repoauditor-0.2.76 → repoauditor-0.2.77}/tests/__init__.py +0 -0
  166. {repoauditor-0.2.76 → repoauditor-0.2.77}/tests/__snapshots__/ExecuteModules_UnitTest.ambr +0 -0
  167. {repoauditor-0.2.76 → repoauditor-0.2.77}/tests/conftest.py +0 -0
  168. {repoauditor-0.2.76 → repoauditor-0.2.77}/uv.lock +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: RepoAuditor
3
- Version: 0.2.76
3
+ Version: 0.2.77
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
@@ -7,7 +7,7 @@
7
7
  """Contains functionality to display the results of executing modules."""
8
8
 
9
9
  import textwrap
10
- from typing import Optional
10
+ from typing import IO, Optional
11
11
 
12
12
  from dbrownell_Common import TextwrapEx # type: ignore[import-untyped]
13
13
  from dbrownell_Common.Streams.DoneManager import DoneManager # type: ignore[import-untyped]
@@ -128,8 +128,22 @@ def DisplayResults(
128
128
  display_resolution: bool,
129
129
  display_rationale: bool,
130
130
  panel_width: Optional[int] = None,
131
+ file: Optional[IO[str]] = None,
131
132
  ) -> None:
132
- """Display the results of executing the modules."""
133
+ """Display the results of executing the modules.
134
+
135
+ Args:
136
+ dm (DoneManager): Manager of all the tasks that need to be executed.
137
+ all_results (list[list[Module.EvaluateInfo]]): List of results of executing each module.
138
+ display_resolution (bool): Flag indicating if the resolution steps should be displayed in the output.
139
+ display_rationale (bool): Flag indicating if the rationale for the error should be displayed in the output.
140
+ panel_width (Optional[int], optional): The width of the output panel. Defaults to None.
141
+ file (Optional[IO[str]], optional): File to write to, or None for stdout. Defaults to None.
142
+
143
+ Raises:
144
+ RuntimeError: Exception if printing or writing to file encounters any issue.
145
+
146
+ """
133
147
  for results in all_results:
134
148
  assert results
135
149
  module = results[0].module
@@ -173,4 +187,5 @@ def DisplayResults(
173
187
  title=results[0].module.name,
174
188
  width=panel_width,
175
189
  ),
190
+ file=file,
176
191
  )
@@ -6,10 +6,12 @@
6
6
  # ----------------------------------------------------------------------
7
7
  """Audits a repository against a set of requirements."""
8
8
 
9
+ import contextlib
9
10
  import os
10
11
  import sys
11
12
  import textwrap
12
13
  import traceback
14
+ from pathlib import Path
13
15
  from typing import Annotated, Optional
14
16
 
15
17
  import pluggy
@@ -91,11 +93,7 @@ def TypeInfoToString(
91
93
  python_type = type_info
92
94
  parameter_info = None
93
95
 
94
- return " {arg_name:<50} {type_description:<7} {help}".format(
95
- arg_name=arg_name,
96
- type_description=python_type.__name__,
97
- help="" if parameter_info is None else parameter_info.help,
98
- )
96
+ return f" {arg_name:<50} {python_type.__name__:<7} {parameter_info.help if parameter_info else ''}"
99
97
 
100
98
 
101
99
  # ----------------------------------------------------------------------
@@ -265,6 +263,13 @@ def EntryPoint( # noqa: PLR0913 # pragma: no cover
265
263
  help="Write verbose information to the terminal.",
266
264
  ),
267
265
  ] = False,
266
+ output: Annotated[
267
+ Optional[str],
268
+ typer.Option(
269
+ "--output",
270
+ help="File name to save the output to.",
271
+ ),
272
+ ] = None,
268
273
  debug: Annotated[ # noqa: FBT002
269
274
  bool,
270
275
  typer.Option(
@@ -320,13 +325,19 @@ def EntryPoint( # noqa: PLR0913 # pragma: no cover
320
325
  # in which case default to None
321
326
  panel_width = None
322
327
 
323
- DisplayResults(
324
- dm,
325
- all_results,
326
- display_resolution=not no_resolution,
327
- display_rationale=not no_rationale,
328
- panel_width=panel_width,
329
- )
328
+ # Since `output` can be None, we use the nullcontext manager to represent None
329
+ with (
330
+ Path.open(output, mode="w+", encoding="UTF-8") if output else contextlib.nullcontext() as file
331
+ ):
332
+ DisplayResults(
333
+ dm,
334
+ all_results,
335
+ display_resolution=not no_resolution,
336
+ display_rationale=not no_rationale,
337
+ panel_width=panel_width,
338
+ file=file,
339
+ )
340
+
330
341
  except Exception as ex:
331
342
  error = traceback.format_exc() if dm.is_debug else str(ex)
332
343
  dm.WriteError(error)
@@ -2,4 +2,4 @@ APP_NAME = "RepoAuditor"
2
2
 
3
3
  # Note that the default value below will be used until the value
4
4
  # here is explicitly updated by the Continuous Integration system.
5
- __version__ = "0.2.76"
5
+ __version__ = "0.2.77"
@@ -31,6 +31,17 @@ def test_Successful(pat_args, snapshot):
31
31
  assert ScrubDurationGithuburlAndSpaces(result.stdout) == snapshot
32
32
 
33
33
 
34
+ # ----------------------------------------------------------------------
35
+ def test_Successful_To_File(pat_args, tmp_path, snapshot):
36
+ """Test if all requirements of the GitHub plugin successfully pass and the output is written to a file."""
37
+ output = tmp_path / "repo_auditor_output.txt"
38
+ result = CliRunner().invoke(app, pat_args + ["--output", str(output), "--verbose"])
39
+
40
+ assert result.exit_code == 0, result.output
41
+ with open(output, mode="r") as file:
42
+ assert ScrubDurationGithuburlAndSpaces(file.read()) == snapshot
43
+
44
+
34
45
  # ----------------------------------------------------------------------
35
46
  def _skip_test_NoPAT():
36
47
  operating_system = os.getenv("GITHUB_CI_OPERATING_SYSTEM")
@@ -2266,5 +2266,237 @@
2266
2266
  Results: DONE! (0, <scrubbed duration>)
2267
2267
 
2268
2268
 
2269
+ '''
2270
+ # ---
2271
+ # name: test_Successful_To_File
2272
+ '''
2273
+ ╭─────────────────────────────────────────────────────── GitHub ───────────────────────────────────────────────────────╮
2274
+ │ │
2275
+ │ Validates GitHub configuration settings. │
2276
+ │ │
2277
+ │ │
2278
+ │ Successful: 38 (97.44%) │
2279
+ │ Warnings: 0 (0.00%) │
2280
+ │ Errors: 0 (0.00%) │
2281
+ │ Skipped: 1 (2.56%) │
2282
+ │ │
2283
+ │ ╭─ [Success] AutoMerge ────────────────────────────────────────────────────────────────────────────────────────────╮ │
2284
+ │ │ │ │
2285
+ │ │ Validates that 'Allow auto-merge' is set to True. │ │
2286
+ │ │ │ │
2287
+ │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │
2288
+ │ ╭─ [Success] DefaultBranch ────────────────────────────────────────────────────────────────────────────────────────╮ │
2289
+ │ │ │ │
2290
+ │ │ Validates that 'Default Branch' is set to 'main'. │ │
2291
+ │ │ │ │
2292
+ │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │
2293
+ │ ╭─ [Success] DeleteHeadBranches ───────────────────────────────────────────────────────────────────────────────────╮ │
2294
+ │ │ │ │
2295
+ │ │ Validates that 'Automatically delete head branches' is set to True. │ │
2296
+ │ │ │ │
2297
+ │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │
2298
+ │ ╭─ [Success] Description ──────────────────────────────────────────────────────────────────────────────────────────╮ │
2299
+ │ │ │ │
2300
+ │ │ Validates if the repository has a description. │ │
2301
+ │ │ │ │
2302
+ │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │
2303
+ │ ╭─ [Success] DependabotSecurityUpdates ────────────────────────────────────────────────────────────────────────────╮ │
2304
+ │ │ │ │
2305
+ │ │ Validates that 'Dependabot security updates' is set to True. │ │
2306
+ │ │ │ │
2307
+ │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │
2308
+ │ ╭─ [Success] License ──────────────────────────────────────────────────────────────────────────────────────────────╮ │
2309
+ │ │ │ │
2310
+ │ │ Validates that 'License' is set to 'MIT License'. │ │
2311
+ │ │ │ │
2312
+ │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │
2313
+ │ ╭─ [Success] MergeCommit ──────────────────────────────────────────────────────────────────────────────────────────╮ │
2314
+ │ │ │ │
2315
+ │ │ Validates that 'Allow merge commits' is set to True. │ │
2316
+ │ │ │ │
2317
+ │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │
2318
+ │ ╭─ [Success] MergeCommitMessage ───────────────────────────────────────────────────────────────────────────────────╮ │
2319
+ │ │ │ │
2320
+ │ │ Validates that 'Allow merge commits -> Default...' is set to 'BLANK'. │ │
2321
+ │ │ │ │
2322
+ │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │
2323
+ │ ╭─ [Success] Private ──────────────────────────────────────────────────────────────────────────────────────────────╮ │
2324
+ │ │ │ │
2325
+ │ │ Validates that the repository's visibility is set to 'public'. │ │
2326
+ │ │ │ │
2327
+ │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │
2328
+ │ ╭─ [Success] RebaseMergeCommit ────────────────────────────────────────────────────────────────────────────────────╮ │
2329
+ │ │ │ │
2330
+ │ │ Validates that 'Allow rebase merging' is set to False. │ │
2331
+ │ │ │ │
2332
+ │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │
2333
+ │ ╭─ [Success] SecretScanning ───────────────────────────────────────────────────────────────────────────────────────╮ │
2334
+ │ │ │ │
2335
+ │ │ Validates that 'Secret protection' is set to True. │ │
2336
+ │ │ │ │
2337
+ │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │
2338
+ │ ╭─ [Success] SecretScanningPushProtection ─────────────────────────────────────────────────────────────────────────╮ │
2339
+ │ │ │ │
2340
+ │ │ Validates that 'Push protection' is set to True. │ │
2341
+ │ │ │ │
2342
+ │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │
2343
+ │ ╭─ [Success] SquashCommitMerge ────────────────────────────────────────────────────────────────────────────────────╮ │
2344
+ │ │ │ │
2345
+ │ │ Validates that 'Allow squash merging' is set to False. │ │
2346
+ │ │ │ │
2347
+ │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │
2348
+ │ ╭─ [DoesNotApply] SquashMergeCommitMessage ────────────────────────────────────────────────────────────────────────╮ │
2349
+ │ │ │ │
2350
+ │ │ Validates that 'Allow squash merging -> Default...' is set to 'COMMIT_MESSAGES'. │ │
2351
+ │ │ │ │
2352
+ │ │ DOESNOTAPPLY: Squash merge commits are not enabled. │ │
2353
+ │ │ │ │
2354
+ │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │
2355
+ │ ╭─ [Success] SuggestUpdatingPullRequestBranches ───────────────────────────────────────────────────────────────────╮ │
2356
+ │ │ │ │
2357
+ │ │ Validates that 'Always suggest updating pull request branches' is set to False. │ │
2358
+ │ │ │ │
2359
+ │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │
2360
+ │ ╭─ [Success] SupportDiscussions ───────────────────────────────────────────────────────────────────────────────────╮ │
2361
+ │ │ │ │
2362
+ │ │ Validates that Support for Discussions is set to False. │ │
2363
+ │ │ │ │
2364
+ │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │
2365
+ │ ╭─ [Success] SupportIssues ────────────────────────────────────────────────────────────────────────────────────────╮ │
2366
+ │ │ │ │
2367
+ │ │ Validates that Support for Issues is set to True. │ │
2368
+ │ │ │ │
2369
+ │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │
2370
+ │ ╭─ [Success] SupportProjects ──────────────────────────────────────────────────────────────────────────────────────╮ │
2371
+ │ │ │ │
2372
+ │ │ Validates that Support for Projects is set to True. │ │
2373
+ │ │ │ │
2374
+ │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │
2375
+ │ ╭─ [Success] SupportWikis ─────────────────────────────────────────────────────────────────────────────────────────╮ │
2376
+ │ │ │ │
2377
+ │ │ Validates that Support for Wikis is set to True. │ │
2378
+ │ │ │ │
2379
+ │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │
2380
+ │ ╭─ [Success] TemplateRepository ───────────────────────────────────────────────────────────────────────────────────╮ │
2381
+ │ │ │ │
2382
+ │ │ Validates that 'Template repository' is set to False. │ │
2383
+ │ │ │ │
2384
+ │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │
2385
+ │ ╭─ [Success] WebCommitSignoff ─────────────────────────────────────────────────────────────────────────────────────╮ │
2386
+ │ │ │ │
2387
+ │ │ Validates that 'Require contributors to sign off on web-based commits' is set to True. │ │
2388
+ │ │ │ │
2389
+ │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │
2390
+ │ ╭─ [Success] Protected ────────────────────────────────────────────────────────────────────────────────────────────╮ │
2391
+ │ │ │ │
2392
+ │ │ Ensures that the mainline branch is protected. │ │
2393
+ │ │ │ │
2394
+ │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │
2395
+ │ ╭─ [Success] AllowDeletions ───────────────────────────────────────────────────────────────────────────────────────╮ │
2396
+ │ │ │ │
2397
+ │ │ Validates that 'Allow deletions' is set to False. │ │
2398
+ │ │ │ │
2399
+ │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │
2400
+ │ ╭─ [Success] AllowMainlineForcePushes ─────────────────────────────────────────────────────────────────────────────╮ │
2401
+ │ │ │ │
2402
+ │ │ Validates that 'Allow force pushes' is set to False. │ │
2403
+ │ │ │ │
2404
+ │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │
2405
+ │ ╭─ [Success] DismissStalePullRequestApprovals ─────────────────────────────────────────────────────────────────────╮ │
2406
+ │ │ │ │
2407
+ │ │ Validates that 'Require a pull request before merging -> Dismiss stale pull request approvals when new commits │ │
2408
+ │ │ are pushed' is set to True. │ │
2409
+ │ │ │ │
2410
+ │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │
2411
+ │ ╭─ [Success] DoNotAllowBypassSettings ─────────────────────────────────────────────────────────────────────────────╮ │
2412
+ │ │ │ │
2413
+ │ │ Validates that 'Do not allow bypassing the above settings' is set to True. │ │
2414
+ │ │ │ │
2415
+ │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │
2416
+ │ ╭─ [Success] EnsureStatusChecks ───────────────────────────────────────────────────────────────────────────────────╮ │
2417
+ │ │ │ │
2418
+ │ │ Ensure that status checks have been enabled for the 'main' branch. │ │
2419
+ │ │ │ │
2420
+ │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │
2421
+ │ ╭─ [Success] RequireApprovalMostRecentPush ────────────────────────────────────────────────────────────────────────╮ │
2422
+ │ │ │ │
2423
+ │ │ Validates that 'Require a pull request before merging -> Require approval of the most recent reviewable push' is │ │
2424
+ │ │ set to True. │ │
2425
+ │ │ │ │
2426
+ │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │
2427
+ │ ╭─ [Success] RequireApprovals ─────────────────────────────────────────────────────────────────────────────────────╮ │
2428
+ │ │ │ │
2429
+ │ │ Validates that 'Require a pull request before merging -> Require approvals' is set to '1'. │ │
2430
+ │ │ │ │
2431
+ │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │
2432
+ │ ╭─ [Success] RequireCodeOwnerReview ───────────────────────────────────────────────────────────────────────────────╮ │
2433
+ │ │ │ │
2434
+ │ │ Validates that 'Require a pull request before merging -> Require review from Code Owners' is set to False. │ │
2435
+ │ │ │ │
2436
+ │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │
2437
+ │ ╭─ [Success] RequireConversationResolution ────────────────────────────────────────────────────────────────────────╮ │
2438
+ │ │ │ │
2439
+ │ │ Validates that 'Require conversation resolution before merging' is set to True. │ │
2440
+ │ │ │ │
2441
+ │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │
2442
+ │ ╭─ [Success] RequireLinearHistory ─────────────────────────────────────────────────────────────────────────────────╮ │
2443
+ │ │ │ │
2444
+ │ │ Validates that 'Require linear history' is set to False. │ │
2445
+ │ │ │ │
2446
+ │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │
2447
+ │ ╭─ [Success] RequirePullRequests ──────────────────────────────────────────────────────────────────────────────────╮ │
2448
+ │ │ │ │
2449
+ │ │ Validates that 'Require a pull request before merging' is set to True. │ │
2450
+ │ │ │ │
2451
+ │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │
2452
+ │ ╭─ [Success] RequireSignedCommits ─────────────────────────────────────────────────────────────────────────────────╮ │
2453
+ │ │ │ │
2454
+ │ │ Validates that 'Require signed commits' is set to True. │ │
2455
+ │ │ │ │
2456
+ │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │
2457
+ │ ╭─ [Success] RequireStatusChecksToPass ────────────────────────────────────────────────────────────────────────────╮ │
2458
+ │ │ │ │
2459
+ │ │ Validates that 'Require status checks to pass before merging' is set to True. │ │
2460
+ │ │ │ │
2461
+ │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │
2462
+ │ ╭─ [Success] RequireUpToDateBranches ──────────────────────────────────────────────────────────────────────────────╮ │
2463
+ │ │ │ │
2464
+ │ │ Validates that 'Require status checks to pass before merging -> Require branches to be up to date before │ │
2465
+ │ │ merging' is set to True. │ │
2466
+ │ │ │ │
2467
+ │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │
2468
+ │ ╭─ [Success] RequireStatusChecksRule ──────────────────────────────────────────────────────────────────────────────╮ │
2469
+ │ │ │ │
2470
+ │ │ Validates that 'Require status checks to pass' is set to True. │ │
2471
+ │ │ │ │
2472
+ │ │ SUCCESS: 'Require status checks to pass' is enabled in Ruleset 'Protect Main' │ │
2473
+ │ │ │ │
2474
+ │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │
2475
+ │ ╭─ [Success] RequirePullRequestsRule ──────────────────────────────────────────────────────────────────────────────╮ │
2476
+ │ │ │ │
2477
+ │ │ Validates that 'Require a pull request before merging' is set to True. │ │
2478
+ │ │ │ │
2479
+ │ │ SUCCESS: 'Require a pull request before merging' is enabled in Ruleset 'Protect Main' │ │
2480
+ │ │ │ │
2481
+ │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │
2482
+ │ ╭─ [Success] RequireSignedCommitsRule ─────────────────────────────────────────────────────────────────────────────╮ │
2483
+ │ │ │ │
2484
+ │ │ Validates that 'Require signed commits' is set to True. │ │
2485
+ │ │ │ │
2486
+ │ │ SUCCESS: 'Require signed commits' is enabled in Ruleset 'Protect Main' │ │
2487
+ │ │ │ │
2488
+ │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │
2489
+ │ ╭─ Metrics ────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │
2490
+ │ │ │ │
2491
+ │ │ │ │
2492
+ │ │ Successful: 38 (97.44%) │ │
2493
+ │ │ Warnings: 0 (0.00%) │ │
2494
+ │ │ Errors: 0 (0.00%) │ │
2495
+ │ │ Skipped: 1 (2.56%) │ │
2496
+ │ │ │ │
2497
+ │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │
2498
+ │ │
2499
+ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
2500
+
2269
2501
  '''
2270
2502
  # ---
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes