rhiza 0.5.2__tar.gz → 0.5.3__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 (64) hide show
  1. {rhiza-0.5.2 → rhiza-0.5.3}/PKG-INFO +1 -1
  2. {rhiza-0.5.2 → rhiza-0.5.3}/pyproject.toml +1 -1
  3. {rhiza-0.5.2 → rhiza-0.5.3}/src/rhiza/__init__.py +8 -0
  4. {rhiza-0.5.2 → rhiza-0.5.3}/src/rhiza/cli.py +36 -0
  5. {rhiza-0.5.2 → rhiza-0.5.3}/src/rhiza/commands/init.py +1 -1
  6. {rhiza-0.5.2 → rhiza-0.5.3}/src/rhiza/commands/materialize.py +23 -22
  7. {rhiza-0.5.2 → rhiza-0.5.3}/src/rhiza/commands/validate.py +1 -0
  8. {rhiza-0.5.2 → rhiza-0.5.3}/tests/test_cli_commands.py +23 -0
  9. {rhiza-0.5.2 → rhiza-0.5.3}/uv.lock +1 -1
  10. {rhiza-0.5.2 → rhiza-0.5.3}/.editorconfig +0 -0
  11. {rhiza-0.5.2 → rhiza-0.5.3}/.github/README.md +0 -0
  12. {rhiza-0.5.2 → rhiza-0.5.3}/.github/TOKEN_SETUP.md +0 -0
  13. {rhiza-0.5.2 → rhiza-0.5.3}/.github/actions/setup-project/action.yml +0 -0
  14. {rhiza-0.5.2 → rhiza-0.5.3}/.github/copilot-instructions.md +0 -0
  15. {rhiza-0.5.2 → rhiza-0.5.3}/.github/renovate.json +0 -0
  16. {rhiza-0.5.2 → rhiza-0.5.3}/.github/scripts/book.sh +0 -0
  17. {rhiza-0.5.2 → rhiza-0.5.3}/.github/scripts/bump.sh +0 -0
  18. {rhiza-0.5.2 → rhiza-0.5.3}/.github/scripts/customisations/build-extras.sh +0 -0
  19. {rhiza-0.5.2 → rhiza-0.5.3}/.github/scripts/customisations/post-release.sh +0 -0
  20. {rhiza-0.5.2 → rhiza-0.5.3}/.github/scripts/marimushka.sh +0 -0
  21. {rhiza-0.5.2 → rhiza-0.5.3}/.github/scripts/release.sh +0 -0
  22. {rhiza-0.5.2 → rhiza-0.5.3}/.github/scripts/update-readme-help.sh +0 -0
  23. {rhiza-0.5.2 → rhiza-0.5.3}/.github/template.yml +0 -0
  24. {rhiza-0.5.2 → rhiza-0.5.3}/.github/workflows/book.yml +0 -0
  25. {rhiza-0.5.2 → rhiza-0.5.3}/.github/workflows/ci.yml +0 -0
  26. {rhiza-0.5.2 → rhiza-0.5.3}/.github/workflows/deptry.yml +0 -0
  27. {rhiza-0.5.2 → rhiza-0.5.3}/.github/workflows/marimo.yml +0 -0
  28. {rhiza-0.5.2 → rhiza-0.5.3}/.github/workflows/pre-commit.yml +0 -0
  29. {rhiza-0.5.2 → rhiza-0.5.3}/.github/workflows/release.yml +0 -0
  30. {rhiza-0.5.2 → rhiza-0.5.3}/.github/workflows/scripts/version_matrix.py +0 -0
  31. {rhiza-0.5.2 → rhiza-0.5.3}/.github/workflows/scripts/version_max.py +0 -0
  32. {rhiza-0.5.2 → rhiza-0.5.3}/.github/workflows/structure.yml +0 -0
  33. {rhiza-0.5.2 → rhiza-0.5.3}/.github/workflows/sync.yml +0 -0
  34. {rhiza-0.5.2 → rhiza-0.5.3}/.gitignore +0 -0
  35. {rhiza-0.5.2 → rhiza-0.5.3}/.pre-commit-config.yaml +0 -0
  36. {rhiza-0.5.2 → rhiza-0.5.3}/.rhiza.history +0 -0
  37. {rhiza-0.5.2 → rhiza-0.5.3}/CLI.md +0 -0
  38. {rhiza-0.5.2 → rhiza-0.5.3}/CODE_OF_CONDUCT.md +0 -0
  39. {rhiza-0.5.2 → rhiza-0.5.3}/CONTRIBUTING.md +0 -0
  40. {rhiza-0.5.2 → rhiza-0.5.3}/LICENSE +0 -0
  41. {rhiza-0.5.2 → rhiza-0.5.3}/Makefile +0 -0
  42. {rhiza-0.5.2 → rhiza-0.5.3}/README.md +0 -0
  43. {rhiza-0.5.2 → rhiza-0.5.3}/USAGE.md +0 -0
  44. {rhiza-0.5.2 → rhiza-0.5.3}/book/marimo/.gitkeep +0 -0
  45. {rhiza-0.5.2 → rhiza-0.5.3}/pytest.ini +0 -0
  46. {rhiza-0.5.2 → rhiza-0.5.3}/ruff.toml +0 -0
  47. {rhiza-0.5.2 → rhiza-0.5.3}/src/rhiza/__main__.py +0 -0
  48. {rhiza-0.5.2 → rhiza-0.5.3}/src/rhiza/commands/__init__.py +0 -0
  49. {rhiza-0.5.2 → rhiza-0.5.3}/src/rhiza/models.py +0 -0
  50. {rhiza-0.5.2 → rhiza-0.5.3}/tests/test_commands/test_init.py +0 -0
  51. {rhiza-0.5.2 → rhiza-0.5.3}/tests/test_commands/test_materialize.py +0 -0
  52. {rhiza-0.5.2 → rhiza-0.5.3}/tests/test_commands/test_validate.py +0 -0
  53. {rhiza-0.5.2 → rhiza-0.5.3}/tests/test_models.py +0 -0
  54. {rhiza-0.5.2 → rhiza-0.5.3}/tests/test_rhiza/README.md +0 -0
  55. {rhiza-0.5.2 → rhiza-0.5.3}/tests/test_rhiza/conftest.py +0 -0
  56. {rhiza-0.5.2 → rhiza-0.5.3}/tests/test_rhiza/test_bump_script.py +0 -0
  57. {rhiza-0.5.2 → rhiza-0.5.3}/tests/test_rhiza/test_docstrings.py +0 -0
  58. {rhiza-0.5.2 → rhiza-0.5.3}/tests/test_rhiza/test_git_repo_fixture.py +0 -0
  59. {rhiza-0.5.2 → rhiza-0.5.3}/tests/test_rhiza/test_makefile.py +0 -0
  60. {rhiza-0.5.2 → rhiza-0.5.3}/tests/test_rhiza/test_marimushka_script.py +0 -0
  61. {rhiza-0.5.2 → rhiza-0.5.3}/tests/test_rhiza/test_readme.py +0 -0
  62. {rhiza-0.5.2 → rhiza-0.5.3}/tests/test_rhiza/test_release_script.py +0 -0
  63. {rhiza-0.5.2 → rhiza-0.5.3}/tests/test_rhiza/test_structure.py +0 -0
  64. {rhiza-0.5.2 → rhiza-0.5.3}/tests/test_rhiza/test_updatereadme_script.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: rhiza
3
- Version: 0.5.2
3
+ Version: 0.5.3
4
4
  Summary: Reusable configuration templates for modern Python projects
5
5
  Project-URL: Homepage, https://github.com/jebel-quant/rhiza-cli
6
6
  Project-URL: Repository, https://github.com/jebel-quant/rhiza-cli
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "rhiza"
7
- version = "0.5.2"
7
+ version = "0.5.3"
8
8
  description = "Reusable configuration templates for modern Python projects"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11"
@@ -4,4 +4,12 @@ This package groups small, user-facing utilities that can be invoked from
4
4
  the command line or other automation scripts.
5
5
  """
6
6
 
7
+ from importlib.metadata import PackageNotFoundError, version
8
+
9
+ try:
10
+ __version__ = version("rhiza")
11
+ except PackageNotFoundError:
12
+ # Package is not installed, use a fallback version
13
+ __version__ = "0.0.0+dev"
14
+
7
15
  __all__ = ["commands", "models"]
@@ -8,6 +8,7 @@ from pathlib import Path
8
8
 
9
9
  import typer
10
10
 
11
+ from rhiza import __version__
11
12
  from rhiza.commands import init as init_cmd
12
13
  from rhiza.commands import materialize as materialize_cmd
13
14
  from rhiza.commands import validate as validate_cmd
@@ -18,6 +19,41 @@ app = typer.Typer(
18
19
  )
19
20
 
20
21
 
22
+ def version_callback(value: bool):
23
+ """Print version information and exit.
24
+
25
+ Args:
26
+ value: Whether the --version flag was provided.
27
+
28
+ Raises:
29
+ typer.Exit: Always exits after printing version.
30
+ """
31
+ if value:
32
+ typer.echo(f"rhiza version {__version__}")
33
+ raise typer.Exit()
34
+
35
+
36
+ @app.callback()
37
+ def main(
38
+ version: bool = typer.Option(
39
+ False,
40
+ "--version",
41
+ "-v",
42
+ help="Show version and exit",
43
+ callback=version_callback,
44
+ is_eager=True,
45
+ ),
46
+ ):
47
+ """Rhiza CLI main callback.
48
+
49
+ This callback is executed before any command. It handles global options
50
+ like --version.
51
+
52
+ Args:
53
+ version: Version flag (handled by callback).
54
+ """
55
+
56
+
21
57
  @app.command()
22
58
  def init(
23
59
  target: Path = typer.Argument(
@@ -61,4 +61,4 @@ Next steps:
61
61
  """)
62
62
 
63
63
  # the template file exists, so validate it
64
- validate(target)
64
+ return validate(target)
@@ -1,5 +1,14 @@
1
+ """Command for materializing Rhiza template files into a repository.
2
+
3
+ This module implements the `materialize` command. It performs a sparse
4
+ checkout of the configured template repository, copies the selected files
5
+ into the target Git repository, and records managed files in
6
+ `.rhiza.history`. Use this to take a one-shot snapshot of template files.
7
+ """
8
+
1
9
  import shutil
2
10
  import subprocess
11
+ import sys
3
12
  import tempfile
4
13
  from pathlib import Path
5
14
 
@@ -43,7 +52,11 @@ def materialize(target: Path, branch: str, force: bool) -> None:
43
52
  # -----------------------
44
53
  # Ensure Rhiza is initialized
45
54
  # -----------------------
46
- init(target)
55
+ valid = init(target)
56
+
57
+ if not valid:
58
+ logger.error(f"Rhiza template is invalid. {target}")
59
+ sys.exit(1)
47
60
 
48
61
  template_file = target / ".github" / "template.yml"
49
62
  template = RhizaTemplate.from_yaml(template_file)
@@ -73,10 +86,12 @@ def materialize(target: Path, branch: str, force: bool) -> None:
73
86
  [
74
87
  "git",
75
88
  "clone",
76
- "--depth", "1",
89
+ "--depth",
90
+ "1",
77
91
  "--filter=blob:none",
78
92
  "--sparse",
79
- "--branch", rhiza_branch,
93
+ "--branch",
94
+ rhiza_branch,
80
95
  f"https://github.com/{rhiza_repo}.git",
81
96
  str(tmp_dir),
82
97
  ],
@@ -101,15 +116,9 @@ def materialize(target: Path, branch: str, force: bool) -> None:
101
116
  # -----------------------
102
117
  all_files = expand_paths(tmp_dir, include_paths)
103
118
 
104
- excluded_files = {
105
- f.resolve()
106
- for f in expand_paths(tmp_dir, excluded_paths)
107
- }
119
+ excluded_files = {f.resolve() for f in expand_paths(tmp_dir, excluded_paths)}
108
120
 
109
- files_to_copy = [
110
- f for f in all_files
111
- if f.resolve() not in excluded_files
112
- ]
121
+ files_to_copy = [f for f in all_files if f.resolve() not in excluded_files]
113
122
 
114
123
  # -----------------------
115
124
  # Copy files into target repo
@@ -121,9 +130,7 @@ def materialize(target: Path, branch: str, force: bool) -> None:
121
130
  materialized_files.append(relative_path)
122
131
 
123
132
  if dst_file.exists() and not force:
124
- logger.warning(
125
- f"{relative_path} already exists — use --force to overwrite"
126
- )
133
+ logger.warning(f"{relative_path} already exists — use --force to overwrite")
127
134
  continue
128
135
 
129
136
  dst_file.parent.mkdir(parents=True, exist_ok=True)
@@ -136,10 +143,7 @@ def materialize(target: Path, branch: str, force: bool) -> None:
136
143
  # -----------------------
137
144
  # Warn about workflow files
138
145
  # -----------------------
139
- workflow_files = [
140
- p for p in materialized_files
141
- if p.parts[:2] == (".github", "workflows")
142
- ]
146
+ workflow_files = [p for p in materialized_files if p.parts[:2] == (".github", "workflows")]
143
147
 
144
148
  if workflow_files:
145
149
  logger.warning(
@@ -161,10 +165,7 @@ def materialize(target: Path, branch: str, force: bool) -> None:
161
165
  for file_path in sorted(materialized_files):
162
166
  f.write(f"{file_path}\n")
163
167
 
164
- logger.info(
165
- f"Created {history_file.relative_to(target)} "
166
- f"with {len(materialized_files)} files"
167
- )
168
+ logger.info(f"Created {history_file.relative_to(target)} with {len(materialized_files)} files")
168
169
 
169
170
  logger.success("Rhiza templates materialized successfully")
170
171
 
@@ -133,4 +133,5 @@ def validate(target: Path) -> bool:
133
133
  return True
134
134
  else:
135
135
  logger.error("✗ Validation failed: template.yml has errors")
136
+ # raise AssertionError("Invalid template.yml")
136
137
  return False
@@ -9,12 +9,35 @@ This module tests:
9
9
  import subprocess
10
10
  import sys
11
11
 
12
+ from rhiza import __version__
12
13
  from rhiza.commands.materialize import expand_paths
13
14
 
14
15
 
15
16
  class TestCliApp:
16
17
  """Tests for the CLI Typer app."""
17
18
 
19
+ def test_version_flag(self):
20
+ """Test that --version flag shows version information."""
21
+ result = subprocess.run(
22
+ [sys.executable, "-m", "rhiza", "--version"],
23
+ capture_output=True,
24
+ text=True,
25
+ )
26
+ assert result.returncode == 0
27
+ assert "rhiza version" in result.stdout
28
+ assert __version__ in result.stdout
29
+
30
+ def test_version_short_flag(self):
31
+ """Test that -v flag shows version information."""
32
+ result = subprocess.run(
33
+ [sys.executable, "-m", "rhiza", "-v"],
34
+ capture_output=True,
35
+ text=True,
36
+ )
37
+ assert result.returncode == 0
38
+ assert "rhiza version" in result.stdout
39
+ assert __version__ in result.stdout
40
+
18
41
 
19
42
  class TestExpandPaths:
20
43
  """Tests for the expand_paths utility function."""
@@ -771,7 +771,7 @@ wheels = [
771
771
 
772
772
  [[package]]
773
773
  name = "rhiza"
774
- version = "0.5.2"
774
+ version = "0.5.3"
775
775
  source = { editable = "." }
776
776
  dependencies = [
777
777
  { name = "loguru" },
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
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
File without changes
File without changes