git-copilot-commit 0.1.1__tar.gz → 0.1.2__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: git-copilot-commit
3
- Version: 0.1.1
3
+ Version: 0.1.2
4
4
  Summary: Automatically generate and commit changes using copilot
5
5
  Author-email: Dheepak Krishnamurthy <1813121+kdheepak@users.noreply.github.com>
6
6
  License-File: LICENSE
@@ -20,6 +20,8 @@ GitHub Copilot.
20
20
 
21
21
  - **AI-Generated Commit Messages**: Uses GitHub Copilot to analyze your staged changes and generate
22
22
  conventional commit messages
23
+ - **Multiple AI Models**: Choose from GPT-4, Claude, Gemini, and other available models
24
+ - **Configurable Defaults**: Set a default model to use across all commits
23
25
  - **Message Editing**: Edit generated messages using your git-configured editor or commit directly
24
26
  - **Conventional Commits**: Follows the [Conventional Commits](https://www.conventionalcommits.org/)
25
27
  specification
@@ -76,6 +78,7 @@ git-copilot-commit commit
76
78
 
77
79
  - `--all, -a`: Stage all files before committing
78
80
  - `--verbose, -v`: Show verbose output with file details
81
+ - `--model, -m`: Specify which AI model to use for generating the commit message
79
82
 
80
83
  1. The tool analyzes your changes
81
84
  2. Prompts you to stage files (if needed)
@@ -101,6 +104,18 @@ List available AI models:
101
104
  git-copilot-commit models
102
105
  ```
103
106
 
107
+ #### `config`
108
+
109
+ Manage application configuration:
110
+
111
+ ```bash
112
+ # Show current configuration
113
+ git-copilot-commit config --show
114
+
115
+ # Set a default model for all commits
116
+ git-copilot-commit config --set-default-model gpt-4o
117
+ ```
118
+
104
119
  ### Examples
105
120
 
106
121
  **Commit all changes with staging prompts:**
@@ -115,6 +130,25 @@ git-copilot-commit commit --all
115
130
  git-copilot-commit commit --verbose
116
131
  ```
117
132
 
133
+ **Use a specific AI model:**
134
+
135
+ ```bash
136
+ git-copilot-commit commit --model claude-3.5-sonnet
137
+ ```
138
+
139
+ **Set up a default model and use it:**
140
+
141
+ ```bash
142
+ # Set default model once
143
+ git-copilot-commit config --set-default-model gpt-4o
144
+
145
+ # Now all commits will use gpt-4o by default
146
+ git-copilot-commit commit
147
+
148
+ # Override with a different model when needed
149
+ git-copilot-commit commit --model claude-3.5-sonnet
150
+ ```
151
+
118
152
  ## Generated Commit Message Format
119
153
 
120
154
  The tool follows the [Conventional Commits](https://www.conventionalcommits.org/) specification:
@@ -7,6 +7,8 @@ GitHub Copilot.
7
7
 
8
8
  - **AI-Generated Commit Messages**: Uses GitHub Copilot to analyze your staged changes and generate
9
9
  conventional commit messages
10
+ - **Multiple AI Models**: Choose from GPT-4, Claude, Gemini, and other available models
11
+ - **Configurable Defaults**: Set a default model to use across all commits
10
12
  - **Message Editing**: Edit generated messages using your git-configured editor or commit directly
11
13
  - **Conventional Commits**: Follows the [Conventional Commits](https://www.conventionalcommits.org/)
12
14
  specification
@@ -63,6 +65,7 @@ git-copilot-commit commit
63
65
 
64
66
  - `--all, -a`: Stage all files before committing
65
67
  - `--verbose, -v`: Show verbose output with file details
68
+ - `--model, -m`: Specify which AI model to use for generating the commit message
66
69
 
67
70
  1. The tool analyzes your changes
68
71
  2. Prompts you to stage files (if needed)
@@ -88,6 +91,18 @@ List available AI models:
88
91
  git-copilot-commit models
89
92
  ```
90
93
 
94
+ #### `config`
95
+
96
+ Manage application configuration:
97
+
98
+ ```bash
99
+ # Show current configuration
100
+ git-copilot-commit config --show
101
+
102
+ # Set a default model for all commits
103
+ git-copilot-commit config --set-default-model gpt-4o
104
+ ```
105
+
91
106
  ### Examples
92
107
 
93
108
  **Commit all changes with staging prompts:**
@@ -102,6 +117,25 @@ git-copilot-commit commit --all
102
117
  git-copilot-commit commit --verbose
103
118
  ```
104
119
 
120
+ **Use a specific AI model:**
121
+
122
+ ```bash
123
+ git-copilot-commit commit --model claude-3.5-sonnet
124
+ ```
125
+
126
+ **Set up a default model and use it:**
127
+
128
+ ```bash
129
+ # Set default model once
130
+ git-copilot-commit config --set-default-model gpt-4o
131
+
132
+ # Now all commits will use gpt-4o by default
133
+ git-copilot-commit commit
134
+
135
+ # Override with a different model when needed
136
+ git-copilot-commit commit --model claude-3.5-sonnet
137
+ ```
138
+
105
139
  ## Generated Commit Message Format
106
140
 
107
141
  The tool follows the [Conventional Commits](https://www.conventionalcommits.org/) specification:
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "git-copilot-commit"
3
- version = "0.1.1"
3
+ version = "0.1.2"
4
4
  description = "Automatically generate and commit changes using copilot"
5
5
  readme = "README.md"
6
6
  authors = [
@@ -11,6 +11,7 @@ from rich.table import Table
11
11
  from pycopilot.copilot import Copilot
12
12
  from pycopilot.auth import Authentication
13
13
  from .git import GitRepository, GitError, NotAGitRepositoryError, GitStatus
14
+ from .settings import Settings
14
15
 
15
16
  console = Console()
16
17
  app = typer.Typer(help=__doc__, add_completion=False)
@@ -59,7 +60,9 @@ def display_file_status(status: GitStatus) -> None:
59
60
  console.print(table)
60
61
 
61
62
 
62
- def generate_commit_message(repo: GitRepository, status: GitStatus, model: str = None) -> str:
63
+ def generate_commit_message(
64
+ repo: GitRepository, status: GitStatus, model: str | None = None
65
+ ) -> str:
63
66
  """Generate a conventional commit message using Copilot API."""
64
67
 
65
68
  # Get recent commits for context
@@ -179,7 +182,9 @@ def commit(
179
182
  False, "--all", "-a", help="Stage all files before committing"
180
183
  ),
181
184
  verbose: bool = typer.Option(False, "--verbose", "-v", help="Show verbose output"),
182
- model: str = typer.Option(None, "--model", "-m", help="Model to use for generating commit message"),
185
+ model: str | None = typer.Option(
186
+ None, "--model", "-m", help="Model to use for generating commit message"
187
+ ),
183
188
  ):
184
189
  """
185
190
  Automatically commit changes in the current git repository.
@@ -190,6 +195,11 @@ def commit(
190
195
  console.print("[red]Error: Not in a git repository[/red]")
191
196
  raise typer.Exit(1)
192
197
 
198
+ # Load settings and use default model if none provided
199
+ settings = Settings()
200
+ if model is None:
201
+ model = settings.default_model
202
+
193
203
  # Get initial status
194
204
  status = repo.get_status()
195
205
 
@@ -206,19 +216,19 @@ def commit(
206
216
  repo.stage_files() # Stage all files
207
217
  console.print("[green]Staged all files.[/green]")
208
218
  else:
209
- # Check if we need to stage files
219
+ # Show git status once if there are unstaged or untracked files to prompt about
220
+ if status.has_unstaged_changes or status.has_untracked_files:
221
+ git_status_output = repo._run_git_command(["status"])
222
+ console.print(git_status_output.stdout)
223
+
210
224
  if status.has_unstaged_changes:
211
- if Confirm.ask("Stage modified files?"):
225
+ if Confirm.ask("Modified files found. Add all to staging?"):
212
226
  repo.stage_modified()
213
227
  console.print("[green]Staged modified files.[/green]")
214
- else:
215
- raise typer.Exit()
216
228
  if status.has_untracked_files:
217
- if Confirm.ask("Stage untracked files?"):
229
+ if Confirm.ask("Untracked files found. Add all to staging?"):
218
230
  repo.stage_files()
219
231
  console.print("[green]Staged untracked files.[/green]")
220
- else:
221
- raise typer.Exit()
222
232
 
223
233
  # Refresh status after staging
224
234
  status = repo.get_status()
@@ -315,5 +325,30 @@ def models():
315
325
  console.print(table)
316
326
 
317
327
 
328
+ @app.command()
329
+ def config(
330
+ set_default_model: str | None = typer.Option(
331
+ None, "--set-default-model", help="Set default model for commit messages"
332
+ ),
333
+ show: bool = typer.Option(False, "--show", help="Show current configuration"),
334
+ ):
335
+ """Manage application configuration."""
336
+ settings = Settings()
337
+
338
+ if set_default_model:
339
+ settings.default_model = set_default_model
340
+ console.print(f"[green]✓ Default model set to: {set_default_model}[/green]")
341
+
342
+ if show or (not set_default_model):
343
+ console.print("\n[bold]Current Configuration:[/bold]")
344
+ default_model = settings.default_model
345
+ if default_model:
346
+ console.print(f"Default model: [cyan]{default_model}[/cyan]")
347
+ else:
348
+ console.print("Default model: [dim]not set[/dim]")
349
+
350
+ console.print(f"Config file: [dim]{settings.config_file}[/dim]")
351
+
352
+
318
353
  if __name__ == "__main__":
319
354
  app()
@@ -0,0 +1,89 @@
1
+ """
2
+ Settings management using XDG Base Directory specification.
3
+ """
4
+
5
+ import json
6
+ from typing import Any
7
+
8
+ from xdg_base_dirs import (
9
+ xdg_cache_home,
10
+ xdg_config_home,
11
+ xdg_data_home,
12
+ xdg_state_home,
13
+ )
14
+
15
+
16
+ class Settings:
17
+ """Manages application settings using XDG Base Directory specification."""
18
+
19
+ APP_NAME = "git-copilot-commit"
20
+
21
+ def __init__(self):
22
+ self.config_dir = xdg_config_home() / self.APP_NAME
23
+ self.data_dir = xdg_data_home() / self.APP_NAME
24
+ self.cache_dir = xdg_cache_home() / self.APP_NAME
25
+ self.state_dir = xdg_state_home() / self.APP_NAME
26
+
27
+ self.config_file = self.config_dir / "config.json"
28
+
29
+ # Ensure directories exist
30
+ self.config_dir.mkdir(parents=True, exist_ok=True)
31
+ self.data_dir.mkdir(parents=True, exist_ok=True)
32
+ self.cache_dir.mkdir(parents=True, exist_ok=True)
33
+ self.state_dir.mkdir(parents=True, exist_ok=True)
34
+
35
+ self._config: dict[str, Any] = self._load_config()
36
+
37
+ def _load_config(self) -> dict[str, Any]:
38
+ """Load configuration from file."""
39
+ if not self.config_file.exists():
40
+ return {}
41
+
42
+ try:
43
+ with open(self.config_file, "r") as f:
44
+ return json.load(f)
45
+ except (json.JSONDecodeError, IOError):
46
+ return {}
47
+
48
+ def _save_config(self) -> None:
49
+ """Save configuration to file."""
50
+ try:
51
+ with open(self.config_file, "w") as f:
52
+ json.dump(self._config, f, indent=2)
53
+ except IOError:
54
+ pass # Silently fail if we can't write
55
+
56
+ def get(self, key: str, default: Any = None) -> Any:
57
+ """Get a configuration value."""
58
+ return self._config.get(key, default)
59
+
60
+ def set(self, key: str, value: Any) -> None:
61
+ """Set a configuration value."""
62
+ self._config[key] = value
63
+ self._save_config()
64
+
65
+ def delete(self, key: str) -> None:
66
+ """Delete a configuration value."""
67
+ if key in self._config:
68
+ del self._config[key]
69
+ self._save_config()
70
+
71
+ @property
72
+ def default_model(self) -> str | None:
73
+ """Get the default model."""
74
+ return self.get("default_model")
75
+
76
+ @default_model.setter
77
+ def default_model(self, model: str) -> None:
78
+ """Set the default model."""
79
+ self.set("default_model", model)
80
+
81
+ def clear_cache(self) -> None:
82
+ """Clear the cache directory."""
83
+ for file in self.cache_dir.glob("*"):
84
+ if file.is_file():
85
+ file.unlink()
86
+ elif file.is_dir():
87
+ import shutil
88
+
89
+ shutil.rmtree(file)
@@ -78,7 +78,7 @@ wheels = [
78
78
 
79
79
  [[package]]
80
80
  name = "git-copilot-commit"
81
- version = "0.1.0"
81
+ version = "0.1.2"
82
82
  source = { editable = "." }
83
83
  dependencies = [
84
84
  { name = "pycopilot" },