gitpr-cli 0.0.14__tar.gz → 0.0.15__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.
- {gitpr_cli-0.0.14 → gitpr_cli-0.0.15}/PKG-INFO +7 -2
- {gitpr_cli-0.0.14 → gitpr_cli-0.0.15}/README.md +6 -1
- {gitpr_cli-0.0.14 → gitpr_cli-0.0.15}/gitpr_cli.egg-info/PKG-INFO +7 -2
- {gitpr_cli-0.0.14 → gitpr_cli-0.0.15}/gitpr_cli.egg-info/SOURCES.txt +2 -0
- {gitpr_cli-0.0.14 → gitpr_cli-0.0.15}/pyproject.toml +1 -1
- {gitpr_cli-0.0.14 → gitpr_cli-0.0.15}/src/config.py +12 -2
- {gitpr_cli-0.0.14 → gitpr_cli-0.0.15}/src/core.py +3 -0
- gitpr_cli-0.0.15/src/issue_engine.py +76 -0
- {gitpr_cli-0.0.14 → gitpr_cli-0.0.15}/src/main.py +43 -2
- gitpr_cli-0.0.15/src/tui_issue.py +34 -0
- {gitpr_cli-0.0.14 → gitpr_cli-0.0.15}/src/updater.py +1 -1
- {gitpr_cli-0.0.14 → gitpr_cli-0.0.15}/LICENSE +0 -0
- {gitpr_cli-0.0.14 → gitpr_cli-0.0.15}/gitpr_cli.egg-info/dependency_links.txt +0 -0
- {gitpr_cli-0.0.14 → gitpr_cli-0.0.15}/gitpr_cli.egg-info/entry_points.txt +0 -0
- {gitpr_cli-0.0.14 → gitpr_cli-0.0.15}/gitpr_cli.egg-info/requires.txt +0 -0
- {gitpr_cli-0.0.14 → gitpr_cli-0.0.15}/gitpr_cli.egg-info/top_level.txt +0 -0
- {gitpr_cli-0.0.14 → gitpr_cli-0.0.15}/setup.cfg +0 -0
- {gitpr_cli-0.0.14 → gitpr_cli-0.0.15}/src/__init__.py +0 -0
- {gitpr_cli-0.0.14 → gitpr_cli-0.0.15}/src/ai_providers.py +0 -0
- {gitpr_cli-0.0.14 → gitpr_cli-0.0.15}/src/blame_engine.py +0 -0
- {gitpr_cli-0.0.14 → gitpr_cli-0.0.15}/src/cache.py +0 -0
- {gitpr_cli-0.0.14 → gitpr_cli-0.0.15}/src/linter_engine.py +0 -0
- {gitpr_cli-0.0.14 → gitpr_cli-0.0.15}/src/security.py +0 -0
- {gitpr_cli-0.0.14 → gitpr_cli-0.0.15}/tests/test_core.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: gitpr-cli
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.15
|
|
4
4
|
Summary: Automação de PRs, Commits e Code Review com IA (Gemini e DeepSeek)
|
|
5
5
|
Author-email: Natan Fiuza <contato@natanfiuza.dev.br>
|
|
6
6
|
Requires-Python: >=3.10
|
|
@@ -29,6 +29,8 @@ Este projeto foi desenvolvido em Python e utiliza as seguintes bibliotecas princ
|
|
|
29
29
|
* [**Pytest**](https://docs.pytest.org/): Para execução de testes unitários de forma simples, colorida e legível no console.
|
|
30
30
|
* [**Cryptography**](https://cryptography.io/): Para garantir que sua `GEMINI_API_KEY` seja armazenada de forma encriptada e segura no disco.
|
|
31
31
|
* [**PyYAML**](https://pyyaml.org/): Utilizado para ler e processar as regras customizadas de análise estática do arquivo `.gitpr.linter.yml`.
|
|
32
|
+
* [**Textual**](https://textual.textualize.io/): Biblioteca poderosa para a criação de Interfaces Gráficas de Terminal (TUI), utilizada no painel interativo de geração e edição de Issues.
|
|
33
|
+
* [**Requests**](https://pypi.org/project/requests/): Biblioteca elegante e robusta para requisições HTTP, utilizada para a comunicação com a API REST do GitHub.
|
|
32
34
|
|
|
33
35
|
----
|
|
34
36
|
|
|
@@ -124,6 +126,7 @@ Você pode passar as seguintes *flags* para ações específicas:
|
|
|
124
126
|
* `-l` ou `--linter`: Roda **apenas o linter estático local** (sem chamadas de IA). Ideal para usar em pipelines de CI/CD para bloquear código fora do padrão.
|
|
125
127
|
* `-ih` ou `--installhooks`: Instala automaticamente os **Git Hooks locais** (`pre-commit` e `prepare-commit-msg`) no seu repositório.
|
|
126
128
|
* `-s` ou `--skill`: Cria os arquivos de template de contexto da IA (`.gitpr.commit.md`, `.gitpr.pr.md`, `.gitpr.review.md`, `.gitpr.filereview.md`) e do Linter (`.gitpr.linter.yml`) na raiz do projeto.
|
|
129
|
+
* `-is` ou `--issue`: Gera automaticamente o rascunho de uma **Issue padronizada** a partir do diff e abre uma interface interativa (TUI) para edição, salvamento ou envio direto para o repositório no GitHub via API REST.
|
|
127
130
|
* `-u` ou `--update`: Verifica e instala a versão mais recente do GitPR (Auto-Updater).
|
|
128
131
|
* `-h` ou `--help`: Exibe o menu de ajuda.
|
|
129
132
|
|
|
@@ -175,7 +178,8 @@ Se você deseja implementar o GitPR como uma barreira de qualidade automatizada
|
|
|
175
178
|
|
|
176
179
|
* [**Guia de Git Hooks Locais (Shift-Left)**](docs/local-git-hooks.md): Como usar o `gitpr --installhooks` para criar travas na máquina do desenvolvedor (bloqueio de *console.log*, *localhost*, etc.) e usar a IA para escrever mensagens de commit automaticamente no editor.
|
|
177
180
|
* [**Integração com CI/CD (GitHub Actions)**](docs/github-ci-linter.md): Como rodar o GitPR no seu pipeline na nuvem para realizar a validação estática e travar o botão de "Merge" de Pull Requests que violem as regras do projeto.
|
|
178
|
-
|
|
181
|
+
* [**Geração de Issues e Interface TUI**](docs/issue-tui-help.md): Como utilizar a interface gráfica de terminal (TUI) para revisar e gerenciar Issues estruturadas antes do envio.
|
|
182
|
+
* [**Integração e Segurança do Token GitHub (PAT)**](docs/github-pat-integration.md): Entenda como o GitPR gera issues diretamente no seu repositório de forma autenticada, mantendo suas credenciais criptografadas localmente.
|
|
179
183
|
|
|
180
184
|
## ⚡ Sistema de Cache Local (Economia de Quota)
|
|
181
185
|
|
|
@@ -189,6 +193,7 @@ Nunca mais se preocupe em baixar novas versões manualmente. O GitPR possui um G
|
|
|
189
193
|
* Em cada execução, ele verifica silenciosamente se há um novo release oficial na API do GitHub.
|
|
190
194
|
* Você pode forçar a busca e instalação rodando `gitpr --update` ou `gitpr -u`.
|
|
191
195
|
* A ferramenta utiliza a técnica de *Hot-Swap*, baixando o novo `.exe` e substituindo a versão antiga de forma transparente.
|
|
196
|
+
|
|
192
197
|
## Publicar no PyPi
|
|
193
198
|
|
|
194
199
|
```bash
|
|
@@ -13,6 +13,8 @@ Este projeto foi desenvolvido em Python e utiliza as seguintes bibliotecas princ
|
|
|
13
13
|
* [**Pytest**](https://docs.pytest.org/): Para execução de testes unitários de forma simples, colorida e legível no console.
|
|
14
14
|
* [**Cryptography**](https://cryptography.io/): Para garantir que sua `GEMINI_API_KEY` seja armazenada de forma encriptada e segura no disco.
|
|
15
15
|
* [**PyYAML**](https://pyyaml.org/): Utilizado para ler e processar as regras customizadas de análise estática do arquivo `.gitpr.linter.yml`.
|
|
16
|
+
* [**Textual**](https://textual.textualize.io/): Biblioteca poderosa para a criação de Interfaces Gráficas de Terminal (TUI), utilizada no painel interativo de geração e edição de Issues.
|
|
17
|
+
* [**Requests**](https://pypi.org/project/requests/): Biblioteca elegante e robusta para requisições HTTP, utilizada para a comunicação com a API REST do GitHub.
|
|
16
18
|
|
|
17
19
|
----
|
|
18
20
|
|
|
@@ -108,6 +110,7 @@ Você pode passar as seguintes *flags* para ações específicas:
|
|
|
108
110
|
* `-l` ou `--linter`: Roda **apenas o linter estático local** (sem chamadas de IA). Ideal para usar em pipelines de CI/CD para bloquear código fora do padrão.
|
|
109
111
|
* `-ih` ou `--installhooks`: Instala automaticamente os **Git Hooks locais** (`pre-commit` e `prepare-commit-msg`) no seu repositório.
|
|
110
112
|
* `-s` ou `--skill`: Cria os arquivos de template de contexto da IA (`.gitpr.commit.md`, `.gitpr.pr.md`, `.gitpr.review.md`, `.gitpr.filereview.md`) e do Linter (`.gitpr.linter.yml`) na raiz do projeto.
|
|
113
|
+
* `-is` ou `--issue`: Gera automaticamente o rascunho de uma **Issue padronizada** a partir do diff e abre uma interface interativa (TUI) para edição, salvamento ou envio direto para o repositório no GitHub via API REST.
|
|
111
114
|
* `-u` ou `--update`: Verifica e instala a versão mais recente do GitPR (Auto-Updater).
|
|
112
115
|
* `-h` ou `--help`: Exibe o menu de ajuda.
|
|
113
116
|
|
|
@@ -159,7 +162,8 @@ Se você deseja implementar o GitPR como uma barreira de qualidade automatizada
|
|
|
159
162
|
|
|
160
163
|
* [**Guia de Git Hooks Locais (Shift-Left)**](docs/local-git-hooks.md): Como usar o `gitpr --installhooks` para criar travas na máquina do desenvolvedor (bloqueio de *console.log*, *localhost*, etc.) e usar a IA para escrever mensagens de commit automaticamente no editor.
|
|
161
164
|
* [**Integração com CI/CD (GitHub Actions)**](docs/github-ci-linter.md): Como rodar o GitPR no seu pipeline na nuvem para realizar a validação estática e travar o botão de "Merge" de Pull Requests que violem as regras do projeto.
|
|
162
|
-
|
|
165
|
+
* [**Geração de Issues e Interface TUI**](docs/issue-tui-help.md): Como utilizar a interface gráfica de terminal (TUI) para revisar e gerenciar Issues estruturadas antes do envio.
|
|
166
|
+
* [**Integração e Segurança do Token GitHub (PAT)**](docs/github-pat-integration.md): Entenda como o GitPR gera issues diretamente no seu repositório de forma autenticada, mantendo suas credenciais criptografadas localmente.
|
|
163
167
|
|
|
164
168
|
## ⚡ Sistema de Cache Local (Economia de Quota)
|
|
165
169
|
|
|
@@ -173,6 +177,7 @@ Nunca mais se preocupe em baixar novas versões manualmente. O GitPR possui um G
|
|
|
173
177
|
* Em cada execução, ele verifica silenciosamente se há um novo release oficial na API do GitHub.
|
|
174
178
|
* Você pode forçar a busca e instalação rodando `gitpr --update` ou `gitpr -u`.
|
|
175
179
|
* A ferramenta utiliza a técnica de *Hot-Swap*, baixando o novo `.exe` e substituindo a versão antiga de forma transparente.
|
|
180
|
+
|
|
176
181
|
## Publicar no PyPi
|
|
177
182
|
|
|
178
183
|
```bash
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: gitpr-cli
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.15
|
|
4
4
|
Summary: Automação de PRs, Commits e Code Review com IA (Gemini e DeepSeek)
|
|
5
5
|
Author-email: Natan Fiuza <contato@natanfiuza.dev.br>
|
|
6
6
|
Requires-Python: >=3.10
|
|
@@ -29,6 +29,8 @@ Este projeto foi desenvolvido em Python e utiliza as seguintes bibliotecas princ
|
|
|
29
29
|
* [**Pytest**](https://docs.pytest.org/): Para execução de testes unitários de forma simples, colorida e legível no console.
|
|
30
30
|
* [**Cryptography**](https://cryptography.io/): Para garantir que sua `GEMINI_API_KEY` seja armazenada de forma encriptada e segura no disco.
|
|
31
31
|
* [**PyYAML**](https://pyyaml.org/): Utilizado para ler e processar as regras customizadas de análise estática do arquivo `.gitpr.linter.yml`.
|
|
32
|
+
* [**Textual**](https://textual.textualize.io/): Biblioteca poderosa para a criação de Interfaces Gráficas de Terminal (TUI), utilizada no painel interativo de geração e edição de Issues.
|
|
33
|
+
* [**Requests**](https://pypi.org/project/requests/): Biblioteca elegante e robusta para requisições HTTP, utilizada para a comunicação com a API REST do GitHub.
|
|
32
34
|
|
|
33
35
|
----
|
|
34
36
|
|
|
@@ -124,6 +126,7 @@ Você pode passar as seguintes *flags* para ações específicas:
|
|
|
124
126
|
* `-l` ou `--linter`: Roda **apenas o linter estático local** (sem chamadas de IA). Ideal para usar em pipelines de CI/CD para bloquear código fora do padrão.
|
|
125
127
|
* `-ih` ou `--installhooks`: Instala automaticamente os **Git Hooks locais** (`pre-commit` e `prepare-commit-msg`) no seu repositório.
|
|
126
128
|
* `-s` ou `--skill`: Cria os arquivos de template de contexto da IA (`.gitpr.commit.md`, `.gitpr.pr.md`, `.gitpr.review.md`, `.gitpr.filereview.md`) e do Linter (`.gitpr.linter.yml`) na raiz do projeto.
|
|
129
|
+
* `-is` ou `--issue`: Gera automaticamente o rascunho de uma **Issue padronizada** a partir do diff e abre uma interface interativa (TUI) para edição, salvamento ou envio direto para o repositório no GitHub via API REST.
|
|
127
130
|
* `-u` ou `--update`: Verifica e instala a versão mais recente do GitPR (Auto-Updater).
|
|
128
131
|
* `-h` ou `--help`: Exibe o menu de ajuda.
|
|
129
132
|
|
|
@@ -175,7 +178,8 @@ Se você deseja implementar o GitPR como uma barreira de qualidade automatizada
|
|
|
175
178
|
|
|
176
179
|
* [**Guia de Git Hooks Locais (Shift-Left)**](docs/local-git-hooks.md): Como usar o `gitpr --installhooks` para criar travas na máquina do desenvolvedor (bloqueio de *console.log*, *localhost*, etc.) e usar a IA para escrever mensagens de commit automaticamente no editor.
|
|
177
180
|
* [**Integração com CI/CD (GitHub Actions)**](docs/github-ci-linter.md): Como rodar o GitPR no seu pipeline na nuvem para realizar a validação estática e travar o botão de "Merge" de Pull Requests que violem as regras do projeto.
|
|
178
|
-
|
|
181
|
+
* [**Geração de Issues e Interface TUI**](docs/issue-tui-help.md): Como utilizar a interface gráfica de terminal (TUI) para revisar e gerenciar Issues estruturadas antes do envio.
|
|
182
|
+
* [**Integração e Segurança do Token GitHub (PAT)**](docs/github-pat-integration.md): Entenda como o GitPR gera issues diretamente no seu repositório de forma autenticada, mantendo suas credenciais criptografadas localmente.
|
|
179
183
|
|
|
180
184
|
## ⚡ Sistema de Cache Local (Economia de Quota)
|
|
181
185
|
|
|
@@ -189,6 +193,7 @@ Nunca mais se preocupe em baixar novas versões manualmente. O GitPR possui um G
|
|
|
189
193
|
* Em cada execução, ele verifica silenciosamente se há um novo release oficial na API do GitHub.
|
|
190
194
|
* Você pode forçar a busca e instalação rodando `gitpr --update` ou `gitpr -u`.
|
|
191
195
|
* A ferramenta utiliza a técnica de *Hot-Swap*, baixando o novo `.exe` e substituindo a versão antiga de forma transparente.
|
|
196
|
+
|
|
192
197
|
## Publicar no PyPi
|
|
193
198
|
|
|
194
199
|
```bash
|
|
@@ -21,7 +21,8 @@ DEFAULT_CONFIG = {
|
|
|
21
21
|
"OUTPUT_FILE_NAME_REVIEW": "{branch}_{datetime}_PR_REVIEW.txt",
|
|
22
22
|
"OUTPUT_FILE_NAME_FULLREVIEW": "{branch}_{datetime}_PR_FULLREVIEW.txt",
|
|
23
23
|
"OUTPUT_FILE_NAME_FILEREVIEW": "{branch}_{datetime}_FILE_REVIEW.txt",
|
|
24
|
-
"OUTPUT_FILE_NAME_BLAME": "{branch}_{datetime}_BLAME_REPORT.md"
|
|
24
|
+
"OUTPUT_FILE_NAME_BLAME": "{branch}_{datetime}_BLAME_REPORT.md",
|
|
25
|
+
"OUTPUT_FILE_NAME_ISSUE": "{branch}_{datetime}_ISSUE.md"
|
|
25
26
|
}
|
|
26
27
|
|
|
27
28
|
def get_ai_provider():
|
|
@@ -152,4 +153,13 @@ def load_linter_rules():
|
|
|
152
153
|
return []
|
|
153
154
|
except Exception as e:
|
|
154
155
|
click.secho(f"\n❌ Erro inesperado ao ler as regras do linter: {e}", fg="red")
|
|
155
|
-
return []
|
|
156
|
+
return []
|
|
157
|
+
|
|
158
|
+
def get_github_token():
|
|
159
|
+
"""Lê e desencripta o token de acesso pessoal (PAT) do GitHub."""
|
|
160
|
+
load_dotenv(ENV_FILE)
|
|
161
|
+
encrypted_token = os.getenv("GITHUB_TOKEN_ENCRYPTED")
|
|
162
|
+
|
|
163
|
+
if encrypted_token:
|
|
164
|
+
return decrypt_data(encrypted_token)
|
|
165
|
+
return None
|
|
@@ -76,6 +76,8 @@ def get_skill_context(action_type="pr"):
|
|
|
76
76
|
target_file = ".gitpr.pr.md"
|
|
77
77
|
elif action_type == "filereview": # NOVO!
|
|
78
78
|
target_file = ".gitpr.filereview.md"
|
|
79
|
+
elif action_type == "issue":
|
|
80
|
+
target_file = ".gitpr.issue.md"
|
|
79
81
|
else: # review ou fullreview
|
|
80
82
|
target_file = ".gitpr.review.md"
|
|
81
83
|
|
|
@@ -189,6 +191,7 @@ def generate_skill_template():
|
|
|
189
191
|
".gitpr.linter.yml": "gitpr.linter.yml",
|
|
190
192
|
".gitpr.filereview.md": "gitpr.filereview.md",
|
|
191
193
|
".gitpr.blame.md": "gitpr.blame.md",
|
|
194
|
+
".gitpr.issue.md": "gitpr.issue.md",
|
|
192
195
|
}
|
|
193
196
|
|
|
194
197
|
success_count = 0
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import subprocess
|
|
2
|
+
import re
|
|
3
|
+
import os
|
|
4
|
+
import click
|
|
5
|
+
from src.ai_providers import call_ai_model
|
|
6
|
+
from src.cache import get_cached_response, save_cached_response
|
|
7
|
+
from src.config import get_api_key, get_api_model, get_ai_provider
|
|
8
|
+
from src.ai_providers import call_ai_model
|
|
9
|
+
|
|
10
|
+
def get_github_repo_info():
|
|
11
|
+
"""Extrai o formato owner/repo do comando git remote -v."""
|
|
12
|
+
try:
|
|
13
|
+
result = subprocess.run(
|
|
14
|
+
["git", "remote", "-v"],
|
|
15
|
+
capture_output=True,
|
|
16
|
+
text=True,
|
|
17
|
+
check=True
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
# Busca padrões como git@github.com:owner/repo.git ou https://github.com/owner/repo.git
|
|
21
|
+
match = re.search(r'github\.com[:/](.+?)/(.+?)(\.git)?\s+\(push\)', result.stdout)
|
|
22
|
+
|
|
23
|
+
if match:
|
|
24
|
+
owner = match.group(1)
|
|
25
|
+
repo = match.group(2).replace('.git', '')
|
|
26
|
+
return f"{owner}/{repo}"
|
|
27
|
+
|
|
28
|
+
return None
|
|
29
|
+
except subprocess.CalledProcessError:
|
|
30
|
+
return None
|
|
31
|
+
|
|
32
|
+
def generate_issue_content(diff_text):
|
|
33
|
+
"""Envia o diff para a IA e retorna um dicionário com título e corpo da issue."""
|
|
34
|
+
if not diff_text or not diff_text.strip():
|
|
35
|
+
return None
|
|
36
|
+
|
|
37
|
+
provider = get_ai_provider()
|
|
38
|
+
api_key = get_api_key(provider)
|
|
39
|
+
|
|
40
|
+
if not api_key:
|
|
41
|
+
click.secho("❌ Erro: Chave de API não encontrada.", fg="red")
|
|
42
|
+
return None
|
|
43
|
+
|
|
44
|
+
# Utilizamos o modelo avançado para garantir a qualidade da estrutura da Issue
|
|
45
|
+
api_model = get_api_model(provider, task_complexity="advanced")
|
|
46
|
+
|
|
47
|
+
skill_path = os.path.join(os.getcwd(), ".gitpr.issue.md")
|
|
48
|
+
sys_inst = ""
|
|
49
|
+
|
|
50
|
+
if os.path.exists(skill_path):
|
|
51
|
+
with open(skill_path, "r", encoding="utf-8") as f:
|
|
52
|
+
sys_inst = f.read()
|
|
53
|
+
else:
|
|
54
|
+
sys_inst = "Você é um Arquiteto de Software. Siga o formato O Que / Por Que / Onde / Como para documentar a Issue."
|
|
55
|
+
|
|
56
|
+
prompt = (
|
|
57
|
+
f"Gere o objeto JSON solicitado seguindo as instruções de sistema para documentar a seguinte alteração:\n\n"
|
|
58
|
+
f"DIFF PARA ANÁLISE:\n{diff_text}"
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
# --- NOVO: Tenta recuperar do Cache ---
|
|
62
|
+
cached_data = get_cached_response("issue", prompt)
|
|
63
|
+
if cached_data:
|
|
64
|
+
click.secho("⚡ Resposta da Issue recuperada do cache local.", fg="green", dim=True)
|
|
65
|
+
return cached_data
|
|
66
|
+
|
|
67
|
+
click.secho(f"🤖 Estruturando a Issue usando {provider.capitalize()} ({api_model})...", fg="cyan", dim=True)
|
|
68
|
+
|
|
69
|
+
result_json = call_ai_model(provider, api_key, api_model, prompt, sys_inst)
|
|
70
|
+
|
|
71
|
+
if result_json and "titulo" in result_json and "corpo" in result_json:
|
|
72
|
+
# --- NOVO: Salva no Cache ---
|
|
73
|
+
save_cached_response("issue", "issue", prompt, result_json)
|
|
74
|
+
return result_json
|
|
75
|
+
|
|
76
|
+
return {"titulo": "Erro ao gerar título", "corpo": "Não foi possível gerar o corpo da issue pela IA."}
|
|
@@ -29,7 +29,7 @@ def print_banner():
|
|
|
29
29
|
"""
|
|
30
30
|
click.secho(banner, fg="cyan", bold=True)
|
|
31
31
|
click.secho(f" 🚀 Automação Inteligente de PRs com IA (v{__version__})", fg="yellow", bold=True)
|
|
32
|
-
click.secho(" Opções: -c,--commit | -r,--review | -f,--fullreview | -l,--linter | -s,--skill | -u,--update | -ih,--installhooks | -h ou --help\n", fg="white", dim=True)
|
|
32
|
+
click.secho(" Opções: -c,--commit | -r,--review | -f,--fullreview | -l,--linter | -s,--skill | -u,--update | -ih,--installhooks | -is,--issue | -h ou --help\n", fg="white", dim=True)
|
|
33
33
|
|
|
34
34
|
|
|
35
35
|
# Configuração nativa do Click para aceitar -h além de --help
|
|
@@ -46,8 +46,9 @@ def print_banner():
|
|
|
46
46
|
@click.option('-q', '--quiet', is_flag=True, hidden=True, help="Oculta o banner e logs não essenciais (uso interno).")
|
|
47
47
|
@click.option('-i', '--input', type=click.Path(exists=True), help="Caminho de um arquivo específico para análise completa.")
|
|
48
48
|
@click.option('-b', '--blame', type=str, help="Analisa a origem de uma regra de negócio (ex: arquivo.py:10-20 ou apenas arquivo.py).")
|
|
49
|
+
@click.option('-is', '--issue', is_flag=True, help="Gera uma Issue padronizada das alterações atuais e abre a interface interativa.")
|
|
49
50
|
@click.option('-p', '--provider', type=click.Choice(['gemini', 'deepseek']), help="Força a utilização de um provedor de IA específico nesta execução.")
|
|
50
|
-
def cli(commit, review, fullreview, linter, skill, update, installhooks, hook, quiet, provider, input, blame):
|
|
51
|
+
def cli(commit, review, fullreview, linter, skill, update, installhooks, hook, quiet, provider, input, blame, issue):
|
|
51
52
|
"""
|
|
52
53
|
GitPR CLI - Automação de PRs e Code Review com IA.
|
|
53
54
|
|
|
@@ -177,6 +178,46 @@ def cli(commit, review, fullreview, linter, skill, update, installhooks, hook, q
|
|
|
177
178
|
run_blame_analysis(file_path.strip(), start_line.strip(), end_line.strip())
|
|
178
179
|
return
|
|
179
180
|
|
|
181
|
+
# Módulo Issue (--issue)
|
|
182
|
+
if issue:
|
|
183
|
+
# Importações sob demanda para não atrasar a CLI se não for usar a TUI
|
|
184
|
+
from src.issue_engine import generate_issue_content, get_github_repo_info
|
|
185
|
+
from src.tui_issue import validate_or_request_github_token, IssueApp
|
|
186
|
+
|
|
187
|
+
diff_text = get_git_diff()
|
|
188
|
+
if not diff_text or not diff_text.strip():
|
|
189
|
+
click.secho("\n⚠️ Nenhum código novo encontrado. Faça alguma alteração antes de gerar a issue.\n", fg="yellow")
|
|
190
|
+
return
|
|
191
|
+
|
|
192
|
+
# Garante que as chaves da IA estão configuradas antes de chamar o motor
|
|
193
|
+
setup_environment()
|
|
194
|
+
|
|
195
|
+
# Gera o conteúdo com a IA
|
|
196
|
+
issue_data = generate_issue_content(diff_text)
|
|
197
|
+
if not issue_data:
|
|
198
|
+
return
|
|
199
|
+
|
|
200
|
+
# Pega informações do repositório
|
|
201
|
+
repo_info = get_github_repo_info()
|
|
202
|
+
|
|
203
|
+
# Valida ou solicita o Token PAT
|
|
204
|
+
github_token = validate_or_request_github_token(repo_info)
|
|
205
|
+
|
|
206
|
+
if not github_token:
|
|
207
|
+
click.secho("❌ Acesso cancelado. O Token do GitHub é obrigatório para esta ação.", fg="red")
|
|
208
|
+
return
|
|
209
|
+
|
|
210
|
+
# Roda a Interface Gráfica do Terminal
|
|
211
|
+
app = IssueApp(issue_data=issue_data, repo_info=repo_info, github_token=github_token)
|
|
212
|
+
app.run()
|
|
213
|
+
|
|
214
|
+
# Exibe a mensagem de retorno após fechar a TUI
|
|
215
|
+
if app.final_message:
|
|
216
|
+
cor = "green" if app.final_action in ["saved", "created"] else "red"
|
|
217
|
+
click.secho(f"\n{app.final_message}\n", fg=cor, bold=True)
|
|
218
|
+
|
|
219
|
+
return
|
|
220
|
+
|
|
180
221
|
# Validação do Modo Input
|
|
181
222
|
if input and not (review or fullreview):
|
|
182
223
|
click.secho("\n❌ Erro: A opção --input (-i) só pode ser utilizada em conjunto com --review (-r) ou --fullreview (-f).", fg="red", bold=True)
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import click
|
|
2
|
+
from dotenv import set_key
|
|
3
|
+
from src.security import encrypt_data
|
|
4
|
+
from src.config import get_github_token, ENV_FILE
|
|
5
|
+
|
|
6
|
+
# Importa a classe do aplicativo da nossa nova pasta de classes
|
|
7
|
+
from src.ui.issue_app import IssueApp
|
|
8
|
+
|
|
9
|
+
def validate_or_request_github_token(repo_info):
|
|
10
|
+
"""Verifica se o PAT existe, caso contrário solicita ao usuário, encripta e salva."""
|
|
11
|
+
token = get_github_token()
|
|
12
|
+
if token:
|
|
13
|
+
return token
|
|
14
|
+
|
|
15
|
+
click.secho(f"\n🔐 Autenticação do GitHub Necessária", fg="cyan", bold=True)
|
|
16
|
+
click.echo("Para criar issues diretamente, precisamos de um Personal Access Token (PAT).")
|
|
17
|
+
click.echo("Clique no link abaixo para gerar um com a permissão 'repo' já selecionada:")
|
|
18
|
+
|
|
19
|
+
repo_param = repo_info if repo_info else "seu-repositorio"
|
|
20
|
+
url_token = f"https://github.com/settings/tokens/new?scopes=repo&description=GitPR+Token+({repo_param})"
|
|
21
|
+
click.secho(f"👉 {url_token}\n", fg="blue", underline=True)
|
|
22
|
+
|
|
23
|
+
# --- NOVO: Link dinâmico para a documentação técnica ---
|
|
24
|
+
click.secho("📚 Entenda por que precisamos do Token e como ele é protegido por criptografia:", fg="cyan", dim=True)
|
|
25
|
+
click.secho("👉 https://github.com/natanfiuza/gitpr/blob/main/docs/github-pat-integration.md\n", fg="blue", underline=True)
|
|
26
|
+
|
|
27
|
+
raw_token = click.prompt("Cole aqui o seu Token (PAT)", hide_input=True)
|
|
28
|
+
|
|
29
|
+
encrypted_token = encrypt_data(raw_token.strip())
|
|
30
|
+
|
|
31
|
+
set_key(ENV_FILE, "GITHUB_TOKEN_ENCRYPTED", encrypted_token)
|
|
32
|
+
click.secho("✅ Token encriptado e salvo com segurança no .env!\n", fg="green")
|
|
33
|
+
|
|
34
|
+
return raw_token.strip()
|
|
@@ -7,7 +7,7 @@ import click
|
|
|
7
7
|
from datetime import datetime
|
|
8
8
|
|
|
9
9
|
# Versão atual do seu executável local (Atualize isso a cada novo build!)
|
|
10
|
-
__version__ = "0.0.
|
|
10
|
+
__version__ = "0.0.15"
|
|
11
11
|
GITHUB_API_URL = "https://api.github.com/repos/natanfiuza/gitpr/releases/latest"
|
|
12
12
|
PYPI_API_URL = "https://pypi.org/pypi/gitpr-cli/json"
|
|
13
13
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|