rhiza 0.5.3__tar.gz → 0.5.4__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 (68) hide show
  1. rhiza-0.5.4/.github/workflows/sym2.yml +134 -0
  2. {rhiza-0.5.3 → rhiza-0.5.4}/CLI.md +5 -1
  3. {rhiza-0.5.3 → rhiza-0.5.4}/PKG-INFO +68 -7
  4. {rhiza-0.5.3 → rhiza-0.5.4}/README.md +67 -6
  5. {rhiza-0.5.3 → rhiza-0.5.4}/USAGE.md +31 -0
  6. {rhiza-0.5.3 → rhiza-0.5.4}/pyproject.toml +1 -1
  7. rhiza-0.5.4/src/rhiza/__init__.py +65 -0
  8. {rhiza-0.5.3 → rhiza-0.5.4}/src/rhiza/cli.py +39 -17
  9. rhiza-0.5.4/src/rhiza/commands/__init__.py +55 -0
  10. {rhiza-0.5.3 → rhiza-0.5.4}/src/rhiza/commands/materialize.py +59 -3
  11. {rhiza-0.5.3 → rhiza-0.5.4}/src/rhiza/commands/validate.py +10 -1
  12. {rhiza-0.5.3 → rhiza-0.5.4}/src/rhiza/models.py +9 -1
  13. {rhiza-0.5.3 → rhiza-0.5.4}/tests/test_cli_commands.py +20 -0
  14. {rhiza-0.5.3 → rhiza-0.5.4}/tests/test_commands/test_materialize.py +407 -10
  15. {rhiza-0.5.3 → rhiza-0.5.4}/tests/test_commands/test_validate.py +74 -0
  16. {rhiza-0.5.3 → rhiza-0.5.4}/tests/test_models.py +90 -0
  17. rhiza-0.5.4/tests/test_package.py +53 -0
  18. {rhiza-0.5.3 → rhiza-0.5.4}/uv.lock +1 -1
  19. rhiza-0.5.3/src/rhiza/__init__.py +0 -15
  20. rhiza-0.5.3/src/rhiza/commands/__init__.py +0 -9
  21. {rhiza-0.5.3 → rhiza-0.5.4}/.editorconfig +0 -0
  22. {rhiza-0.5.3 → rhiza-0.5.4}/.github/README.md +0 -0
  23. {rhiza-0.5.3 → rhiza-0.5.4}/.github/TOKEN_SETUP.md +0 -0
  24. {rhiza-0.5.3 → rhiza-0.5.4}/.github/actions/setup-project/action.yml +0 -0
  25. {rhiza-0.5.3 → rhiza-0.5.4}/.github/copilot-instructions.md +0 -0
  26. {rhiza-0.5.3 → rhiza-0.5.4}/.github/renovate.json +0 -0
  27. {rhiza-0.5.3 → rhiza-0.5.4}/.github/scripts/book.sh +0 -0
  28. {rhiza-0.5.3 → rhiza-0.5.4}/.github/scripts/bump.sh +0 -0
  29. {rhiza-0.5.3 → rhiza-0.5.4}/.github/scripts/customisations/build-extras.sh +0 -0
  30. {rhiza-0.5.3 → rhiza-0.5.4}/.github/scripts/customisations/post-release.sh +0 -0
  31. {rhiza-0.5.3 → rhiza-0.5.4}/.github/scripts/marimushka.sh +0 -0
  32. {rhiza-0.5.3 → rhiza-0.5.4}/.github/scripts/release.sh +0 -0
  33. {rhiza-0.5.3 → rhiza-0.5.4}/.github/scripts/update-readme-help.sh +0 -0
  34. {rhiza-0.5.3 → rhiza-0.5.4}/.github/template.yml +0 -0
  35. {rhiza-0.5.3 → rhiza-0.5.4}/.github/workflows/book.yml +0 -0
  36. {rhiza-0.5.3 → rhiza-0.5.4}/.github/workflows/ci.yml +0 -0
  37. {rhiza-0.5.3 → rhiza-0.5.4}/.github/workflows/deptry.yml +0 -0
  38. {rhiza-0.5.3 → rhiza-0.5.4}/.github/workflows/marimo.yml +0 -0
  39. {rhiza-0.5.3 → rhiza-0.5.4}/.github/workflows/pre-commit.yml +0 -0
  40. {rhiza-0.5.3 → rhiza-0.5.4}/.github/workflows/release.yml +0 -0
  41. {rhiza-0.5.3 → rhiza-0.5.4}/.github/workflows/scripts/version_matrix.py +0 -0
  42. {rhiza-0.5.3 → rhiza-0.5.4}/.github/workflows/scripts/version_max.py +0 -0
  43. {rhiza-0.5.3 → rhiza-0.5.4}/.github/workflows/structure.yml +0 -0
  44. {rhiza-0.5.3 → rhiza-0.5.4}/.github/workflows/sync.yml +0 -0
  45. {rhiza-0.5.3 → rhiza-0.5.4}/.gitignore +0 -0
  46. {rhiza-0.5.3 → rhiza-0.5.4}/.pre-commit-config.yaml +0 -0
  47. {rhiza-0.5.3 → rhiza-0.5.4}/.rhiza.history +0 -0
  48. {rhiza-0.5.3 → rhiza-0.5.4}/CODE_OF_CONDUCT.md +0 -0
  49. {rhiza-0.5.3 → rhiza-0.5.4}/CONTRIBUTING.md +0 -0
  50. {rhiza-0.5.3 → rhiza-0.5.4}/LICENSE +0 -0
  51. {rhiza-0.5.3 → rhiza-0.5.4}/Makefile +0 -0
  52. {rhiza-0.5.3 → rhiza-0.5.4}/book/marimo/.gitkeep +0 -0
  53. {rhiza-0.5.3 → rhiza-0.5.4}/pytest.ini +0 -0
  54. {rhiza-0.5.3 → rhiza-0.5.4}/ruff.toml +0 -0
  55. {rhiza-0.5.3 → rhiza-0.5.4}/src/rhiza/__main__.py +0 -0
  56. {rhiza-0.5.3 → rhiza-0.5.4}/src/rhiza/commands/init.py +0 -0
  57. {rhiza-0.5.3 → rhiza-0.5.4}/tests/test_commands/test_init.py +0 -0
  58. {rhiza-0.5.3 → rhiza-0.5.4}/tests/test_rhiza/README.md +0 -0
  59. {rhiza-0.5.3 → rhiza-0.5.4}/tests/test_rhiza/conftest.py +0 -0
  60. {rhiza-0.5.3 → rhiza-0.5.4}/tests/test_rhiza/test_bump_script.py +0 -0
  61. {rhiza-0.5.3 → rhiza-0.5.4}/tests/test_rhiza/test_docstrings.py +0 -0
  62. {rhiza-0.5.3 → rhiza-0.5.4}/tests/test_rhiza/test_git_repo_fixture.py +0 -0
  63. {rhiza-0.5.3 → rhiza-0.5.4}/tests/test_rhiza/test_makefile.py +0 -0
  64. {rhiza-0.5.3 → rhiza-0.5.4}/tests/test_rhiza/test_marimushka_script.py +0 -0
  65. {rhiza-0.5.3 → rhiza-0.5.4}/tests/test_rhiza/test_readme.py +0 -0
  66. {rhiza-0.5.3 → rhiza-0.5.4}/tests/test_rhiza/test_release_script.py +0 -0
  67. {rhiza-0.5.3 → rhiza-0.5.4}/tests/test_rhiza/test_structure.py +0 -0
  68. {rhiza-0.5.3 → rhiza-0.5.4}/tests/test_rhiza/test_updatereadme_script.py +0 -0
@@ -0,0 +1,134 @@
1
+ name: SYM2
2
+ # This workflow materializes rhiza templates using the update_rhiza branch
3
+ # and creates a pull request with the changes.
4
+ # IMPORTANT: When workflow files (.github/workflows/*.yml) are modified,
5
+ # a Personal Access Token (PAT) with 'workflow' scope is required.
6
+ # The PAT_TOKEN secret must be set in repository secrets.
7
+ # See .github/TOKEN_SETUP.md for setup instructions.
8
+
9
+ permissions:
10
+ contents: write
11
+ pull-requests: write
12
+
13
+
14
+ on:
15
+ workflow_dispatch:
16
+ inputs:
17
+ create-pr:
18
+ description: "Create a pull request"
19
+ type: boolean
20
+ default: true
21
+
22
+ jobs:
23
+ materialize:
24
+ if: ${{ github.ref_name != 'update_rhiza' }}
25
+ runs-on: ubuntu-latest
26
+
27
+ steps:
28
+ - name: Checkout repository
29
+ uses: actions/checkout@v6
30
+ with:
31
+ token: ${{ secrets.PAT_TOKEN }}
32
+ fetch-depth: 0
33
+
34
+ - name: Check PAT_TOKEN configuration
35
+ shell: bash
36
+ env:
37
+ PAT_TOKEN: ${{ secrets.PAT_TOKEN }}
38
+ run: |
39
+ if [ -z "$PAT_TOKEN" ]; then
40
+ echo "::warning::PAT_TOKEN secret is not configured."
41
+ echo "::warning::If this materialize modifies workflow files, the push will fail."
42
+ echo "::warning::See .github/TOKEN_SETUP.md for setup instructions."
43
+ else
44
+ echo "✓ PAT_TOKEN is configured."
45
+ fi
46
+
47
+ - name: Install uv
48
+ uses: astral-sh/setup-uv@v7
49
+
50
+ - name: Materialize rhiza templates
51
+ id: materialize
52
+ shell: bash
53
+ env:
54
+ PAT_TOKEN: ${{ secrets.PAT_TOKEN }}
55
+ run: |
56
+ set -euo pipefail
57
+
58
+ git checkout -B update_rhiza
59
+
60
+ uvx rhiza materialize --force --branch update_rhiza .
61
+
62
+ git add -A
63
+
64
+ if git diff --cached --quiet; then
65
+ echo "No changes detected."
66
+ {
67
+ echo "changes_detected=false"
68
+ echo "workflows_changed=false"
69
+ echo "push_succeeded=false"
70
+ } >> "$GITHUB_OUTPUT"
71
+ exit 0
72
+ fi
73
+
74
+ echo "changes_detected=true" >> "$GITHUB_OUTPUT"
75
+
76
+ workflows_changed=false
77
+ can_push=true
78
+
79
+ if git diff --cached --name-only | grep -q '^\.github/workflows/'; then
80
+ workflows_changed=true
81
+ echo "workflows_changed=true" >> "$GITHUB_OUTPUT"
82
+ echo "⚠️ Workflow files modified."
83
+ echo ""
84
+ echo "ℹ️ Pushing workflow changes requires a PAT with 'workflow' scope."
85
+
86
+ if [ -n "$PAT_TOKEN" ]; then
87
+ git remote set-url origin \
88
+ "https://x-access-token:${PAT_TOKEN}@github.com/${{ github.repository }}.git"
89
+ echo "✓ Using PAT_TOKEN for authentication."
90
+ else
91
+ echo "::error::Workflow files changed but PAT_TOKEN secret is not set."
92
+ echo "::error::GitHub's security policy requires a Personal Access Token with 'workflow' scope to push workflow changes."
93
+ echo "::error::See .github/TOKEN_SETUP.md for instructions on creating and configuring the PAT_TOKEN secret."
94
+ can_push=false
95
+ fi
96
+ else
97
+ echo "workflows_changed=false" >> "$GITHUB_OUTPUT"
98
+ fi
99
+
100
+ git config user.name "github-actions[bot]"
101
+ git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
102
+
103
+ git commit -m "chore: Materialize rhiza templates from update_rhiza branch"
104
+
105
+ if [ "$can_push" = true ]; then
106
+ if git push origin HEAD:update_rhiza --force-with-lease; then
107
+ echo "push_succeeded=true" >> "$GITHUB_OUTPUT"
108
+ else
109
+ echo "push_succeeded=false" >> "$GITHUB_OUTPUT"
110
+ echo "::error::Failed to push branch 'update_rhiza'."
111
+ echo "::error::If workflow files were changed, this is likely because:"
112
+ echo "::error:: 1. PAT_TOKEN secret is not set, OR"
113
+ echo "::error:: 2. PAT_TOKEN lacks the 'workflow' scope"
114
+ echo "::error::See .github/TOKEN_SETUP.md for setup instructions."
115
+ exit 1
116
+ fi
117
+ else
118
+ echo "push_succeeded=false" >> "$GITHUB_OUTPUT"
119
+ fi
120
+
121
+ - name: Create pull request
122
+ if: ${{ inputs.create-pr && steps.materialize.outputs.changes_detected == 'true' && steps.materialize.outputs.push_succeeded == 'true' }}
123
+ uses: peter-evans/create-pull-request@v8
124
+ with:
125
+ token: ${{ secrets.PAT_TOKEN || github.token }}
126
+ base: ${{ github.event.repository.default_branch }}
127
+ branch: update_rhiza
128
+ delete-branch: false
129
+ title: "chore: Materialize rhiza templates from update_rhiza branch"
130
+ body: |
131
+ This pull request materializes rhiza templates using the `update_rhiza` branch.
132
+
133
+ Changes were generated automatically using **rhiza materialize --force --branch update_rhiza**.
134
+
@@ -165,6 +165,9 @@ grep "myfile.txt" .rhiza.history
165
165
  # Required: Template repository (owner/repo format)
166
166
  template-repository: jebel-quant/rhiza
167
167
 
168
+ # Optional: Hosting platform (default: github)
169
+ template-host: github
170
+
168
171
  # Optional: Branch to use (default: main)
169
172
  template-branch: main
170
173
 
@@ -184,7 +187,8 @@ exclude:
184
187
 
185
188
  | Field | Type | Required | Description |
186
189
  |-------|------|----------|-------------|
187
- | `template-repository` | string | Yes | GitHub repo in `owner/repo` format |
190
+ | `template-repository` | string | Yes | GitHub or GitLab repo in `owner/repo` format |
191
+ | `template-host` | string | No | Hosting platform: `github` (default) or `gitlab` |
188
192
  | `template-branch` | string | No | Branch name (default: `main`) |
189
193
  | `include` | list | Yes | Paths to copy from template |
190
194
  | `exclude` | list | No | Paths to skip when copying |
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: rhiza
3
- Version: 0.5.3
3
+ Version: 0.5.4
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
@@ -370,9 +370,12 @@ Rhiza uses a `.github/template.yml` file to define template sources and what to
370
370
  The `template.yml` file uses YAML format with the following structure:
371
371
 
372
372
  ```yaml
373
- # Required: GitHub repository containing templates (format: owner/repo)
373
+ # Required: GitHub or GitLab repository containing templates (format: owner/repo)
374
374
  template-repository: jebel-quant/rhiza
375
375
 
376
+ # Optional: Git hosting platform (default: github)
377
+ template-host: github
378
+
376
379
  # Optional: Branch to use from template repository (default: main)
377
380
  template-branch: main
378
381
 
@@ -398,8 +401,16 @@ exclude:
398
401
 
399
402
  - **Type:** String
400
403
  - **Format:** `owner/repository`
401
- - **Description:** GitHub repository containing your configuration templates
402
- - **Example:** `jebel-quant/rhiza`, `myorg/python-templates`
404
+ - **Description:** GitHub or GitLab repository containing your configuration templates
405
+ - **Example:** `jebel-quant/rhiza`, `myorg/python-templates`, `mygroup/gitlab-templates`
406
+
407
+ #### `template-host` (optional)
408
+
409
+ - **Type:** String
410
+ - **Default:** `github`
411
+ - **Options:** `github`, `gitlab`
412
+ - **Description:** Git hosting platform where the template repository is hosted
413
+ - **Example:** `github`, `gitlab`
403
414
 
404
415
  #### `template-branch` (optional)
405
416
 
@@ -443,6 +454,7 @@ exclude:
443
454
 
444
455
  ### Complete Configuration Example
445
456
 
457
+ #### GitHub Example
446
458
  ```yaml
447
459
  template-repository: jebel-quant/rhiza
448
460
  template-branch: main
@@ -461,6 +473,21 @@ exclude:
461
473
  - .github/CODEOWNERS
462
474
  ```
463
475
 
476
+ #### GitLab Example
477
+ ```yaml
478
+ template-repository: mygroup/python-templates
479
+ template-host: gitlab
480
+ template-branch: main
481
+ include:
482
+ - .gitlab-ci.yml
483
+ - .editorconfig
484
+ - .gitignore
485
+ - Makefile
486
+ - pytest.ini
487
+ exclude:
488
+ - .gitlab-ci.yml
489
+ ```
490
+
464
491
  ## Examples
465
492
 
466
493
  ### Example 1: Setting up a new Python project
@@ -532,7 +559,29 @@ Then materialize:
532
559
  rhiza materialize --force
533
560
  ```
534
561
 
535
- ### Example 4: Validating before CI/CD
562
+ ### Example 4: Using a GitLab template repository
563
+
564
+ Edit `.github/template.yml`:
565
+
566
+ ```yaml
567
+ template-repository: mygroup/python-templates
568
+ template-host: gitlab
569
+ template-branch: main
570
+ include:
571
+ - .gitlab-ci.yml
572
+ - .editorconfig
573
+ - .gitignore
574
+ - Makefile
575
+ - pytest.ini
576
+ ```
577
+
578
+ Then materialize:
579
+
580
+ ```bash
581
+ rhiza materialize --force
582
+ ```
583
+
584
+ ### Example 5: Validating before CI/CD
536
585
 
537
586
  Add to your CI pipeline:
538
587
 
@@ -736,8 +785,9 @@ Run `rhiza validate` for detailed error messages.
736
785
  Ensure:
737
786
  1. The template repository exists and is accessible
738
787
  2. The specified branch exists
739
- 3. You have network connectivity to GitHub
788
+ 3. You have network connectivity to GitHub or GitLab
740
789
  4. The repository is public (or you have appropriate credentials configured)
790
+ 5. The `template-host` field matches your repository's hosting platform (defaults to "github")
741
791
 
742
792
  ### Files not being copied
743
793
 
@@ -755,7 +805,18 @@ A: Yes, as long as you have Git credentials configured that allow access to the
755
805
 
756
806
  **Q: Does Rhiza support template repositories hosted outside GitHub?**
757
807
 
758
- A: Currently, Rhiza is designed for GitHub repositories. Support for other Git hosting services could be added in the future.
808
+ A: Yes! Rhiza supports both GitHub and GitLab repositories. Use the `template-host` field in your `.github/template.yml` to specify "github" (default) or "gitlab".
809
+
810
+ **Q: How do I use a GitLab repository as a template source?**
811
+
812
+ A: Add `template-host: gitlab` to your `.github/template.yml` file. For example:
813
+ ```yaml
814
+ template-repository: mygroup/myproject
815
+ template-host: gitlab
816
+ include:
817
+ - .gitlab-ci.yml
818
+ - Makefile
819
+ ```
759
820
 
760
821
  **Q: Can I materialize templates from multiple repositories?**
761
822
 
@@ -337,9 +337,12 @@ Rhiza uses a `.github/template.yml` file to define template sources and what to
337
337
  The `template.yml` file uses YAML format with the following structure:
338
338
 
339
339
  ```yaml
340
- # Required: GitHub repository containing templates (format: owner/repo)
340
+ # Required: GitHub or GitLab repository containing templates (format: owner/repo)
341
341
  template-repository: jebel-quant/rhiza
342
342
 
343
+ # Optional: Git hosting platform (default: github)
344
+ template-host: github
345
+
343
346
  # Optional: Branch to use from template repository (default: main)
344
347
  template-branch: main
345
348
 
@@ -365,8 +368,16 @@ exclude:
365
368
 
366
369
  - **Type:** String
367
370
  - **Format:** `owner/repository`
368
- - **Description:** GitHub repository containing your configuration templates
369
- - **Example:** `jebel-quant/rhiza`, `myorg/python-templates`
371
+ - **Description:** GitHub or GitLab repository containing your configuration templates
372
+ - **Example:** `jebel-quant/rhiza`, `myorg/python-templates`, `mygroup/gitlab-templates`
373
+
374
+ #### `template-host` (optional)
375
+
376
+ - **Type:** String
377
+ - **Default:** `github`
378
+ - **Options:** `github`, `gitlab`
379
+ - **Description:** Git hosting platform where the template repository is hosted
380
+ - **Example:** `github`, `gitlab`
370
381
 
371
382
  #### `template-branch` (optional)
372
383
 
@@ -410,6 +421,7 @@ exclude:
410
421
 
411
422
  ### Complete Configuration Example
412
423
 
424
+ #### GitHub Example
413
425
  ```yaml
414
426
  template-repository: jebel-quant/rhiza
415
427
  template-branch: main
@@ -428,6 +440,21 @@ exclude:
428
440
  - .github/CODEOWNERS
429
441
  ```
430
442
 
443
+ #### GitLab Example
444
+ ```yaml
445
+ template-repository: mygroup/python-templates
446
+ template-host: gitlab
447
+ template-branch: main
448
+ include:
449
+ - .gitlab-ci.yml
450
+ - .editorconfig
451
+ - .gitignore
452
+ - Makefile
453
+ - pytest.ini
454
+ exclude:
455
+ - .gitlab-ci.yml
456
+ ```
457
+
431
458
  ## Examples
432
459
 
433
460
  ### Example 1: Setting up a new Python project
@@ -499,7 +526,29 @@ Then materialize:
499
526
  rhiza materialize --force
500
527
  ```
501
528
 
502
- ### Example 4: Validating before CI/CD
529
+ ### Example 4: Using a GitLab template repository
530
+
531
+ Edit `.github/template.yml`:
532
+
533
+ ```yaml
534
+ template-repository: mygroup/python-templates
535
+ template-host: gitlab
536
+ template-branch: main
537
+ include:
538
+ - .gitlab-ci.yml
539
+ - .editorconfig
540
+ - .gitignore
541
+ - Makefile
542
+ - pytest.ini
543
+ ```
544
+
545
+ Then materialize:
546
+
547
+ ```bash
548
+ rhiza materialize --force
549
+ ```
550
+
551
+ ### Example 5: Validating before CI/CD
503
552
 
504
553
  Add to your CI pipeline:
505
554
 
@@ -703,8 +752,9 @@ Run `rhiza validate` for detailed error messages.
703
752
  Ensure:
704
753
  1. The template repository exists and is accessible
705
754
  2. The specified branch exists
706
- 3. You have network connectivity to GitHub
755
+ 3. You have network connectivity to GitHub or GitLab
707
756
  4. The repository is public (or you have appropriate credentials configured)
757
+ 5. The `template-host` field matches your repository's hosting platform (defaults to "github")
708
758
 
709
759
  ### Files not being copied
710
760
 
@@ -722,7 +772,18 @@ A: Yes, as long as you have Git credentials configured that allow access to the
722
772
 
723
773
  **Q: Does Rhiza support template repositories hosted outside GitHub?**
724
774
 
725
- A: Currently, Rhiza is designed for GitHub repositories. Support for other Git hosting services could be added in the future.
775
+ A: Yes! Rhiza supports both GitHub and GitLab repositories. Use the `template-host` field in your `.github/template.yml` to specify "github" (default) or "gitlab".
776
+
777
+ **Q: How do I use a GitLab repository as a template source?**
778
+
779
+ A: Add `template-host: gitlab` to your `.github/template.yml` file. For example:
780
+ ```yaml
781
+ template-repository: mygroup/myproject
782
+ template-host: gitlab
783
+ include:
784
+ - .gitlab-ci.yml
785
+ - Makefile
786
+ ```
726
787
 
727
788
  **Q: Can I materialize templates from multiple repositories?**
728
789
 
@@ -252,6 +252,37 @@ vim .github/template.yml # Change template-branch to 'develop'
252
252
  rhiza materialize
253
253
  ```
254
254
 
255
+ ### Using GitLab Repositories
256
+
257
+ Configure Rhiza to use a GitLab template repository:
258
+
259
+ **Edit `.github/template.yml`:**
260
+
261
+ ```yaml
262
+ template-repository: mygroup/python-templates
263
+ template-host: gitlab
264
+ template-branch: main
265
+ include:
266
+ - .gitlab-ci.yml
267
+ - .editorconfig
268
+ - .gitignore
269
+ - Makefile
270
+ - pytest.ini
271
+ exclude:
272
+ - .gitlab-ci.yml # Example exclusion
273
+ ```
274
+
275
+ **Materialize:**
276
+
277
+ ```bash
278
+ rhiza materialize --force
279
+ ```
280
+
281
+ **Notes:**
282
+ - The `template-host` field supports `github` (default) and `gitlab`
283
+ - Repository format is the same: `owner/repo` for GitHub or `group/project` for GitLab
284
+ - All other Rhiza features work identically with GitLab repositories
285
+
255
286
  ### Selective Inclusion
256
287
 
257
288
  Include only specific files:
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "rhiza"
7
- version = "0.5.3"
7
+ version = "0.5.4"
8
8
  description = "Reusable configuration templates for modern Python projects"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11"
@@ -0,0 +1,65 @@
1
+ """Rhiza — Manage reusable configuration templates for Python projects.
2
+
3
+ Rhiza is a command‑line interface (CLI) that helps you maintain consistent
4
+ configuration across multiple Python projects using templates stored in a
5
+ central repository. It can initialize projects with standard configuration,
6
+ materialize (inject) template files into a target repository, and validate the
7
+ template configuration.
8
+
9
+ ## Key features
10
+
11
+ - Template initialization for new or existing projects.
12
+ - Template materialization with selective include/exclude support.
13
+ - Configuration validation (syntax and basic semantics).
14
+ - Multi‑host support (GitHub and GitLab).
15
+ - Non‑destructive updates by default, with an explicit `--force` flag.
16
+
17
+ ## Quick start
18
+
19
+ Initialize a project with Rhiza templates:
20
+
21
+ ```bash
22
+ cd your-project
23
+ rhiza init
24
+ ```
25
+
26
+ Validate your configuration:
27
+
28
+ ```bash
29
+ rhiza validate
30
+ ```
31
+
32
+ Customize `.github/template.yml`, then materialize templates into your project:
33
+
34
+ ```bash
35
+ rhiza materialize
36
+ ```
37
+
38
+ ## Main modules
39
+
40
+ - `rhiza.commands` — Core command implementations (init, materialize, validate).
41
+ - `rhiza.models` — Data models and schemas for template configuration.
42
+
43
+ ## Documentation
44
+
45
+ For an overview and usage guides, see the repository files:
46
+
47
+ - [README.md](https://github.com/jebel-quant/rhiza-cli/blob/main/README.md) —
48
+ Project overview and installation instructions.
49
+ - [USAGE.md](https://github.com/jebel-quant/rhiza-cli/blob/main/USAGE.md) —
50
+ Practical examples, workflows, and best practices.
51
+ - [CLI.md](https://github.com/jebel-quant/rhiza-cli/blob/main/CLI.md) —
52
+ Command reference with examples.
53
+
54
+ Latest version and updates: https://github.com/jebel-quant/rhiza-cli
55
+ """
56
+
57
+ from importlib.metadata import PackageNotFoundError, version
58
+
59
+ try:
60
+ __version__ = version("rhiza")
61
+ except PackageNotFoundError:
62
+ # Package is not installed, use a fallback version
63
+ __version__ = "0.0.0+dev"
64
+
65
+ __all__ = ["commands", "models"]
@@ -14,7 +14,13 @@ from rhiza.commands import materialize as materialize_cmd
14
14
  from rhiza.commands import validate as validate_cmd
15
15
 
16
16
  app = typer.Typer(
17
- help="Rhiza - Manage reusable configuration templates for Python projects",
17
+ help=(
18
+ """
19
+ Rhiza - Manage reusable configuration templates for Python projects
20
+
21
+ \x1b]8;;https://jebel-quant.github.io/rhiza-cli/\x1b\\https://jebel-quant.github.io/rhiza-cli/\x1b]8;;\x1b\\
22
+ """
23
+ ),
18
24
  add_completion=True,
19
25
  )
20
26
 
@@ -64,11 +70,13 @@ def init(
64
70
  help="Target directory (defaults to current directory)",
65
71
  ),
66
72
  ):
67
- """Initialize or validate .github/template.yml.
73
+ r"""Initialize or validate .github/template.yml.
68
74
 
69
- Creates a default .github/template.yml configuration file if one doesn't
70
- exist, or validates the existing configuration.
75
+ \b
76
+ Creates a default `.github/template.yml` configuration file if one
77
+ doesn't exist, or validates the existing configuration.
71
78
 
79
+ \b
72
80
  The default template includes common Python project files:
73
81
  - .github (workflows, actions, etc.)
74
82
  - .editorconfig
@@ -77,10 +85,11 @@ def init(
77
85
  - Makefile
78
86
  - pytest.ini
79
87
 
88
+ \b
80
89
  Examples:
81
- rhiza init
82
- rhiza init /path/to/project
83
- rhiza init ..
90
+ rhiza init
91
+ rhiza init /path/to/project
92
+ rhiza init ..
84
93
  """
85
94
  init_cmd(target)
86
95
 
@@ -95,27 +104,36 @@ def materialize(
95
104
  help="Target git repository (defaults to current directory)",
96
105
  ),
97
106
  branch: str = typer.Option("main", "--branch", "-b", help="Rhiza branch to use"),
107
+ target_branch: str = typer.Option(
108
+ None,
109
+ "--target-branch",
110
+ "--checkout-branch",
111
+ help="Create and checkout a new branch in the target repository for changes",
112
+ ),
98
113
  force: bool = typer.Option(False, "--force", "-y", help="Overwrite existing files"),
99
114
  ):
100
- """Inject Rhiza configuration templates into a target repository.
115
+ r"""Inject Rhiza configuration templates into a target repository.
101
116
 
117
+ \b
102
118
  Materializes configuration files from the template repository specified
103
119
  in .github/template.yml into your project. This command:
104
120
 
105
- 1. Reads .github/template.yml configuration
106
- 2. Performs a sparse clone of the template repository
107
- 3. Copies specified files/directories to your project
108
- 4. Respects exclusion patterns defined in the configuration
109
-
110
- Files that already exist will NOT be overwritten unless --force is used.
121
+ \b
122
+ - Reads .github/template.yml configuration
123
+ - Performs a sparse clone of the template repository
124
+ - Copies specified files/directories to your project
125
+ - Respects exclusion patterns defined in the configuration
126
+ - Files that already exist will NOT be overwritten unless --force is used.
111
127
 
128
+ \b
112
129
  Examples:
113
130
  rhiza materialize
114
131
  rhiza materialize --branch develop
115
132
  rhiza materialize --force
133
+ rhiza materialize --target-branch feature/update-templates
116
134
  rhiza materialize /path/to/project -b v2.0 -y
117
135
  """
118
- materialize_cmd(target, branch, force)
136
+ materialize_cmd(target, branch, target_branch, force)
119
137
 
120
138
 
121
139
  @app.command()
@@ -128,11 +146,13 @@ def validate(
128
146
  help="Target git repository (defaults to current directory)",
129
147
  ),
130
148
  ):
131
- """Validate Rhiza template configuration.
149
+ r"""Validate Rhiza template configuration.
132
150
 
133
151
  Validates the .github/template.yml file to ensure it is syntactically
134
- correct and semantically valid. Performs comprehensive validation:
152
+ correct and semantically valid.
135
153
 
154
+ \b
155
+ Performs comprehensive validation:
136
156
  - Checks if template.yml exists
137
157
  - Validates YAML syntax
138
158
  - Verifies required fields are present (template-repository, include)
@@ -140,8 +160,10 @@ def validate(
140
160
  - Ensures repository name follows owner/repo format
141
161
  - Confirms include paths are not empty
142
162
 
163
+
143
164
  Returns exit code 0 on success, 1 on validation failure.
144
165
 
166
+ \b
145
167
  Examples:
146
168
  rhiza validate
147
169
  rhiza validate /path/to/project
@@ -0,0 +1,55 @@
1
+ """Command implementations for the Rhiza CLI.
2
+
3
+ This package contains the core implementation functions that back the Typer
4
+ commands exposed by `rhiza.cli`. These commands help you manage reusable
5
+ configuration templates for Python projects.
6
+
7
+ ## Available Commands
8
+
9
+ ### init
10
+
11
+ Initialize or validate `.github/template.yml` in a target directory.
12
+
13
+ Creates a default configuration file if it doesn't exist, or validates
14
+ an existing one. The default configuration includes common Python project
15
+ files like `.github`, `.editorconfig`, `.gitignore`,
16
+ `.pre-commit-config.yaml`, `Makefile`, and `pytest.ini`.
17
+
18
+ ### materialize
19
+
20
+ Inject Rhiza configuration templates into a target repository.
21
+
22
+ Materializes template files from the configured template repository into
23
+ your target project by performing a sparse clone of the template repository,
24
+ copying specified files/directories, and respecting exclusion patterns.
25
+ Files that already exist will not be overwritten unless the `--force` flag
26
+ is used.
27
+
28
+ ### validate
29
+
30
+ Validate Rhiza template configuration.
31
+
32
+ Validates the `.github/template.yml` file to ensure it is syntactically
33
+ correct and semantically valid. Performs comprehensive validation including
34
+ YAML syntax checking, required field verification, field type validation,
35
+ and repository format verification.
36
+
37
+ ## Usage Example
38
+
39
+ These functions are typically invoked through the CLI:
40
+
41
+ ```bash
42
+ $ rhiza init # Initialize configuration
43
+
44
+ $ rhiza materialize # Apply templates to project
45
+
46
+ $ rhiza validate # Validate template configuration
47
+ ```
48
+
49
+ For more detailed usage examples and workflows, see the USAGE.md guide
50
+ or try rhiza <command> --help
51
+ """
52
+
53
+ from .init import init # noqa: F401
54
+ from .materialize import materialize # noqa: F401
55
+ from .validate import validate # noqa: F401