rhiza 0.10.1__tar.gz → 0.10.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.
- {rhiza-0.10.1 → rhiza-0.10.2}/.github/workflows/rhiza_validate.yml +4 -4
- {rhiza-0.10.1 → rhiza-0.10.2}/.pre-commit-config.yaml +3 -1
- {rhiza-0.10.1 → rhiza-0.10.2}/PKG-INFO +1 -1
- {rhiza-0.10.1 → rhiza-0.10.2}/pyproject.toml +1 -1
- {rhiza-0.10.1 → rhiza-0.10.2}/src/rhiza/bundle_resolver.py +7 -7
- {rhiza-0.10.1 → rhiza-0.10.2}/src/rhiza/commands/materialize.py +3 -3
- {rhiza-0.10.1 → rhiza-0.10.2}/src/rhiza/models.py +4 -4
- {rhiza-0.10.1 → rhiza-0.10.2}/tests/test_bundle_resolver.py +12 -12
- {rhiza-0.10.1 → rhiza-0.10.2}/tests/test_commands/test_materialize_bundles.py +3 -3
- {rhiza-0.10.1 → rhiza-0.10.2}/uv.lock +1 -1
- {rhiza-0.10.1 → rhiza-0.10.2}/.editorconfig +0 -0
- {rhiza-0.10.1 → rhiza-0.10.2}/.github/ISSUE_TEMPLATE/assign_ui_implementation.md +0 -0
- {rhiza-0.10.1 → rhiza-0.10.2}/.github/actions/configure-git-auth/README.md +0 -0
- {rhiza-0.10.1 → rhiza-0.10.2}/.github/actions/configure-git-auth/action.yml +0 -0
- {rhiza-0.10.1 → rhiza-0.10.2}/.github/agents/analyser.md +0 -0
- {rhiza-0.10.1 → rhiza-0.10.2}/.github/agents/summarise.md +0 -0
- {rhiza-0.10.1 → rhiza-0.10.2}/.github/copilot-instructions.md +0 -0
- {rhiza-0.10.1 → rhiza-0.10.2}/.github/workflows/rhiza_ci.yml +0 -0
- {rhiza-0.10.1 → rhiza-0.10.2}/.github/workflows/rhiza_codeql.yml +0 -0
- {rhiza-0.10.1 → rhiza-0.10.2}/.github/workflows/rhiza_deptry.yml +0 -0
- {rhiza-0.10.1 → rhiza-0.10.2}/.github/workflows/rhiza_mypy.yml +0 -0
- {rhiza-0.10.1 → rhiza-0.10.2}/.github/workflows/rhiza_pre-commit.yml +0 -0
- {rhiza-0.10.1 → rhiza-0.10.2}/.github/workflows/rhiza_release.yml +0 -0
- {rhiza-0.10.1 → rhiza-0.10.2}/.github/workflows/rhiza_security.yml +0 -0
- {rhiza-0.10.1 → rhiza-0.10.2}/.github/workflows/rhiza_sync.yml +0 -0
- {rhiza-0.10.1 → rhiza-0.10.2}/.gitignore +0 -0
- {rhiza-0.10.1 → rhiza-0.10.2}/.python-version +0 -0
- {rhiza-0.10.1 → rhiza-0.10.2}/.rhiza/.cfg.toml +0 -0
- {rhiza-0.10.1 → rhiza-0.10.2}/.rhiza/.gitignore +0 -0
- {rhiza-0.10.1 → rhiza-0.10.2}/.rhiza/.rhiza-version +0 -0
- {rhiza-0.10.1 → rhiza-0.10.2}/.rhiza/assets/rhiza-logo.svg +0 -0
- {rhiza-0.10.1 → rhiza-0.10.2}/.rhiza/docs/CONFIG.md +0 -0
- {rhiza-0.10.1 → rhiza-0.10.2}/.rhiza/docs/PRIVATE_PACKAGES.md +0 -0
- {rhiza-0.10.1 → rhiza-0.10.2}/.rhiza/docs/TOKEN_SETUP.md +0 -0
- {rhiza-0.10.1 → rhiza-0.10.2}/.rhiza/history +0 -0
- {rhiza-0.10.1 → rhiza-0.10.2}/.rhiza/make.d/00-custom-env.mk +0 -0
- {rhiza-0.10.1 → rhiza-0.10.2}/.rhiza/make.d/01-test.mk +0 -0
- {rhiza-0.10.1 → rhiza-0.10.2}/.rhiza/make.d/05-github.mk +0 -0
- {rhiza-0.10.1 → rhiza-0.10.2}/.rhiza/make.d/06-agentic.mk +0 -0
- {rhiza-0.10.1 → rhiza-0.10.2}/.rhiza/make.d/08-docs.mk +0 -0
- {rhiza-0.10.1 → rhiza-0.10.2}/.rhiza/make.d/10-custom-task.mk +0 -0
- {rhiza-0.10.1 → rhiza-0.10.2}/.rhiza/make.d/README.md +0 -0
- {rhiza-0.10.1 → rhiza-0.10.2}/.rhiza/requirements/README.md +0 -0
- {rhiza-0.10.1 → rhiza-0.10.2}/.rhiza/requirements/docs.txt +0 -0
- {rhiza-0.10.1 → rhiza-0.10.2}/.rhiza/requirements/marimo.txt +0 -0
- {rhiza-0.10.1 → rhiza-0.10.2}/.rhiza/requirements/tests.txt +0 -0
- {rhiza-0.10.1 → rhiza-0.10.2}/.rhiza/requirements/tools.txt +0 -0
- {rhiza-0.10.1 → rhiza-0.10.2}/.rhiza/rhiza.mk +0 -0
- {rhiza-0.10.1 → rhiza-0.10.2}/.rhiza/scripts/release.sh +0 -0
- {rhiza-0.10.1 → rhiza-0.10.2}/.rhiza/template.yml +0 -0
- {rhiza-0.10.1 → rhiza-0.10.2}/.rhiza/templates/minibook/custom.html.jinja2 +0 -0
- {rhiza-0.10.1 → rhiza-0.10.2}/.rhiza/utils/version_matrix.py +0 -0
- {rhiza-0.10.1 → rhiza-0.10.2}/CLI.md +0 -0
- {rhiza-0.10.1 → rhiza-0.10.2}/CODE_OF_CONDUCT.md +0 -0
- {rhiza-0.10.1 → rhiza-0.10.2}/CONTRIBUTING.md +0 -0
- {rhiza-0.10.1 → rhiza-0.10.2}/GETTING_STARTED.md +0 -0
- {rhiza-0.10.1 → rhiza-0.10.2}/LICENSE +0 -0
- {rhiza-0.10.1 → rhiza-0.10.2}/Makefile +0 -0
- {rhiza-0.10.1 → rhiza-0.10.2}/README.md +0 -0
- {rhiza-0.10.1 → rhiza-0.10.2}/USAGE.md +0 -0
- {rhiza-0.10.1 → rhiza-0.10.2}/pr-description.md +0 -0
- {rhiza-0.10.1 → rhiza-0.10.2}/pytest.ini +0 -0
- {rhiza-0.10.1 → rhiza-0.10.2}/renovate.json +0 -0
- {rhiza-0.10.1 → rhiza-0.10.2}/ruff.toml +0 -0
- {rhiza-0.10.1 → rhiza-0.10.2}/src/rhiza/__init__.py +0 -0
- {rhiza-0.10.1 → rhiza-0.10.2}/src/rhiza/__main__.py +0 -0
- {rhiza-0.10.1 → rhiza-0.10.2}/src/rhiza/_templates/basic/__init__.py.jinja2 +0 -0
- {rhiza-0.10.1 → rhiza-0.10.2}/src/rhiza/_templates/basic/main.py.jinja2 +0 -0
- {rhiza-0.10.1 → rhiza-0.10.2}/src/rhiza/_templates/basic/pyproject.toml.jinja2 +0 -0
- {rhiza-0.10.1 → rhiza-0.10.2}/src/rhiza/cli.py +0 -0
- {rhiza-0.10.1 → rhiza-0.10.2}/src/rhiza/commands/__init__.py +0 -0
- {rhiza-0.10.1 → rhiza-0.10.2}/src/rhiza/commands/init.py +0 -0
- {rhiza-0.10.1 → rhiza-0.10.2}/src/rhiza/commands/migrate.py +0 -0
- {rhiza-0.10.1 → rhiza-0.10.2}/src/rhiza/commands/summarise.py +0 -0
- {rhiza-0.10.1 → rhiza-0.10.2}/src/rhiza/commands/uninstall.py +0 -0
- {rhiza-0.10.1 → rhiza-0.10.2}/src/rhiza/commands/validate.py +0 -0
- {rhiza-0.10.1 → rhiza-0.10.2}/src/rhiza/commands/welcome.py +0 -0
- {rhiza-0.10.1 → rhiza-0.10.2}/src/rhiza/subprocess_utils.py +0 -0
- {rhiza-0.10.1 → rhiza-0.10.2}/tests/test_cli_commands.py +0 -0
- {rhiza-0.10.1 → rhiza-0.10.2}/tests/test_commands/test_init.py +0 -0
- {rhiza-0.10.1 → rhiza-0.10.2}/tests/test_commands/test_materialize.py +0 -0
- {rhiza-0.10.1 → rhiza-0.10.2}/tests/test_commands/test_migrate.py +0 -0
- {rhiza-0.10.1 → rhiza-0.10.2}/tests/test_commands/test_summarise.py +0 -0
- {rhiza-0.10.1 → rhiza-0.10.2}/tests/test_commands/test_uninstall.py +0 -0
- {rhiza-0.10.1 → rhiza-0.10.2}/tests/test_commands/test_validate.py +0 -0
- {rhiza-0.10.1 → rhiza-0.10.2}/tests/test_models.py +0 -0
- {rhiza-0.10.1 → rhiza-0.10.2}/tests/test_package.py +0 -0
|
@@ -54,7 +54,7 @@ repos:
|
|
|
54
54
|
- id: uv-lock
|
|
55
55
|
|
|
56
56
|
- repo: https://github.com/Jebel-Quant/rhiza-hooks
|
|
57
|
-
rev: v0.1.
|
|
57
|
+
rev: v0.1.5 # Use the latest release
|
|
58
58
|
hooks:
|
|
59
59
|
# Migrated from rhiza
|
|
60
60
|
- id: check-rhiza-workflow-names
|
|
@@ -63,3 +63,5 @@ repos:
|
|
|
63
63
|
- id: check-rhiza-config
|
|
64
64
|
- id: check-makefile-targets
|
|
65
65
|
- id: check-python-version-consistency
|
|
66
|
+
- id: check-template-bundles
|
|
67
|
+
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: rhiza
|
|
3
|
-
Version: 0.10.
|
|
3
|
+
Version: 0.10.2
|
|
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
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"""Bundle resolution logic for template configuration.
|
|
2
2
|
|
|
3
3
|
This module provides functions to load and resolve bundle configurations
|
|
4
|
-
from the template repository's
|
|
4
|
+
from the template repository's template-bundles.yml file.
|
|
5
5
|
"""
|
|
6
6
|
|
|
7
7
|
from pathlib import Path
|
|
@@ -10,19 +10,19 @@ from rhiza.models import RhizaBundles, RhizaTemplate
|
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
def load_bundles_from_clone(tmp_dir: Path) -> RhizaBundles | None:
|
|
13
|
-
"""Load .rhiza/
|
|
13
|
+
"""Load .rhiza/template-bundles.yml from cloned template repo.
|
|
14
14
|
|
|
15
15
|
Args:
|
|
16
16
|
tmp_dir: Path to the cloned template repository.
|
|
17
17
|
|
|
18
18
|
Returns:
|
|
19
|
-
RhizaBundles if
|
|
19
|
+
RhizaBundles if template-bundles.yml exists, None otherwise.
|
|
20
20
|
|
|
21
21
|
Raises:
|
|
22
|
-
yaml.YAMLError: If
|
|
23
|
-
ValueError: If
|
|
22
|
+
yaml.YAMLError: If template-bundles.yml is malformed.
|
|
23
|
+
ValueError: If template-bundles.yml is invalid.
|
|
24
24
|
"""
|
|
25
|
-
bundles_file = tmp_dir / ".rhiza" / "
|
|
25
|
+
bundles_file = tmp_dir / ".rhiza" / "template-bundles.yml"
|
|
26
26
|
if not bundles_file.exists():
|
|
27
27
|
return None
|
|
28
28
|
return RhizaBundles.from_yaml(bundles_file)
|
|
@@ -54,7 +54,7 @@ def resolve_include_paths(
|
|
|
54
54
|
# Resolve templates to paths if specified
|
|
55
55
|
if template.templates:
|
|
56
56
|
if not bundles_config:
|
|
57
|
-
msg = "Template uses templates but
|
|
57
|
+
msg = "Template uses templates but template-bundles.yml not found in template repository"
|
|
58
58
|
raise ValueError(msg)
|
|
59
59
|
paths.extend(bundles_config.resolve_to_paths(template.templates))
|
|
60
60
|
|
|
@@ -121,7 +121,7 @@ def _validate_and_load_template(target: Path, branch: str) -> tuple[RhizaTemplat
|
|
|
121
121
|
excluded_paths = template.exclude
|
|
122
122
|
|
|
123
123
|
# Note: We'll resolve templates to paths after cloning the template repo,
|
|
124
|
-
# since we need access to
|
|
124
|
+
# since we need access to template-bundles.yml from the template
|
|
125
125
|
include_paths = template.include
|
|
126
126
|
|
|
127
127
|
# Validate that we have either templates or include paths
|
|
@@ -545,11 +545,11 @@ def materialize(target: Path, branch: str, target_branch: str | None, force: boo
|
|
|
545
545
|
logger.debug(f"Temporary directory: {tmp_dir}")
|
|
546
546
|
|
|
547
547
|
try:
|
|
548
|
-
# Clone with initial minimal checkout to load
|
|
548
|
+
# Clone with initial minimal checkout to load template-bundles.yml if needed
|
|
549
549
|
initial_paths = [".rhiza"] if template.templates else include_paths
|
|
550
550
|
_clone_template_repository(tmp_dir, git_url, rhiza_branch, initial_paths, git_executable, git_env)
|
|
551
551
|
|
|
552
|
-
# Load
|
|
552
|
+
# Load template-bundles.yml and resolve templates to paths if using template mode
|
|
553
553
|
if template.templates:
|
|
554
554
|
logger.info("Resolving templates to file paths...")
|
|
555
555
|
try:
|
|
@@ -64,7 +64,7 @@ def _normalize_to_list(value: str | list[str] | None) -> list[str]:
|
|
|
64
64
|
|
|
65
65
|
@dataclass
|
|
66
66
|
class BundleDefinition:
|
|
67
|
-
"""Represents a single bundle from
|
|
67
|
+
"""Represents a single bundle from template-bundles.yml.
|
|
68
68
|
|
|
69
69
|
Attributes:
|
|
70
70
|
name: The bundle identifier (e.g., "core", "tests", "github").
|
|
@@ -87,7 +87,7 @@ class BundleDefinition:
|
|
|
87
87
|
|
|
88
88
|
@dataclass
|
|
89
89
|
class RhizaBundles:
|
|
90
|
-
"""Represents the structure of
|
|
90
|
+
"""Represents the structure of template-bundles.yml.
|
|
91
91
|
|
|
92
92
|
Attributes:
|
|
93
93
|
version: Version string of the bundles configuration format.
|
|
@@ -102,7 +102,7 @@ class RhizaBundles:
|
|
|
102
102
|
"""Load RhizaBundles from a YAML file.
|
|
103
103
|
|
|
104
104
|
Args:
|
|
105
|
-
file_path: Path to the
|
|
105
|
+
file_path: Path to the template-bundles.yml file.
|
|
106
106
|
|
|
107
107
|
Returns:
|
|
108
108
|
The loaded bundles configuration.
|
|
@@ -163,7 +163,7 @@ class RhizaBundles:
|
|
|
163
163
|
# Validate all bundles exist
|
|
164
164
|
for name in bundle_names:
|
|
165
165
|
if name not in self.bundles:
|
|
166
|
-
raise ValueError(f"Bundle '{name}' not found in
|
|
166
|
+
raise ValueError(f"Bundle '{name}' not found in template-bundles.yml") # noqa: TRY003
|
|
167
167
|
|
|
168
168
|
resolved: list[str] = []
|
|
169
169
|
visiting: set[str] = set()
|
|
@@ -170,8 +170,8 @@ class TestRhizaBundles:
|
|
|
170
170
|
assert result.index("tests1.txt") < result.index("docs1.txt")
|
|
171
171
|
|
|
172
172
|
def test_from_yaml_valid(self, tmp_path):
|
|
173
|
-
"""Test loading valid
|
|
174
|
-
bundles_file = tmp_path / "
|
|
173
|
+
"""Test loading valid template-bundles.yml."""
|
|
174
|
+
bundles_file = tmp_path / "template-bundles.yml"
|
|
175
175
|
bundles_file.write_text("""
|
|
176
176
|
version: "1.0"
|
|
177
177
|
bundles:
|
|
@@ -200,24 +200,24 @@ bundles:
|
|
|
200
200
|
assert result.bundles["tests"].depends_on == ["core"]
|
|
201
201
|
|
|
202
202
|
def test_from_yaml_empty(self, tmp_path):
|
|
203
|
-
"""Test loading empty
|
|
204
|
-
bundles_file = tmp_path / "
|
|
203
|
+
"""Test loading empty template-bundles.yml."""
|
|
204
|
+
bundles_file = tmp_path / "template-bundles.yml"
|
|
205
205
|
bundles_file.write_text("")
|
|
206
206
|
|
|
207
207
|
with pytest.raises(ValueError, match="Bundles file is empty"):
|
|
208
208
|
RhizaBundles.from_yaml(bundles_file)
|
|
209
209
|
|
|
210
210
|
def test_from_yaml_missing_version(self, tmp_path):
|
|
211
|
-
"""Test loading
|
|
212
|
-
bundles_file = tmp_path / "
|
|
211
|
+
"""Test loading template-bundles.yml without version."""
|
|
212
|
+
bundles_file = tmp_path / "template-bundles.yml"
|
|
213
213
|
bundles_file.write_text("bundles: {}")
|
|
214
214
|
|
|
215
215
|
with pytest.raises(ValueError, match="missing required field: version"):
|
|
216
216
|
RhizaBundles.from_yaml(bundles_file)
|
|
217
217
|
|
|
218
218
|
def test_from_yaml_invalid_bundles_type(self, tmp_path):
|
|
219
|
-
"""Test loading
|
|
220
|
-
bundles_file = tmp_path / "
|
|
219
|
+
"""Test loading template-bundles.yml with invalid bundles type."""
|
|
220
|
+
bundles_file = tmp_path / "template-bundles.yml"
|
|
221
221
|
bundles_file.write_text("version: '1.0'\nbundles: 'invalid'")
|
|
222
222
|
|
|
223
223
|
with pytest.raises(TypeError, match="Bundles must be a dictionary"):
|
|
@@ -322,7 +322,7 @@ class TestResolveIncludePaths:
|
|
|
322
322
|
templates=["core"],
|
|
323
323
|
)
|
|
324
324
|
|
|
325
|
-
with pytest.raises(ValueError, match=r"Template uses templates but
|
|
325
|
+
with pytest.raises(ValueError, match=r"Template uses templates but template-bundles\.yml not found"):
|
|
326
326
|
resolve_include_paths(template, None)
|
|
327
327
|
|
|
328
328
|
def test_no_configuration(self) -> None:
|
|
@@ -339,10 +339,10 @@ class TestLoadBundlesFromClone:
|
|
|
339
339
|
"""Test load_bundles_from_clone function."""
|
|
340
340
|
|
|
341
341
|
def test_load_existing_bundles(self, tmp_path):
|
|
342
|
-
"""Test loading
|
|
342
|
+
"""Test loading template-bundles.yml from cloned repo."""
|
|
343
343
|
rhiza_dir = tmp_path / ".rhiza"
|
|
344
344
|
rhiza_dir.mkdir()
|
|
345
|
-
bundles_file = rhiza_dir / "
|
|
345
|
+
bundles_file = rhiza_dir / "template-bundles.yml"
|
|
346
346
|
bundles_file.write_text("""
|
|
347
347
|
version: "1.0"
|
|
348
348
|
bundles:
|
|
@@ -359,6 +359,6 @@ bundles:
|
|
|
359
359
|
assert "core" in result.bundles
|
|
360
360
|
|
|
361
361
|
def test_load_missing_bundles(self, tmp_path):
|
|
362
|
-
"""Test that missing
|
|
362
|
+
"""Test that missing template-bundles.yml returns None."""
|
|
363
363
|
result = load_bundles_from_clone(tmp_path)
|
|
364
364
|
assert result is None
|
|
@@ -7,7 +7,7 @@ from rhiza.models import RhizaTemplate
|
|
|
7
7
|
|
|
8
8
|
@pytest.fixture
|
|
9
9
|
def template_repo(tmp_path):
|
|
10
|
-
"""Create a mock template repository with
|
|
10
|
+
"""Create a mock template repository with template-bundles.yml."""
|
|
11
11
|
repo = tmp_path / "template-repo"
|
|
12
12
|
repo.mkdir()
|
|
13
13
|
|
|
@@ -18,10 +18,10 @@ def template_repo(tmp_path):
|
|
|
18
18
|
subprocess.run(["git", "config", "user.email", "test@example.com"], cwd=repo, capture_output=True, check=True)
|
|
19
19
|
subprocess.run(["git", "config", "user.name", "Test User"], cwd=repo, capture_output=True, check=True)
|
|
20
20
|
|
|
21
|
-
# Create
|
|
21
|
+
# Create template-bundles.yml
|
|
22
22
|
rhiza_dir = repo / ".rhiza"
|
|
23
23
|
rhiza_dir.mkdir()
|
|
24
|
-
bundles_file = rhiza_dir / "
|
|
24
|
+
bundles_file = rhiza_dir / "template-bundles.yml"
|
|
25
25
|
bundles_file.write_text("""
|
|
26
26
|
version: "1.0"
|
|
27
27
|
bundles:
|
|
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
|
|
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
|
|
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
|