devgen-cli 0.2.7__tar.gz → 0.2.8__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 (56) hide show
  1. {devgen_cli-0.2.7/devgen_cli.egg-info → devgen_cli-0.2.8}/PKG-INFO +1 -1
  2. {devgen_cli-0.2.7 → devgen_cli-0.2.8}/devgen/cli/setup.py +3 -3
  3. {devgen_cli-0.2.7 → devgen_cli-0.2.8}/devgen/modules/changelog_generator.py +1 -1
  4. {devgen_cli-0.2.7 → devgen_cli-0.2.8}/devgen/modules/commit_generator.py +2 -1
  5. {devgen_cli-0.2.7 → devgen_cli-0.2.8}/devgen/modules/diff_builder.py +6 -2
  6. {devgen_cli-0.2.7 → devgen_cli-0.2.8}/devgen/modules/git_ops.py +5 -2
  7. {devgen_cli-0.2.7 → devgen_cli-0.2.8}/devgen/providers/anthropic.py +1 -1
  8. {devgen_cli-0.2.7 → devgen_cli-0.2.8}/devgen/providers/base.py +2 -1
  9. {devgen_cli-0.2.7 → devgen_cli-0.2.8}/devgen/providers/gemini.py +1 -1
  10. {devgen_cli-0.2.7 → devgen_cli-0.2.8}/devgen/providers/ollama.py +1 -1
  11. {devgen_cli-0.2.7 → devgen_cli-0.2.8}/devgen/providers/openai.py +1 -1
  12. {devgen_cli-0.2.7 → devgen_cli-0.2.8}/devgen/utils.py +5 -0
  13. {devgen_cli-0.2.7 → devgen_cli-0.2.8/devgen_cli.egg-info}/PKG-INFO +1 -1
  14. {devgen_cli-0.2.7 → devgen_cli-0.2.8}/pyproject.toml +1 -1
  15. {devgen_cli-0.2.7 → devgen_cli-0.2.8}/setup.py +1 -1
  16. {devgen_cli-0.2.7 → devgen_cli-0.2.8}/LICENSE +0 -0
  17. {devgen_cli-0.2.7 → devgen_cli-0.2.8}/MANIFEST.in +0 -0
  18. {devgen_cli-0.2.7 → devgen_cli-0.2.8}/README.md +0 -0
  19. {devgen_cli-0.2.7 → devgen_cli-0.2.8}/devgen/__init__.py +0 -0
  20. {devgen_cli-0.2.7 → devgen_cli-0.2.8}/devgen/ai.py +0 -0
  21. {devgen_cli-0.2.7 → devgen_cli-0.2.8}/devgen/cli/__init__.py +0 -0
  22. {devgen_cli-0.2.7 → devgen_cli-0.2.8}/devgen/cli/changelog.py +0 -0
  23. {devgen_cli-0.2.7 → devgen_cli-0.2.8}/devgen/cli/commit.py +0 -0
  24. {devgen_cli-0.2.7 → devgen_cli-0.2.8}/devgen/cli/config.py +0 -0
  25. {devgen_cli-0.2.7 → devgen_cli-0.2.8}/devgen/cli/gitignore.py +0 -0
  26. {devgen_cli-0.2.7 → devgen_cli-0.2.8}/devgen/cli/license.py +0 -0
  27. {devgen_cli-0.2.7 → devgen_cli-0.2.8}/devgen/cli/main.py +0 -0
  28. {devgen_cli-0.2.7 → devgen_cli-0.2.8}/devgen/cli/release.py +0 -0
  29. {devgen_cli-0.2.7 → devgen_cli-0.2.8}/devgen/modules/__init__.py +0 -0
  30. {devgen_cli-0.2.7 → devgen_cli-0.2.8}/devgen/modules/changelog_sections.py +0 -0
  31. {devgen_cli-0.2.7 → devgen_cli-0.2.8}/devgen/modules/gitignore_generator.py +0 -0
  32. {devgen_cli-0.2.7 → devgen_cli-0.2.8}/devgen/modules/license_generator.py +0 -0
  33. {devgen_cli-0.2.7 → devgen_cli-0.2.8}/devgen/modules/release_note_generator.py +0 -0
  34. {devgen_cli-0.2.7 → devgen_cli-0.2.8}/devgen/providers/__init__.py +0 -0
  35. {devgen_cli-0.2.7 → devgen_cli-0.2.8}/devgen/providers/huggingface.py +0 -0
  36. {devgen_cli-0.2.7 → devgen_cli-0.2.8}/devgen/providers/openrouter.py +0 -0
  37. {devgen_cli-0.2.7 → devgen_cli-0.2.8}/devgen/templates/commit/commit_message.tpl +0 -0
  38. {devgen_cli-0.2.7 → devgen_cli-0.2.8}/devgen/templates/licenses/agpl-3.0.json +0 -0
  39. {devgen_cli-0.2.7 → devgen_cli-0.2.8}/devgen/templates/licenses/apache-2.0.json +0 -0
  40. {devgen_cli-0.2.7 → devgen_cli-0.2.8}/devgen/templates/licenses/bsd-2-clause.json +0 -0
  41. {devgen_cli-0.2.7 → devgen_cli-0.2.8}/devgen/templates/licenses/bsd-3-clause.json +0 -0
  42. {devgen_cli-0.2.7 → devgen_cli-0.2.8}/devgen/templates/licenses/bsl-1.0.json +0 -0
  43. {devgen_cli-0.2.7 → devgen_cli-0.2.8}/devgen/templates/licenses/cc0-1.0.json +0 -0
  44. {devgen_cli-0.2.7 → devgen_cli-0.2.8}/devgen/templates/licenses/epl-2.0.json +0 -0
  45. {devgen_cli-0.2.7 → devgen_cli-0.2.8}/devgen/templates/licenses/gpl-2.0.json +0 -0
  46. {devgen_cli-0.2.7 → devgen_cli-0.2.8}/devgen/templates/licenses/gpl-3.0.json +0 -0
  47. {devgen_cli-0.2.7 → devgen_cli-0.2.8}/devgen/templates/licenses/lgpl-2.1.json +0 -0
  48. {devgen_cli-0.2.7 → devgen_cli-0.2.8}/devgen/templates/licenses/mit.json +0 -0
  49. {devgen_cli-0.2.7 → devgen_cli-0.2.8}/devgen/templates/licenses/mpl-2.0.json +0 -0
  50. {devgen_cli-0.2.7 → devgen_cli-0.2.8}/devgen/templates/licenses/unlicense.json +0 -0
  51. {devgen_cli-0.2.7 → devgen_cli-0.2.8}/devgen_cli.egg-info/SOURCES.txt +0 -0
  52. {devgen_cli-0.2.7 → devgen_cli-0.2.8}/devgen_cli.egg-info/dependency_links.txt +0 -0
  53. {devgen_cli-0.2.7 → devgen_cli-0.2.8}/devgen_cli.egg-info/entry_points.txt +0 -0
  54. {devgen_cli-0.2.7 → devgen_cli-0.2.8}/devgen_cli.egg-info/requires.txt +0 -0
  55. {devgen_cli-0.2.7 → devgen_cli-0.2.8}/devgen_cli.egg-info/top_level.txt +0 -0
  56. {devgen_cli-0.2.7 → devgen_cli-0.2.8}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: devgen-cli
3
- Version: 0.2.7
3
+ Version: 0.2.8
4
4
  Summary: A collection of developer tools
5
5
  Home-page: https://github.com/S4NKALP/devgen
6
6
  Author: Sankalp Tharu
@@ -85,14 +85,14 @@ def setup_config() -> None:
85
85
  raise typer.Exit(code=130)
86
86
  ollama_host = ollama_host_input.strip() or ollama_host
87
87
 
88
- # Save Config
89
- new_config = {
88
+ # Save Config — merge with existing to preserve extra keys
89
+ new_config = {**current_config, **{
90
90
  "provider": provider,
91
91
  "model": model,
92
92
  "api_key": api_key,
93
93
  "emoji": emoji,
94
94
  "ollama_host": ollama_host,
95
- }
95
+ }}
96
96
 
97
97
  try:
98
98
  with config_path.open("w", encoding="utf-8") as f:
@@ -145,7 +145,7 @@ class ChangelogGenerator:
145
145
  old = path.read_text(encoding="utf-8")
146
146
  if old.strip().startswith("# CHANGELOG"):
147
147
  header, _, rest = old.partition("\n")
148
- new_content = f"{header}\n\n{md_content}\n{rest.lstrip()}"
148
+ new_content = f"{header}\n\n{md_content}\n{rest}"
149
149
  else:
150
150
  new_content = f"# CHANGELOG\n\n{md_content}\n\n{old}"
151
151
  else:
@@ -48,6 +48,7 @@ class CacheManager:
48
48
 
49
49
  def __init__(self, path: Path, max_age_minutes: int = 120) -> None:
50
50
  self.path = path
51
+ self.max_age_minutes = max_age_minutes
51
52
 
52
53
  def init_dry_run(self) -> None:
53
54
  self.path.parent.mkdir(parents=True, exist_ok=True)
@@ -59,7 +60,7 @@ class CacheManager:
59
60
  if dry_run:
60
61
  self.init_dry_run()
61
62
  return {}
62
- if not force_rebuild and is_file_recent(self.path):
63
+ if not force_rebuild and is_file_recent(self.path, self.max_age_minutes):
63
64
  return extract_commit_messages(self.path)
64
65
  return {}
65
66
 
@@ -70,7 +70,7 @@ class DiffBuilder:
70
70
  def _partition(self, files: List[str]) -> tuple[list[str], list[str]]:
71
71
  summary, to_diff = [], []
72
72
  for f in files:
73
- if any(p in f for p in IGNORED_DIFF_PATTERNS):
73
+ if Path(f).name in IGNORED_DIFF_PATTERNS:
74
74
  summary.append(f"[METADATA UPDATED] {f}")
75
75
  else:
76
76
  to_diff.append(f)
@@ -128,7 +128,11 @@ class FileGrouper:
128
128
  deepest = max(candidates, key=lambda p: len(Path(p).parts))
129
129
  parent_path = str(Path(deepest).parent)
130
130
  new_key = "root" if parent_path == "." else parent_path
131
- groups.setdefault(new_key, []).extend(groups.pop(deepest))
131
+ files = groups.pop(deepest)
132
+ if new_key in groups:
133
+ groups[new_key].extend(files)
134
+ else:
135
+ groups["root"].extend(files)
132
136
  return groups
133
137
 
134
138
 
@@ -115,8 +115,11 @@ class GitOperator:
115
115
  self._run(["git", "add", *existing])
116
116
  if deleted:
117
117
  self._run(["git", "rm", *deleted])
118
- except GitError as e:
119
- raise GitError(f"Could not stage files: {e}") from e
118
+ except GitError:
119
+ # Fallback: file state may have changed between check and command.
120
+ # Try a single git add --all for the whole set; git will handle
121
+ # both additions and removals correctly.
122
+ self._run(["git", "add", "--all", "--", *files])
120
123
 
121
124
  def commit(self, message: str) -> None:
122
125
  """``git commit -m`` with the given message."""
@@ -16,4 +16,4 @@ class AnthropicProvider(BaseProvider):
16
16
  max_tokens=1024,
17
17
  messages=[{"role": "user", "content": prompt}],
18
18
  )
19
- return message.content[0].text
19
+ return message.content[0].text or ""
@@ -53,7 +53,8 @@ class BaseProvider(ABC):
53
53
  )
54
54
  chosen_model = model or self.DEFAULT_MODEL
55
55
  try:
56
- return self._generate(prompt, api_key, chosen_model, **kwargs).strip()
56
+ text = self._generate(prompt, api_key, chosen_model, **kwargs)
57
+ return (text or "").strip()
57
58
  except Exception as e:
58
59
  self._handle_error(e)
59
60
 
@@ -30,7 +30,7 @@ class GeminiProvider(BaseProvider):
30
30
  max_output_tokens=kwargs.get("max_output_tokens", 2048),
31
31
  ),
32
32
  )
33
- return response.text
33
+ return response.text or ""
34
34
  except Exception as e:
35
35
  if is_token_limit_error(e):
36
36
  raise # base class handles with friendly message
@@ -36,7 +36,7 @@ class OllamaProvider(BaseProvider):
36
36
  f"Ollama returned no choices for model {model!r}. "
37
37
  "The model may not be installed locally."
38
38
  )
39
- return response.choices[0].message.content
39
+ return response.choices[0].message.content or ""
40
40
 
41
41
  def _handle_error(self, error):
42
42
  """Override default wrapping — Ollama has no API key to check."""
@@ -17,4 +17,4 @@ class OpenaiProvider(BaseProvider):
17
17
  messages=[{"role": "user", "content": prompt}],
18
18
  **kwargs,
19
19
  )
20
- return response.choices[0].message.content
20
+ return response.choices[0].message.content or ""
@@ -209,6 +209,11 @@ def delete_file(filepath: Path | str) -> bool:
209
209
 
210
210
  def load_template_env(sub_dir: str) -> Environment:
211
211
  template_dir = Path(__file__).parent / "templates" / sub_dir
212
+ if not template_dir.is_dir():
213
+ raise RuntimeError(
214
+ f"Template directory not found: {template_dir}. "
215
+ "The installation may be corrupted."
216
+ )
212
217
  return Environment(loader=FileSystemLoader(template_dir))
213
218
 
214
219
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: devgen-cli
3
- Version: 0.2.7
3
+ Version: 0.2.8
4
4
  Summary: A collection of developer tools
5
5
  Home-page: https://github.com/S4NKALP/devgen
6
6
  Author: Sankalp Tharu
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "devgen-cli"
7
- version = "0.2.7"
7
+ version = "0.2.8"
8
8
  description = "A collection of developer tools"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
@@ -6,7 +6,7 @@ from setuptools import find_packages, setup
6
6
 
7
7
  setup(
8
8
  name="devgen-cli",
9
- version="0.2.7",
9
+ version="0.2.8",
10
10
  packages=find_packages(),
11
11
  include_package_data=True,
12
12
  install_requires=[
File without changes
File without changes
File without changes
File without changes
File without changes