gitpr-cli 1.4.4__py3-none-any.whl → 1.5.0__py3-none-any.whl
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.
- {gitpr_cli-1.4.4.dist-info → gitpr_cli-1.5.0.dist-info}/METADATA +20 -1
- gitpr_cli-1.5.0.dist-info/RECORD +181 -0
- src/__init__.py +1 -1
- src/application/__init__.py +2 -2
- src/application/use_cases/__init__.py +8 -8
- src/application/use_cases/activate_policy_pack.py +122 -122
- src/application/use_cases/baseline_gate.py +415 -415
- src/application/use_cases/baseline_summary.py +259 -259
- src/application/use_cases/calculate_risk.py +309 -309
- src/application/use_cases/compare_against_baseline.py +41 -41
- src/application/use_cases/create_baseline.py +709 -709
- src/application/use_cases/generate_mentor_explanation.py +279 -279
- src/application/use_cases/generate_pr_explanation.py +82 -82
- src/application/use_cases/generate_test_file.py +247 -247
- src/application/use_cases/install_policy_pack.py +71 -71
- src/application/use_cases/publish_pull_request.py +272 -272
- src/application/use_cases/resolve_effective_policy.py +208 -208
- src/application/use_cases/run_check.py +448 -446
- src/application/use_cases/suppress_finding.py +483 -483
- src/application/use_cases/validate_policy_pack.py +263 -263
- src/branding/__init__.py +1 -1
- src/branding/badge_builder.py +139 -139
- src/branding/badge_data.py +53 -53
- src/changelog_builder.py +272 -272
- src/commit_classifier.py +178 -178
- src/config.py +14 -0
- src/config_schema.py +1357 -1270
- src/core.py +2328 -2281
- src/demo/__init__.py +7 -7
- src/demo/demo_runner.py +336 -336
- src/demo/fake_ai_provider.py +112 -112
- src/demo/scenarios/__init__.py +128 -128
- src/demo/scenarios/laravel_bug_fix.py +443 -443
- src/demo/scenarios/security_issue.py +511 -511
- src/diff_parser.py +321 -321
- src/doc_links.py +28 -28
- src/domain/baseline/__init__.py +143 -143
- src/domain/baseline/baseline_comparator.py +268 -268
- src/domain/baseline/baseline_fingerprint.py +103 -103
- src/domain/baseline/baseline_manifest.py +291 -291
- src/domain/baseline/baseline_types.py +289 -289
- src/domain/baseline/suppression_policy.py +661 -661
- src/domain/check/__init__.py +31 -31
- src/domain/check/check_config.py +122 -122
- src/domain/check/check_output.py +112 -112
- src/domain/check/check_types.py +165 -165
- src/domain/finding/__init__.py +5 -5
- src/domain/finding/finding_types.py +25 -25
- src/domain/linter/__init__.py +8 -8
- src/domain/linter/sast_finding_mapper.py +83 -83
- src/domain/mentor/__init__.py +15 -15
- src/domain/mentor/mentor_explanation_builder.py +228 -228
- src/domain/policy/__init__.py +116 -116
- src/domain/policy/policy_checksum.py +60 -60
- src/domain/policy/policy_compatibility.py +210 -210
- src/domain/policy/policy_manifest.py +694 -694
- src/domain/policy/policy_resolver.py +706 -706
- src/domain/policy/policy_types.py +237 -237
- src/domain/pr/__init__.py +14 -14
- src/domain/pr/explain_section_builder.py +153 -153
- src/domain/risk/__init__.py +18 -18
- src/domain/risk/risk_calculator.py +144 -144
- src/domain/risk/risk_explanation.py +78 -78
- src/domain/risk/risk_rules.py +261 -261
- src/domain/risk/risk_types.py +113 -113
- src/domain/tests_generation/__init__.py +14 -14
- src/domain/tests_generation/framework_detector.py +120 -120
- src/domain/tests_generation/test_content_types.py +43 -43
- src/domain/tests_generation/test_scaffold_builder.py +92 -92
- src/fix/__init__.py +16 -16
- src/fix/apply_fix.py +479 -479
- src/fix/fix_history.py +153 -153
- src/fix/patch_applier.py +42 -42
- src/fix/patch_extractor.py +61 -61
- src/fix/patch_provenance.py +96 -96
- src/fix/patch_safety_classifier.py +101 -101
- src/fix/rollback_fix.py +69 -69
- src/github_api.py +112 -112
- src/infrastructure/__init__.py +1 -1
- src/infrastructure/baseline/__init__.py +28 -28
- src/infrastructure/baseline/local_baseline_repository.py +355 -355
- src/infrastructure/ci/__init__.py +11 -11
- src/infrastructure/ci/junit_builder.py +102 -102
- src/infrastructure/ci/masking.py +65 -65
- src/infrastructure/ci/sarif_builder.py +152 -152
- src/infrastructure/git/__init__.py +1 -1
- src/infrastructure/git/identity.py +155 -155
- src/infrastructure/git/patch_applier.py +209 -209
- src/infrastructure/git/risk_history_reader.py +93 -93
- src/infrastructure/git/selective_stager.py +198 -198
- src/infrastructure/git/test_matcher.py +78 -78
- src/infrastructure/linter/external/__init__.py +9 -9
- src/infrastructure/linter/external/bandit_bridge.py +127 -127
- src/infrastructure/linter/external/base_bridge.py +95 -95
- src/infrastructure/linter/external/gitleaks_bridge.py +168 -168
- src/infrastructure/linter/external/semgrep_bridge.py +139 -139
- src/infrastructure/policy/__init__.py +45 -45
- src/infrastructure/policy/local_policy_repository.py +142 -142
- src/infrastructure/policy/policy_pack_loader.py +240 -240
- src/infrastructure/scm/__init__.py +62 -62
- src/infrastructure/scm/azure_devops_provider.py +464 -464
- src/infrastructure/scm/base.py +420 -352
- src/infrastructure/scm/bitbucket_provider.py +402 -402
- src/infrastructure/scm/factory.py +97 -97
- src/infrastructure/scm/github_provider.py +564 -531
- src/infrastructure/scm/gitlab_provider.py +435 -435
- src/infrastructure/scm/web_links.py +103 -103
- src/issue_autoclose/__init__.py +12 -0
- src/issue_autoclose/insert_close_line.py +46 -0
- src/issue_autoclose/issue_registry.py +235 -0
- src/issue_autoclose/register_created_issue.py +80 -0
- src/issue_autoclose/resolve_close_issue.py +226 -0
- src/linter_wizard.py +210 -210
- src/main.py +6260 -5931
- src/mcp_server.py +52 -31
- src/metrics.py +1105 -1105
- src/net.py +74 -74
- src/policy_packs/laravel-quality/CHANGELOG.md +25 -25
- src/policy_packs/laravel-quality/README.md +41 -41
- src/policy_packs/laravel-quality/linter.yml +61 -61
- src/policy_packs/laravel-quality/policy.yml +110 -110
- src/policy_packs/node-quality/README.md +27 -27
- src/policy_packs/node-quality/linter.yml +57 -57
- src/policy_packs/node-quality/policy.yml +82 -82
- src/policy_packs/php-security/README.md +33 -33
- src/policy_packs/php-security/linter.yml +69 -69
- src/policy_packs/php-security/policy.yml +75 -75
- src/policy_packs/vue-quality/README.md +29 -29
- src/policy_packs/vue-quality/linter.yml +50 -50
- src/policy_packs/vue-quality/policy.yml +78 -78
- src/project_config.py +426 -0
- src/release_engine.py +990 -990
- src/review/__init__.py +13 -13
- src/review/diff_normalizer.py +84 -84
- src/review/diff_source.py +69 -69
- src/review/remote_pr.py +350 -350
- src/review/render.py +83 -83
- src/reviewer_resolution.py +159 -159
- src/reviewer_suggestion.py +258 -258
- src/security_ruleset.py +115 -108
- src/spinner.py +257 -257
- src/split/__init__.py +17 -17
- src/split/apply_split_plan.py +251 -251
- src/split/generate_split_plan.py +222 -222
- src/split/hunk_grouper.py +347 -347
- src/split/hunk_parser.py +256 -256
- src/split/split_plan.py +153 -153
- src/suggest_reviewers.py +146 -146
- src/tui_issue.py +281 -281
- src/ui/chat_app.py +11 -11
- src/ui/commit_app.py +220 -220
- src/ui/config_app.py +2043 -1835
- src/ui/demo/__init__.py +1 -1
- src/ui/demo/demo_app.py +91 -91
- src/ui/demo/demo_help_screen.py +52 -52
- src/ui/demo/demo_screens.py +60 -60
- src/ui/issue_app.py +22 -0
- src/ui/linter_app.py +46 -46
- src/ui/metrics_app.py +456 -456
- src/ui/metrics_migration_app.py +173 -173
- src/ui/pr_base_app.py +98 -0
- src/ui/pr_publish_app.py +1783 -1775
- src/ui/pr_publish_help.py +50 -50
- src/updater.py +274 -274
- src/usage_log.py +127 -127
- src/version_bump.py +87 -87
- gitpr_cli-1.4.4.dist-info/RECORD +0 -174
- {gitpr_cli-1.4.4.dist-info → gitpr_cli-1.5.0.dist-info}/WHEEL +0 -0
- {gitpr_cli-1.4.4.dist-info → gitpr_cli-1.5.0.dist-info}/entry_points.txt +0 -0
- {gitpr_cli-1.4.4.dist-info → gitpr_cli-1.5.0.dist-info}/licenses/LICENSE +0 -0
- {gitpr_cli-1.4.4.dist-info → gitpr_cli-1.5.0.dist-info}/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: gitpr-cli
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.5.0
|
|
4
4
|
Summary: AI-powered PR automation, commit messages, and code review (Gemini, DeepSeek, and Ollama)
|
|
5
5
|
Author-email: Natan Fiuza <contato@natanfiuza.dev.br>
|
|
6
6
|
Requires-Python: >=3.10
|
|
@@ -194,6 +194,7 @@ You can pass the following *flags* for specific actions:
|
|
|
194
194
|
* **New Code Issue (`gitpr -is`):** Reads the current `git diff`. **Why use:** Ideal for quickly documenting the task you just finished programming, before committing.
|
|
195
195
|
* **Epic/Release Issue (`gitpr -is -ht`):** Reads the full history of the current branch (Git Log + PR Cache). **Why use:** Ideal for generating consolidated documentation of an entire release or a large *feature* that took several days/commits to complete.
|
|
196
196
|
* **Archaeological/Technical Debt Issue (`gitpr -is -b file:lines`):** Reads the timeline of a specific business rule. **Why use:** Ideal for documenting technical debt, explaining how a legacy code block evolved and why it needs to be refactored.
|
|
197
|
+
* `--close-issue` / `--no-close-issue`: Control the **automatic issue closure**. After `gitpr -is` creates an issue on GitHub, the next `gitpr` run offers to add `close #N` to the Pull Request description — the record lives in `.gitpr/conf/github.yml`, which GitPR adds to `.gitignore` automatically. `--close-issue` accepts without asking, `--no-close-issue` skips the check for the run, and `GITPR_ISSUE_AUTOCLOSE=false` turns the feature off. 📖 [Full docs](https://gitpr.natanfiuza.dev.br/docs/issue-autoclose)
|
|
197
198
|
* **PR Publisher (default):** Running `gitpr` generates the PR description with AI, saves the `.md` file to `.gitpr/reports/pr_desc/`, and opens an interactive terminal interface (TUI) to review, edit, and publish the Pull Request directly to GitHub, GitLab, Bitbucket, or Azure DevOps via REST API. Before generation, it checks for unstaged files, calculates suggested reviewers, and offers a modal to manage them. Use `--no-publish` to save only the PR file locally without opening the publisher, or `--no-edit` to auto-commit pending changes (with lint validation), auto-push, and publish immediately — handling existing PR updates, optional auto-merge, and clear error feedback when merge conflicts occur. Use `--base <branch>` to change the target branch. 📖 [Full docs](https://gitpr.natanfiuza.dev.br/docs/pull-request-publication)
|
|
198
199
|
* `-h` or `--help`: Shows the general help with all options. Use together with another flag for **contextual help** (e.g.: `gitpr -h --issue`, `gitpr -h --linter`) with a direct link to the detailed documentation of each feature.
|
|
199
200
|
* `-u` or `--update`: Checks the latest version of GitPR on PyPI and shows how to update it (Auto-Updater).
|
|
@@ -339,6 +340,23 @@ For your own README there is a static badge. `gitpr badge --readme` prints the l
|
|
|
339
340
|
|
|
340
341
|
📖 **Full documentation:** [gitpr.natanfiuza.dev.br/docs/badge](https://gitpr.natanfiuza.dev.br/docs/badge)
|
|
341
342
|
|
|
343
|
+
## 🔗 Automatic Issue Closure (--close-issue)
|
|
344
|
+
|
|
345
|
+
`gitpr -is` creates an issue, and the pull request is where it gets closed. This feature carries the number between the two: when `F3` creates the issue on GitHub, GitPR records it in `.gitpr/conf/github.yml` (added to `.gitignore` automatically) — one issue at a time, the last one wins.
|
|
346
|
+
|
|
347
|
+
On the next `gitpr` run, before the description is generated, GitPR checks the recorded issue on GitHub. While it is still open, it offers to add `close #N` to the pull request body; the line becomes its own paragraph at the end and is never duplicated. Merging the pull request then closes the issue automatically.
|
|
348
|
+
|
|
349
|
+
| Flag / setting | Effect |
|
|
350
|
+
|---|---|
|
|
351
|
+
| `--close-issue` | Adds the line without asking (the issue is still checked) |
|
|
352
|
+
| `--no-close-issue` | Skips the check for this run — no record is read and no forge call is made |
|
|
353
|
+
| `GITPR_ISSUE_AUTOCLOSE=false` | Turns the feature off for every run; `--close-issue` does not override it |
|
|
354
|
+
| `GITPR_ISSUE_AUTOCLOSE_TIMEOUT` | Seconds to wait for the forge while checking the issue (default `5`) |
|
|
355
|
+
|
|
356
|
+
GitHub only; the other forges skip the feature in silence. A run with no terminal does not ask — use `--close-issue` to opt in. The record survives a failed or cancelled publish and is cleared only after the body reaches the forge; a closed, deleted or pull-request number forgets itself, and a record from another repository is ignored and kept.
|
|
357
|
+
|
|
358
|
+
📖 **Full documentation:** [gitpr.natanfiuza.dev.br/docs/issue-autoclose](https://gitpr.natanfiuza.dev.br/docs/issue-autoclose)
|
|
359
|
+
|
|
342
360
|
## 🧠 Multi-Model Architecture (AI-Agnostic)
|
|
343
361
|
|
|
344
362
|
GitPR is not tied to a single Artificial Intelligence. During initial setup, the user can choose their default engine. We currently support:
|
|
@@ -564,6 +582,7 @@ If you want to implement GitPR as an automated quality barrier in your team, che
|
|
|
564
582
|
* [**Remote Pull Request Review (gitpr review-pr)**](https://gitpr.natanfiuza.dev.br/docs/review-pr) — How the `gitpr review-pr` subcommand reviews a pull request that is already open on the forge, fetching its diff from the API without checking out its branch.
|
|
565
583
|
* [**AI Commit Messages**](https://gitpr.natanfiuza.dev.br/docs/commit-message-ia) — How to generate messages in the Conventional Commits standard and integrate with Git Hooks.
|
|
566
584
|
* [**Issue Generation and TUI Interface**](https://gitpr.natanfiuza.dev.br/docs/issue-tui-help) — How to use the terminal graphical interface (TUI) and the 3 context engines to manage structured Issues.
|
|
585
|
+
* [**Automatic Issue Closure (--close-issue)**](https://gitpr.natanfiuza.dev.br/docs/issue-autoclose) — How the issue created by `gitpr -is` is recorded in `.gitpr/conf/github.yml`, the gate order that decides when the next pull request offers `close #N`, why the record survives a failed publish, and how the line is kept from being duplicated.
|
|
567
586
|
* [**Code Archaeologist (Git Blame)**](https://gitpr.natanfiuza.dev.br/docs/blame-arqueologo) — How to trace the origin of business rules with `git blame` and AI.
|
|
568
587
|
* [**Skills and Templates System**](https://gitpr.natanfiuza.dev.br/docs/skill-template) — How to customize AI behavior with `.gitpr.*.md` files.
|
|
569
588
|
* [**Release Notes & Changelog (gitpr release)**](https://gitpr.natanfiuza.dev.br/docs/release-notes) — How the `gitpr release` subcommand generates the changelog / release notes of a repository from the delta of the previous version, links every commit, pull request and contributor, suggests the next semantic version and publishes releases on the forge.
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
gitpr_cli-1.5.0.dist-info/licenses/LICENSE,sha256=UQzLC6mwqb-ZNDkBBAqOxC-SMQcEID0gaM6oFcu6u48,27030
|
|
2
|
+
src/__init__.py,sha256=ZHymXsocMDazI_fjOIgAQsRQvFPN2tV8FOuv0qptI_o,30
|
|
3
|
+
src/ai_providers.py,sha256=QyFEOsXyA59lZziO5bl-4nlYFJpxBcxU9aLhcTBnkWE,14633
|
|
4
|
+
src/blame_engine.py,sha256=Zov1hxrt7Dcmf56ovJKz3QmHIfzDKtSub2iItXeg9-A,17104
|
|
5
|
+
src/cache.py,sha256=frROc69NyTn3TdJIOPctvuH9z_sh2pdKxL4ekMtyh6k,6572
|
|
6
|
+
src/changelog_builder.py,sha256=Ea0coS6LCqsdxTWrKW8SZyVsD02HuNNYzCoggI0loi8,9922
|
|
7
|
+
src/chat_memory.py,sha256=PcohnyspAfIwwwbsp9U2Wk_1AylJMFEMoWqRSJe_w30,8949
|
|
8
|
+
src/commit_classifier.py,sha256=HQHxPbCfgW_GD1_4mbO2No16jh_Ci5RTSoLbTU4IWYI,6920
|
|
9
|
+
src/config.py,sha256=3O6h-A_gVJLxxG9M1L6fHCk-6UeP4tscONepZHInWHM,54130
|
|
10
|
+
src/config_schema.py,sha256=hqfiNQgyJQ7l_f4VU315gMEUUG_D8490aXDPwMmFw4I,48087
|
|
11
|
+
src/core.py,sha256=w29W2Tyx4DqWfLcZ1svMDyEwLfFpVZbFmFi79QE-mLc,88666
|
|
12
|
+
src/diff_parser.py,sha256=ZJxiDMWLglk6QADS37S-oMDhuCvZ5eiKOnCWy6E-Avg,11573
|
|
13
|
+
src/doc_links.py,sha256=xc9An9_MyLRYGo_4K5qXRqemG5t_QmWTik8lh8Rlpjo,1185
|
|
14
|
+
src/github_api.py,sha256=i1o58oKWWmMCerP-g-hOQHGCwPWd01ooKntTKjpFhIA,3948
|
|
15
|
+
src/i18n.py,sha256=PdUmtZlH1zogbiDc3j6xiwtnvUd7XiNbiS-xKjYK4WM,4844
|
|
16
|
+
src/issue_engine.py,sha256=RmZsQVg6N1vCcpMdv_5FX-cMGgQ3I0vwMN4parQ4zFg,10974
|
|
17
|
+
src/ledger.py,sha256=s10Sm0qcA1b916X7m8d2osDThCmSK0UQnmUrkyj8Eao,43663
|
|
18
|
+
src/linter_engine.py,sha256=hIxht8M09Fnm6NiJZOqjI6dyqnFoHUDVA8Ve4dWZV4s,25214
|
|
19
|
+
src/linter_wizard.py,sha256=mo8aSTZmVLluCOskWv3nji74WPJh_6c122zwADN9aCc,7634
|
|
20
|
+
src/main.py,sha256=W7AWcM4vnaqwXSeg30Sc5_uBTK9-HGWFsUVPwOFiGaY,229742
|
|
21
|
+
src/mcp_server.py,sha256=SoTS23WbkmE6VowIdQOcUiFkXKlP5aDrr7MSJX5KD5o,112417
|
|
22
|
+
src/metrics.py,sha256=g39FYKx-LAuVyjZLxZCU66iulne8mhTLzPbINk5TFnU,40665
|
|
23
|
+
src/net.py,sha256=CjhgmQnp4OHVmO-3Lm-DLhNfo2RW0M9FnD_HYPKcnNI,2848
|
|
24
|
+
src/project_config.py,sha256=9mXC5GKLv3pgQvlc50XCBnMVvTtbWCwIHAi-J48XXyA,15278
|
|
25
|
+
src/release_engine.py,sha256=gowcInpeAA581YheeBbRk9dKz3CL-K-zY7kEdEw6DqA,38423
|
|
26
|
+
src/reviewer_resolution.py,sha256=bFRdf4GVWIpz4kk7cyF7EYWV43aP7V8sAlNGqKRPd7A,5913
|
|
27
|
+
src/reviewer_suggestion.py,sha256=4tFwfltsEvx3s8RnUDKMaFGhdtWPWfgM0wqCTzEzWjE,8759
|
|
28
|
+
src/security.py,sha256=fkWy-r4tdISH0xOyWZyR8ZCFyLuYqu8fn9sKsIeNAso,1351
|
|
29
|
+
src/security_ruleset.py,sha256=4mqmqtWLHuhuCcjjaoKUM_YFzil4cWZ_ubjlOLgbM_4,4874
|
|
30
|
+
src/spinner.py,sha256=8w3_BpIi-EkqmjP2OspALx9lWNyn8XwLw44gCTBeQv8,9221
|
|
31
|
+
src/suggest_reviewers.py,sha256=WITj8lZOomwSL703Rw-cFBr59LnQ9t0Pl2kALCh9AA8,5327
|
|
32
|
+
src/tui_issue.py,sha256=zNGglq_Xk8qTmoFmoQpIZjgIUz7fX7rvyp1fnBuUbME,10612
|
|
33
|
+
src/updater.py,sha256=7UeSsDUbYT4OrvX8UnEP0WmUWYZ58oYBS0huCPZn9mo,9560
|
|
34
|
+
src/usage_log.py,sha256=CBCNlUm_xftXsBaGRHvsEjTENvZfE-lW70HGLMkisSg,4508
|
|
35
|
+
src/version_bump.py,sha256=Dw1LZ_c6VzaO_s9cDeYSevoWtXVr_oP70eS_mkrOm8s,3041
|
|
36
|
+
src/application/__init__.py,sha256=3YXFcmxJh0f7BwryKXxUrOhGrLnZLsagV-VbBIk0eGk,31
|
|
37
|
+
src/application/use_cases/__init__.py,sha256=jgOjxxTdvgGTmaHA7VIcAnNoDKIdvqOs8IYhCV3N3aE,292
|
|
38
|
+
src/application/use_cases/activate_policy_pack.py,sha256=U6nNsESRDJv4bW_v__qc7zSo2LxiLcBkkppievfiSls,4627
|
|
39
|
+
src/application/use_cases/baseline_gate.py,sha256=-3c5iy7i-HJ7_lsgHGftc8JDYOct0OnrkppQEJn47HE,16734
|
|
40
|
+
src/application/use_cases/baseline_summary.py,sha256=BK5LibkNbQsIRmYvqv8AcS_kkC1b_Lt9Q6ZiOMzYCO0,10550
|
|
41
|
+
src/application/use_cases/calculate_risk.py,sha256=Kgd6YVTrt6DtizXAZQ97XCYd0TBXXytiloauke-L-ko,13513
|
|
42
|
+
src/application/use_cases/compare_against_baseline.py,sha256=hePa-yidv9OfBe8AZoNhu6FA5MBg5izZyL5K9ZAOWAI,1916
|
|
43
|
+
src/application/use_cases/create_baseline.py,sha256=amVigQG-E3yCqzPNmCK9wazSC3Rh4sXJgntqhgg6cUU,26637
|
|
44
|
+
src/application/use_cases/generate_mentor_explanation.py,sha256=pPXSLYBJwum6a2P1TYv_B1zwAuM3xYtT8T2LhKO60rY,9707
|
|
45
|
+
src/application/use_cases/generate_pr_explanation.py,sha256=vlR6Lw7XBnHD7Cloz2gZMrW-kx31cBeC2kSM0qSnUjk,3418
|
|
46
|
+
src/application/use_cases/generate_test_file.py,sha256=U6EyPbZSXEv9A34PYHkQDToenjqu5Fu1h-nIBqcT9Ds,9657
|
|
47
|
+
src/application/use_cases/install_policy_pack.py,sha256=7s8wUL_SticgRnUMpzLJCmHso6y6tDHLibSdBLyXb0M,2816
|
|
48
|
+
src/application/use_cases/publish_pull_request.py,sha256=sBQTBhFGJ98YKTqatZdEccTHfNrp3rxZ_qbKUR9nZrw,9762
|
|
49
|
+
src/application/use_cases/resolve_effective_policy.py,sha256=HQruehhgqzT5cX2YcVftm1cZqiwDS5cAkRO0txj3hns,7771
|
|
50
|
+
src/application/use_cases/run_check.py,sha256=fWzMj91Kp5SXgmCwdWS5IjALXX0wNa3-M7yoHWID27g,15835
|
|
51
|
+
src/application/use_cases/suppress_finding.py,sha256=a9oXVFZmvNFrKbEMNXepAu9dEIUqqBb-H1ZSjM0hcAs,18292
|
|
52
|
+
src/application/use_cases/validate_policy_pack.py,sha256=OaHfs_coNFR9s6c2I7MKFVZRy2Hw2q_y9_B48poOZrE,9906
|
|
53
|
+
src/branding/__init__.py,sha256=BJ7o5Z13LvWnUVb1aN1tz2XlFk7h89MQGkB2nJuJO0s,81
|
|
54
|
+
src/branding/badge_builder.py,sha256=y-YYE3UCWuZ6aBte857TIgaFXJ4rpgqDLr5qBnP45jI,5038
|
|
55
|
+
src/branding/badge_data.py,sha256=ZJGQsbguX3p9n6_XQbyO7UBEc-Guub731Q1Vbe8YCSM,1978
|
|
56
|
+
src/demo/__init__.py,sha256=0sJ_1xV65ND-HNZjUBMFtIFdiqfskl5BR_BDkR9Yoq4,377
|
|
57
|
+
src/demo/demo_runner.py,sha256=s3ghZ6VJLlol6qPjNiuHV0fvSJd64gqACTgfC08nOzU,11057
|
|
58
|
+
src/demo/fake_ai_provider.py,sha256=PbdZoY0rlWoA-LUx0oD9ERjZL69N1BoohQbgRYLcLLk,4150
|
|
59
|
+
src/demo/scenarios/__init__.py,sha256=OSXSvpqm4xi6HElA0-xZjUcvTFgMZQ91aHMHwwvZyiM,4169
|
|
60
|
+
src/demo/scenarios/laravel_bug_fix.py,sha256=OOh4AVWYDah0sCQ2kU4UaqRM5I56nSqhG5EYOhVQQSY,20904
|
|
61
|
+
src/demo/scenarios/security_issue.py,sha256=dnrnWyUDOfUTk2ANbwXQTnuXk50tohG7AtdPdthVjyE,24332
|
|
62
|
+
src/domain/baseline/__init__.py,sha256=mHQRdNMh_VMUzm2mVFqwHdcqI_d9ipxEA0CJwH010Cs,3945
|
|
63
|
+
src/domain/baseline/baseline_comparator.py,sha256=G0QUBpDpxUHjIepevOp9S8RQ3wpG1OmEEMYEX2ST6Yc,8970
|
|
64
|
+
src/domain/baseline/baseline_fingerprint.py,sha256=8RqBJMnz9yqRvqzpldV7_ynv_hHOiu-Hi1n8ubomV0A,4473
|
|
65
|
+
src/domain/baseline/baseline_manifest.py,sha256=q3svlaqso0mYGIP0xQQSmA_oWLDbQmfl3AmAbawYDvE,10720
|
|
66
|
+
src/domain/baseline/baseline_types.py,sha256=oRMdXxAdpx94Ur-n9XwSSO--d-CC4w2-k6M549h6ADI,11509
|
|
67
|
+
src/domain/baseline/suppression_policy.py,sha256=x6W-4_Hl16q5lA3wgXWa0BkIkE4J5W3k0MCzhQ49dhM,23150
|
|
68
|
+
src/domain/check/__init__.py,sha256=OA8heAdclSkZRPY6pumHGPPq9yC6XL5FLD__JHUo85A,712
|
|
69
|
+
src/domain/check/check_config.py,sha256=b8--2g4PVu_CxnTvPhRagNpxFr7I3YtQFlRp4ox8zZI,3801
|
|
70
|
+
src/domain/check/check_output.py,sha256=6kAf0zkuQZi6J79fL7JrwEvbF8sQbly557rxt_Caz4Q,3946
|
|
71
|
+
src/domain/check/check_types.py,sha256=TS7oZEg82geIn-q601CV6NP4co1laN_HnqAhnE7aeYw,5221
|
|
72
|
+
src/domain/finding/__init__.py,sha256=j-veoGxtyF0TVJTQxV2jy-Jgy5k3u6dAzg6d-i8g2nI,171
|
|
73
|
+
src/domain/finding/finding_types.py,sha256=_ZVC-KB48qXlD1Q5y8aSwnfQD5GSeeKZUIkfJoSmHJU,858
|
|
74
|
+
src/domain/linter/__init__.py,sha256=Ic3z4fXCxESzLPZF7LLEzgyWjrEF_A6vh3QEL0ScYOo,244
|
|
75
|
+
src/domain/linter/sast_finding_mapper.py,sha256=oD7wLH0LlMcC-_6Luv6rKPNfynBRcDCoa-zRFx0M1dU,3419
|
|
76
|
+
src/domain/mentor/__init__.py,sha256=w1_wx0el3z03QwSiKB6mr8dyprML-AFUsE99Ez8_wUg,372
|
|
77
|
+
src/domain/mentor/mentor_explanation_builder.py,sha256=6eON3x20BEpi7bVdu3TCJh_qstkMYUoLpz-VfORVTqQ,7004
|
|
78
|
+
src/domain/policy/__init__.py,sha256=n15hFYtfI-mg0_Z47A6Bm4rqbjUklQXAxaHTTdr27F0,3617
|
|
79
|
+
src/domain/policy/policy_checksum.py,sha256=5rzJo31iAkbbuJREyNKm5FVOyL6SH6roYlxDXc9YYRg,2342
|
|
80
|
+
src/domain/policy/policy_compatibility.py,sha256=_optz7r56tF_rmq42DeA-34VbUolUcP6kvo5TcPJdDQ,8477
|
|
81
|
+
src/domain/policy/policy_manifest.py,sha256=d9PEvZKaGMg3koGEJ6XIwNevJGssrw3Q6VqUkvvcwq4,26986
|
|
82
|
+
src/domain/policy/policy_resolver.py,sha256=xduWDDaqU1T-BDSckhmyOViXwXZQiXLrPyOsh9qvB3U,29589
|
|
83
|
+
src/domain/policy/policy_types.py,sha256=IOgGVM6oIDrFmSdOkkNpwxkQpTgXIBqY1hxVY-RxMwo,10112
|
|
84
|
+
src/domain/pr/__init__.py,sha256=zCKL3_JVnOAfAoKQGT4dbpJmpF2mU9KKeumxIN50MzE,288
|
|
85
|
+
src/domain/pr/explain_section_builder.py,sha256=Nhnmm7166V1rEft4uRaNxx5_gV0MoCJOQkMOogbWzHg,5176
|
|
86
|
+
src/domain/risk/__init__.py,sha256=wvsE1QhTUVSwcnwDDMEnQTgdbzurCFJDxsbrjKjbve4,301
|
|
87
|
+
src/domain/risk/risk_calculator.py,sha256=ZSJeU6YaQAxQfo5mLyAqtvPVLuWT4kYKqFId8bXtq4M,5181
|
|
88
|
+
src/domain/risk/risk_explanation.py,sha256=JIoeP_GYvVe-1ul-HU43qedoCpgAjWuVtH0WvFdfTrM,3083
|
|
89
|
+
src/domain/risk/risk_rules.py,sha256=6dP4QVaaDwJbrdX401ahG_p_wNCG5JKIrvWAsq1X93g,8966
|
|
90
|
+
src/domain/risk/risk_types.py,sha256=-kgr_a1ky4RKhP17tm2Q33VD4C_pdz9GD5FK3Be2zow,4154
|
|
91
|
+
src/domain/tests_generation/__init__.py,sha256=TqKcuJhvH3v_S_1R8ju1dRFx-cmp9v0ewPYjyQsqxOU,265
|
|
92
|
+
src/domain/tests_generation/framework_detector.py,sha256=s4yN5ZjtCGX8hDiMHDPO9dZs8jWU2m8bBMP_Iihx0MM,4559
|
|
93
|
+
src/domain/tests_generation/test_content_types.py,sha256=tfBGn26jx5VMK2PxRkJf3Md25Z4ofCkLaNktvyzKDns,1062
|
|
94
|
+
src/domain/tests_generation/test_scaffold_builder.py,sha256=t3CUBuUchTPgKVgZicjCz-VS5Ea7WUhvd4dbbi2UV6g,3892
|
|
95
|
+
src/fix/__init__.py,sha256=tkdj-xF8PCJ6PaIRmH61W3vUn8vnRJXz00Atnf61Yo8,953
|
|
96
|
+
src/fix/apply_fix.py,sha256=XURlvTnkBjwLzdwixEy5v8PBAKCTam6B3CCSNMFEhTE,18391
|
|
97
|
+
src/fix/fix_history.py,sha256=jxUbwsSi4lqw-64zlVVj2suVnOrvRPrrgWVlzjRO4Gw,5779
|
|
98
|
+
src/fix/patch_applier.py,sha256=DJ5rS5tOM3v5g8l9dWVpNoalWhukj6wVRUwdTkXJACg,1277
|
|
99
|
+
src/fix/patch_extractor.py,sha256=8SdltGtbccBowHbnYd4BU-oUcEQegel_tB7o_2uK6wo,2575
|
|
100
|
+
src/fix/patch_provenance.py,sha256=7PlygeSHp4qSa-XmUUkEkV-N5aSeaHhRvNQA35aA-MQ,3291
|
|
101
|
+
src/fix/patch_safety_classifier.py,sha256=cEkzMyQkXQeCE-btY1Tl9xdvah6RMioQ_L5HAoqzqDs,4222
|
|
102
|
+
src/fix/rollback_fix.py,sha256=jwmISZP-EiaNFEKlSNdhiKWuPytV635BdDmzAurmegY,2570
|
|
103
|
+
src/infrastructure/__init__.py,sha256=FDQv7sZaZ3bZFyIm7MJap-99SdeDRqiLcXhZudjDYnk,82
|
|
104
|
+
src/infrastructure/baseline/__init__.py,sha256=FIG9NT1dTUA4i59xXIhwzLKmNCa7sOIf1KRWHO8-lE0,642
|
|
105
|
+
src/infrastructure/baseline/local_baseline_repository.py,sha256=6r4_qpzEGUFClD1Yt-Vm-ws5AQrDpzqsq70J3V0uBHA,13815
|
|
106
|
+
src/infrastructure/ci/__init__.py,sha256=epqkB76zTFODGQ2ZknO-x3-F83WOQ-ZtJXFaFYoPX70,345
|
|
107
|
+
src/infrastructure/ci/junit_builder.py,sha256=uxII_90biDKOm-l0xn2Q4QAAxDt0kl0oYAsQk4etBUQ,3921
|
|
108
|
+
src/infrastructure/ci/masking.py,sha256=neKqDWAlnlg2n78vCdb8v78mNylXxpSWxpsqNCJaKb0,2218
|
|
109
|
+
src/infrastructure/ci/sarif_builder.py,sha256=fbAshYS0BTBH3Vg_FEkzK8o3rSD6xOvHrq0g2K08wsc,5385
|
|
110
|
+
src/infrastructure/git/__init__.py,sha256=YERpBrzf1S76qi9rHqDuaq9_X5pDeKKXaAmw9C6SOuI,88
|
|
111
|
+
src/infrastructure/git/identity.py,sha256=SdcNyPF_eISGGye0PtxiSWAU4YyDcTIFYtQyKa6590Q,5877
|
|
112
|
+
src/infrastructure/git/patch_applier.py,sha256=x7xU2mdq6eEDJtpO7G4ZZKq1hsIJ81HiFCwdF2360Oc,8197
|
|
113
|
+
src/infrastructure/git/risk_history_reader.py,sha256=YtKSguDZgMqVXx3IpEXQCGB1yzuCro1S8KjaU8VkgpE,2826
|
|
114
|
+
src/infrastructure/git/selective_stager.py,sha256=yjztG4fV1mp-KHCvF7a-caGtcg_WUSrPAtYH96tGq0k,8236
|
|
115
|
+
src/infrastructure/git/test_matcher.py,sha256=Uk4f7f2XeVuUbLyQ7miGwAhOAN0m_YS3stqrumNPhRc,2664
|
|
116
|
+
src/infrastructure/linter/external/__init__.py,sha256=OOIw9u587FnscgyPBnR2X3cvNjT0iiNH9XY45DI5FOU,326
|
|
117
|
+
src/infrastructure/linter/external/bandit_bridge.py,sha256=U_e-h74S9LcnRMJxoJxPPzN9YKb69NZOrJjpFugBKCs,4457
|
|
118
|
+
src/infrastructure/linter/external/base_bridge.py,sha256=iMQwRWy5BibgWEDs-Pi3-YvKEmy452u5qG8yHYtmEhI,3158
|
|
119
|
+
src/infrastructure/linter/external/gitleaks_bridge.py,sha256=9v3jnDcgwVfJQS4M6jTvt69X061S7YshmiecVjaWLiY,6049
|
|
120
|
+
src/infrastructure/linter/external/semgrep_bridge.py,sha256=7iZMm2QY44_dUnpqeBIXLMkn0SAuuiswaSvGVeg-VtU,4643
|
|
121
|
+
src/infrastructure/policy/__init__.py,sha256=mgznDOqCM9iazgY8DTi3uJqrc9wqIQp9D5eCDa5tyAk,1084
|
|
122
|
+
src/infrastructure/policy/local_policy_repository.py,sha256=-dW4QR-rzUM6qwOSC5UhA51tg1iWAXkTxKcZJPK0eBo,5786
|
|
123
|
+
src/infrastructure/policy/policy_pack_loader.py,sha256=uRTp64ksVkdC3GBYgaHxkXUjeTk7UWPy0ePWVRo92k4,9559
|
|
124
|
+
src/infrastructure/scm/__init__.py,sha256=CbW2p9DsYpwwUqy4xdtgoPugsLijopfNwLT-IAfEcqA,1887
|
|
125
|
+
src/infrastructure/scm/azure_devops_provider.py,sha256=5k3w6HWpZm2hlv_00E5sQYV7OgZcQh1XwJsNlyPa51k,18384
|
|
126
|
+
src/infrastructure/scm/base.py,sha256=SJlrjktVUJapTLxWmtT652e2yvuK0kuMOTNCI5_Wleo,17172
|
|
127
|
+
src/infrastructure/scm/bitbucket_provider.py,sha256=gGZo6YSUt2HkVdJdKVizkEF9bv4X0bhrzKGST_iybdQ,15553
|
|
128
|
+
src/infrastructure/scm/factory.py,sha256=U-1IkVaWxBCb1-8dbyGBJKCFwQWSqLE2P6ZG4_cad1c,3953
|
|
129
|
+
src/infrastructure/scm/github_provider.py,sha256=vdJDTTYd-CYkAQos-6IZ2hFOJkXG09SrkIcZzHbuuIc,21316
|
|
130
|
+
src/infrastructure/scm/gitlab_provider.py,sha256=8AimDKgVPXkYmvZXUYD-NBWfAk-EjhhSgvVVMiUAoBU,17030
|
|
131
|
+
src/infrastructure/scm/web_links.py,sha256=-7oF7oUwK_UvKVJZWDPbTnKBi9JEQu2dMDYtgqH10iM,3724
|
|
132
|
+
src/issue_autoclose/__init__.py,sha256=9IuLWTrq7Vvk2pf3BWMtxVFJ0ALmmHOpYjG8Rwd_x5U,651
|
|
133
|
+
src/issue_autoclose/insert_close_line.py,sha256=MY8Hr1HWbdIflI6L0Drg9x3ouEJy9BbYxnm1PNguzxY,1779
|
|
134
|
+
src/issue_autoclose/issue_registry.py,sha256=UONwAwVEENh3AA527rs-tme-LBALVnZHbVq8WPTI95c,8731
|
|
135
|
+
src/issue_autoclose/register_created_issue.py,sha256=jCSDQWVN6WEhMj8s_Ggkx2FsFQPq2m2ehQom3GI6s2I,3006
|
|
136
|
+
src/issue_autoclose/resolve_close_issue.py,sha256=clGc2g1vsmCJ4fxieDsN-zfNyemZ1aYvRStHZlMkFZg,7951
|
|
137
|
+
src/policy_packs/laravel-quality/CHANGELOG.md,sha256=g7f9coAAKmPMa3IxpI1bduvr1WfapgfM6KE_kBs5vLM,1154
|
|
138
|
+
src/policy_packs/laravel-quality/README.md,sha256=MhSQV-p8F6jmBEenvDvklseQ3FDvnvvmN6A16L6-x4s,1852
|
|
139
|
+
src/policy_packs/laravel-quality/linter.yml,sha256=bzA9yWf1obx3qDs4TCPzfkinOUJaScDI7mK8BlAm8xo,3191
|
|
140
|
+
src/policy_packs/laravel-quality/policy.yml,sha256=mQFsaJn1_QZ7lfHB24Sz3qvAN6CsEoI9oYwNDD5ARdg,3813
|
|
141
|
+
src/policy_packs/node-quality/README.md,sha256=1C_o-8y6jsI2x963KjQ0VeSB4MlxDHK3ACEYO81rmPI,1313
|
|
142
|
+
src/policy_packs/node-quality/linter.yml,sha256=0211mNdOU70N5C-U4tT1qivkis5_bptU_y6fLGnRc1Q,2874
|
|
143
|
+
src/policy_packs/node-quality/policy.yml,sha256=7BByVT_qE9q5YIT0Tt2_7eM9eTMdcFF_HsCugc-q0uQ,3219
|
|
144
|
+
src/policy_packs/php-security/README.md,sha256=wVOu2uPyDR0sAjo605jTijJ6AprYKNRma5MRFqAIEqw,1489
|
|
145
|
+
src/policy_packs/php-security/linter.yml,sha256=2WTX_2YajaH7wwB7t-A-W4u317jG7wkf5jW5qrhsvdQ,3260
|
|
146
|
+
src/policy_packs/php-security/policy.yml,sha256=cQkffWrRgLu-KUyDaLuTuJ_9ahwLySNbAV0OO9GP8kY,3258
|
|
147
|
+
src/policy_packs/vue-quality/README.md,sha256=2CCPyZbePU4Aiq06lygcVlOcFtNALJaxh0-xt7t4ZPM,1293
|
|
148
|
+
src/policy_packs/vue-quality/linter.yml,sha256=_G_CMBB4hvo-mkRI0rv77530Es5GnXoNipD5wpfPwvg,2508
|
|
149
|
+
src/policy_packs/vue-quality/policy.yml,sha256=FyVL17Fl_bgVjxZU5lO7MME5w04vjKV3UfISOBkGBXc,3099
|
|
150
|
+
src/review/__init__.py,sha256=ux2rkwebfnzuQpFc57eEceOC4CZkojPOtfp951Ux5Gc,700
|
|
151
|
+
src/review/diff_normalizer.py,sha256=ITSoJc1s_SKDjSRjFM7pFvotDO9kclW0wf9XSZZcgC4,3635
|
|
152
|
+
src/review/diff_source.py,sha256=V6fMtgxNJbMBL_qRifkLGfzFwtaTCbFFKFvcutHZjLk,2733
|
|
153
|
+
src/review/remote_pr.py,sha256=9oEEo-v-D08egxwN_EINh5Ju74vow91-CAH1kAb2ql0,13669
|
|
154
|
+
src/review/render.py,sha256=l63vQ3WiGxPSzCk4JxyQoFNfIyG0AdHgMobAjMeaOcY,3194
|
|
155
|
+
src/split/__init__.py,sha256=8XZn4jwPhQ0pJyNEMTBfgbGTMJkQUvePNp5ZncWCJ-Q,929
|
|
156
|
+
src/split/apply_split_plan.py,sha256=ZKoACWLCaBndLzvRl8wHyAyPlalTrjrPJ2ep_AjpWCE,10929
|
|
157
|
+
src/split/generate_split_plan.py,sha256=60nMWOsokcweWE6tX2RJqeJ_8o-XByAMtg2Zcmwumt0,9008
|
|
158
|
+
src/split/hunk_grouper.py,sha256=35PU7I_9iUzaN9xaJvoK2y9KGkeKjKofO_7l6xOWWks,14596
|
|
159
|
+
src/split/hunk_parser.py,sha256=DYc82pCKnuquJJwB7nm44WtZKK22lv-d75g9EeBhCm8,10266
|
|
160
|
+
src/split/split_plan.py,sha256=Y0Ah3LbzixKgAy74dh7XiQImsw6-f2dxwfJSkQHreCw,6572
|
|
161
|
+
src/ui/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
162
|
+
src/ui/chat_app.py,sha256=y6hDKGgSaJDfp1rZBWxwQVQHzP_xx6-3q-oxxWnTUfg,26839
|
|
163
|
+
src/ui/commit_app.py,sha256=mggIsdHkg3EIvQoSc11XL7tpkSGJ25WWszHdgmJnMjc,8304
|
|
164
|
+
src/ui/config_app.py,sha256=YTQSkSWh97UqIWTcwu2_bAbra9C4pt2vgth8F-L-Ad0,84484
|
|
165
|
+
src/ui/help_screen.py,sha256=EvbP8kFZ6Sdehi7bJ6Wo_YcTTk5MTkgneeidWwefYrA,1890
|
|
166
|
+
src/ui/issue_app.py,sha256=ao2PDiT539Ppc2LItjesmMG7I5Mj96DIy4fFU7UCw_g,10378
|
|
167
|
+
src/ui/linter_app.py,sha256=kXhcHlhOMRCKTdfnXlCU34oDvHkm1aRivGWlz0AkeKM,1612
|
|
168
|
+
src/ui/metrics_app.py,sha256=fLDVWFVkJSZcDKfx2t5njtjGR_3laVeHu4rm19ByW7E,16759
|
|
169
|
+
src/ui/metrics_migration_app.py,sha256=U6l-ORUk1NlC2aIQSLvFjahMVM1dat-wFjWlct0fRYQ,6096
|
|
170
|
+
src/ui/pr_base_app.py,sha256=OvPcQVeyBrGBH8lhlVy0Ks1kVdvqcYHl7Zc3P2tXPGI,3857
|
|
171
|
+
src/ui/pr_publish_app.py,sha256=TU5IrSB3bkQEhl2N0W8KCwHfRGGacijqziMD9I7By04,71802
|
|
172
|
+
src/ui/pr_publish_help.py,sha256=3fcTbrQIoPM72kTbNjFu4PAin592DuNQlNIn_AeRmVk,1941
|
|
173
|
+
src/ui/demo/__init__.py,sha256=aOdUN0izuwW2FfLAHG9Qga-DJG5NBVqP0gYNO8OiKls,59
|
|
174
|
+
src/ui/demo/demo_app.py,sha256=4t_Mct-BJXpe5tlt1XmtRyN1IT0OL6U3WSmGqOJqMG4,3165
|
|
175
|
+
src/ui/demo/demo_help_screen.py,sha256=I_LELswhPtbHjfMWGVUqLtOwxGbzSYJsVWXjqZrLoLA,2108
|
|
176
|
+
src/ui/demo/demo_screens.py,sha256=GXaQFTgTn9awSP-EYiBXsCZqB583WrSQcuNYoBK12g8,1997
|
|
177
|
+
gitpr_cli-1.5.0.dist-info/METADATA,sha256=xkoqpc842w0Y6RcI0MdeH6VUbn0QvGPKYB821hnIpBE,54016
|
|
178
|
+
gitpr_cli-1.5.0.dist-info/WHEEL,sha256=mOdXR9C3wMVov7cSY8PY-XCzo3SmmWCHvGQr5csJoao,91
|
|
179
|
+
gitpr_cli-1.5.0.dist-info/entry_points.txt,sha256=TstGnMUzdOI5qNmpM97EPDBPuMqOZxoo6EoLxHSOMSQ,71
|
|
180
|
+
gitpr_cli-1.5.0.dist-info/top_level.txt,sha256=74rtVfumQlgAPzR5_2CgYN24MB0XARCg0t-gzk6gTrM,4
|
|
181
|
+
gitpr_cli-1.5.0.dist-info/RECORD,,
|
src/__init__.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
# Módulo principal do GitPR
|
|
1
|
+
# Módulo principal do GitPR
|
src/application/__init__.py
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
# Application layer markers
|
|
2
|
-
|
|
1
|
+
# Application layer markers
|
|
2
|
+
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
from src.application.use_cases.generate_test_file import generate_test_file, validate_test_syntax
|
|
2
|
-
from src.application.use_cases.generate_pr_explanation import generate_pr_explanation
|
|
3
|
-
|
|
4
|
-
__all__ = [
|
|
5
|
-
"generate_test_file",
|
|
6
|
-
"validate_test_syntax",
|
|
7
|
-
"generate_pr_explanation",
|
|
8
|
-
]
|
|
1
|
+
from src.application.use_cases.generate_test_file import generate_test_file, validate_test_syntax
|
|
2
|
+
from src.application.use_cases.generate_pr_explanation import generate_pr_explanation
|
|
3
|
+
|
|
4
|
+
__all__ = [
|
|
5
|
+
"generate_test_file",
|
|
6
|
+
"validate_test_syntax",
|
|
7
|
+
"generate_pr_explanation",
|
|
8
|
+
]
|
|
@@ -1,122 +1,122 @@
|
|
|
1
|
-
"""Use case: record which pack a repository follows.
|
|
2
|
-
|
|
3
|
-
The record is ``.gitpr/policy.lock.yml``, a file meant to be committed: it is
|
|
4
|
-
what makes the policy the same for everyone on the team and what lets a later
|
|
5
|
-
run notice that a pack changed under it.
|
|
6
|
-
|
|
7
|
-
Activation is **one pack per repository**. Choosing a second one replaces the
|
|
8
|
-
first rather than adding to it, so there is never a question about which pack
|
|
9
|
-
owns a value — the graph below the root is reached through ``extends``, and only
|
|
10
|
-
through it.
|
|
11
|
-
|
|
12
|
-
Building the lockfile and writing it are separate functions because the CLI has
|
|
13
|
-
to show the user what will be written *before* asking whether to write it. A
|
|
14
|
-
command that writes first and asks afterwards is not asking.
|
|
15
|
-
"""
|
|
16
|
-
|
|
17
|
-
import os
|
|
18
|
-
from datetime import datetime, timezone
|
|
19
|
-
from typing import Any
|
|
20
|
-
|
|
21
|
-
from src.domain.policy import set_active_policy
|
|
22
|
-
from src.domain.policy.policy_resolver import resolve_graph
|
|
23
|
-
from src.i18n import __
|
|
24
|
-
from src.infrastructure.policy.local_policy_repository import (
|
|
25
|
-
LOCKFILE_SCHEMA_VERSION,
|
|
26
|
-
lockfile_path,
|
|
27
|
-
write_lockfile,
|
|
28
|
-
)
|
|
29
|
-
from src.infrastructure.policy.policy_pack_loader import (
|
|
30
|
-
load_pack_by_reference,
|
|
31
|
-
make_loader,
|
|
32
|
-
)
|
|
33
|
-
|
|
34
|
-
from src.application.use_cases.validate_policy_pack import split_reference
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
def _relative_to_repo(absolute: str, repo_path: str) -> str | None:
|
|
38
|
-
"""*absolute* as a repository-relative POSIX path, or None when outside.
|
|
39
|
-
|
|
40
|
-
Only packs that live inside the repository are recorded by path. A pack in
|
|
41
|
-
``~/.gitpr/policies/`` is recorded by name and version instead, so the
|
|
42
|
-
lockfile stays valid for a teammate who has it installed somewhere else.
|
|
43
|
-
"""
|
|
44
|
-
try:
|
|
45
|
-
relative = os.path.relpath(absolute, repo_path)
|
|
46
|
-
except ValueError:
|
|
47
|
-
# Different drives on Windows.
|
|
48
|
-
return None
|
|
49
|
-
parts = relative.split(os.sep)
|
|
50
|
-
if not relative or parts[0] == "..":
|
|
51
|
-
return None
|
|
52
|
-
return relative.replace(os.sep, "/")
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
def _lockfile_entry(pack: Any, repo_path: str) -> dict[str, Any]:
|
|
56
|
-
entry: dict[str, Any] = {
|
|
57
|
-
"name": pack.reference.name,
|
|
58
|
-
"version": pack.reference.version,
|
|
59
|
-
"source": pack.reference.source.value,
|
|
60
|
-
"checksum": pack.reference.checksum,
|
|
61
|
-
}
|
|
62
|
-
if pack.reference.path:
|
|
63
|
-
relative = _relative_to_repo(pack.reference.path, repo_path)
|
|
64
|
-
if relative:
|
|
65
|
-
entry["path"] = relative
|
|
66
|
-
return entry
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
def build_lockfile(root_reference: str, repo_path: str | None = None) -> dict[str, Any]:
|
|
70
|
-
"""Resolves *root_reference* and the lockfile that would pin it.
|
|
71
|
-
|
|
72
|
-
Raises ``PolicyError`` when the pack cannot be found or its graph does not
|
|
73
|
-
resolve, and writes nothing. The CLI calls this first, shows the result, and
|
|
74
|
-
only then decides whether to call :func:`activate_policy_pack`.
|
|
75
|
-
"""
|
|
76
|
-
from src.updater import __version__
|
|
77
|
-
|
|
78
|
-
repo = os.path.abspath(repo_path or os.getcwd())
|
|
79
|
-
name, version_range = split_reference(root_reference)
|
|
80
|
-
root = load_pack_by_reference(name, version_range, repo)
|
|
81
|
-
packs = resolve_graph(root, make_loader(repo))
|
|
82
|
-
|
|
83
|
-
return {
|
|
84
|
-
"schema_version": LOCKFILE_SCHEMA_VERSION,
|
|
85
|
-
"gitpr_version": __version__,
|
|
86
|
-
"activated_at": datetime.now(timezone.utc).isoformat(timespec="seconds"),
|
|
87
|
-
"root": _lockfile_entry(root, repo),
|
|
88
|
-
"packs": [_lockfile_entry(pack, repo) for pack in packs],
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
def activate_policy_pack(root_reference: str, repo_path: str | None = None) -> str:
|
|
93
|
-
"""Pins *root_reference* for the repository and returns the lockfile path."""
|
|
94
|
-
data = build_lockfile(root_reference, repo_path)
|
|
95
|
-
return write_lockfile(data, repo_path)
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
def deactivate_policy_pack(repo_path: str | None = None) -> bool:
|
|
99
|
-
"""Removes the lockfile. Returns whether there was one to remove.
|
|
100
|
-
|
|
101
|
-
The overrides file and the packs themselves are left alone: they are the
|
|
102
|
-
user's material, and a decision to stop following a pack is not a decision to
|
|
103
|
-
delete it.
|
|
104
|
-
"""
|
|
105
|
-
target = lockfile_path(repo_path)
|
|
106
|
-
if not os.path.isfile(target):
|
|
107
|
-
return False
|
|
108
|
-
os.remove(target)
|
|
109
|
-
set_active_policy(None)
|
|
110
|
-
return True
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
def describe_lockfile(data: dict[str, Any]) -> str:
|
|
114
|
-
"""A one-line summary for the confirmation prompt."""
|
|
115
|
-
root = data.get("root") or {}
|
|
116
|
-
dependencies = [p for p in data.get("packs", []) if p.get("name") != root.get("name")]
|
|
117
|
-
return __(
|
|
118
|
-
"{pack}@{version} with {count} dependency pack(s)",
|
|
119
|
-
pack=root.get("name", "?"),
|
|
120
|
-
version=root.get("version", "?"),
|
|
121
|
-
count=len(dependencies),
|
|
122
|
-
)
|
|
1
|
+
"""Use case: record which pack a repository follows.
|
|
2
|
+
|
|
3
|
+
The record is ``.gitpr/policy.lock.yml``, a file meant to be committed: it is
|
|
4
|
+
what makes the policy the same for everyone on the team and what lets a later
|
|
5
|
+
run notice that a pack changed under it.
|
|
6
|
+
|
|
7
|
+
Activation is **one pack per repository**. Choosing a second one replaces the
|
|
8
|
+
first rather than adding to it, so there is never a question about which pack
|
|
9
|
+
owns a value — the graph below the root is reached through ``extends``, and only
|
|
10
|
+
through it.
|
|
11
|
+
|
|
12
|
+
Building the lockfile and writing it are separate functions because the CLI has
|
|
13
|
+
to show the user what will be written *before* asking whether to write it. A
|
|
14
|
+
command that writes first and asks afterwards is not asking.
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
import os
|
|
18
|
+
from datetime import datetime, timezone
|
|
19
|
+
from typing import Any
|
|
20
|
+
|
|
21
|
+
from src.domain.policy import set_active_policy
|
|
22
|
+
from src.domain.policy.policy_resolver import resolve_graph
|
|
23
|
+
from src.i18n import __
|
|
24
|
+
from src.infrastructure.policy.local_policy_repository import (
|
|
25
|
+
LOCKFILE_SCHEMA_VERSION,
|
|
26
|
+
lockfile_path,
|
|
27
|
+
write_lockfile,
|
|
28
|
+
)
|
|
29
|
+
from src.infrastructure.policy.policy_pack_loader import (
|
|
30
|
+
load_pack_by_reference,
|
|
31
|
+
make_loader,
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
from src.application.use_cases.validate_policy_pack import split_reference
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def _relative_to_repo(absolute: str, repo_path: str) -> str | None:
|
|
38
|
+
"""*absolute* as a repository-relative POSIX path, or None when outside.
|
|
39
|
+
|
|
40
|
+
Only packs that live inside the repository are recorded by path. A pack in
|
|
41
|
+
``~/.gitpr/policies/`` is recorded by name and version instead, so the
|
|
42
|
+
lockfile stays valid for a teammate who has it installed somewhere else.
|
|
43
|
+
"""
|
|
44
|
+
try:
|
|
45
|
+
relative = os.path.relpath(absolute, repo_path)
|
|
46
|
+
except ValueError:
|
|
47
|
+
# Different drives on Windows.
|
|
48
|
+
return None
|
|
49
|
+
parts = relative.split(os.sep)
|
|
50
|
+
if not relative or parts[0] == "..":
|
|
51
|
+
return None
|
|
52
|
+
return relative.replace(os.sep, "/")
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def _lockfile_entry(pack: Any, repo_path: str) -> dict[str, Any]:
|
|
56
|
+
entry: dict[str, Any] = {
|
|
57
|
+
"name": pack.reference.name,
|
|
58
|
+
"version": pack.reference.version,
|
|
59
|
+
"source": pack.reference.source.value,
|
|
60
|
+
"checksum": pack.reference.checksum,
|
|
61
|
+
}
|
|
62
|
+
if pack.reference.path:
|
|
63
|
+
relative = _relative_to_repo(pack.reference.path, repo_path)
|
|
64
|
+
if relative:
|
|
65
|
+
entry["path"] = relative
|
|
66
|
+
return entry
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def build_lockfile(root_reference: str, repo_path: str | None = None) -> dict[str, Any]:
|
|
70
|
+
"""Resolves *root_reference* and the lockfile that would pin it.
|
|
71
|
+
|
|
72
|
+
Raises ``PolicyError`` when the pack cannot be found or its graph does not
|
|
73
|
+
resolve, and writes nothing. The CLI calls this first, shows the result, and
|
|
74
|
+
only then decides whether to call :func:`activate_policy_pack`.
|
|
75
|
+
"""
|
|
76
|
+
from src.updater import __version__
|
|
77
|
+
|
|
78
|
+
repo = os.path.abspath(repo_path or os.getcwd())
|
|
79
|
+
name, version_range = split_reference(root_reference)
|
|
80
|
+
root = load_pack_by_reference(name, version_range, repo)
|
|
81
|
+
packs = resolve_graph(root, make_loader(repo))
|
|
82
|
+
|
|
83
|
+
return {
|
|
84
|
+
"schema_version": LOCKFILE_SCHEMA_VERSION,
|
|
85
|
+
"gitpr_version": __version__,
|
|
86
|
+
"activated_at": datetime.now(timezone.utc).isoformat(timespec="seconds"),
|
|
87
|
+
"root": _lockfile_entry(root, repo),
|
|
88
|
+
"packs": [_lockfile_entry(pack, repo) for pack in packs],
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
def activate_policy_pack(root_reference: str, repo_path: str | None = None) -> str:
|
|
93
|
+
"""Pins *root_reference* for the repository and returns the lockfile path."""
|
|
94
|
+
data = build_lockfile(root_reference, repo_path)
|
|
95
|
+
return write_lockfile(data, repo_path)
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
def deactivate_policy_pack(repo_path: str | None = None) -> bool:
|
|
99
|
+
"""Removes the lockfile. Returns whether there was one to remove.
|
|
100
|
+
|
|
101
|
+
The overrides file and the packs themselves are left alone: they are the
|
|
102
|
+
user's material, and a decision to stop following a pack is not a decision to
|
|
103
|
+
delete it.
|
|
104
|
+
"""
|
|
105
|
+
target = lockfile_path(repo_path)
|
|
106
|
+
if not os.path.isfile(target):
|
|
107
|
+
return False
|
|
108
|
+
os.remove(target)
|
|
109
|
+
set_active_policy(None)
|
|
110
|
+
return True
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
def describe_lockfile(data: dict[str, Any]) -> str:
|
|
114
|
+
"""A one-line summary for the confirmation prompt."""
|
|
115
|
+
root = data.get("root") or {}
|
|
116
|
+
dependencies = [p for p in data.get("packs", []) if p.get("name") != root.get("name")]
|
|
117
|
+
return __(
|
|
118
|
+
"{pack}@{version} with {count} dependency pack(s)",
|
|
119
|
+
pack=root.get("name", "?"),
|
|
120
|
+
version=root.get("version", "?"),
|
|
121
|
+
count=len(dependencies),
|
|
122
|
+
)
|