rhiza 0.3.0__py3-none-any.whl → 0.5.0__py3-none-any.whl

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.
@@ -0,0 +1,773 @@
1
+ Metadata-Version: 2.4
2
+ Name: rhiza
3
+ Version: 0.5.0
4
+ Summary: Reusable configuration templates for modern Python projects
5
+ Project-URL: Homepage, https://github.com/jebel-quant/rhiza-cli
6
+ Project-URL: Repository, https://github.com/jebel-quant/rhiza-cli
7
+ Project-URL: Issues, https://github.com/jebel-quant/rhiza/issues-cli
8
+ Author: Thomas Schmelzer
9
+ License: MIT
10
+ License-File: LICENSE
11
+ Keywords: ci,configuration,ruff,taskfile,templates
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3 :: Only
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Programming Language :: Python :: 3.13
19
+ Classifier: Programming Language :: Python :: 3.14
20
+ Classifier: Topic :: Software Development :: Build Tools
21
+ Requires-Python: >=3.11
22
+ Requires-Dist: loguru>=0.7.3
23
+ Requires-Dist: pyyaml==6.0.3
24
+ Requires-Dist: typer>=0.20.0
25
+ Provides-Extra: dev
26
+ Requires-Dist: marimo==0.18.4; extra == 'dev'
27
+ Requires-Dist: pdoc>=16.0.0; extra == 'dev'
28
+ Requires-Dist: pre-commit==4.5.0; extra == 'dev'
29
+ Requires-Dist: pytest-cov>=7.0.0; extra == 'dev'
30
+ Requires-Dist: pytest-html>=4.1.1; extra == 'dev'
31
+ Requires-Dist: pytest==9.0.2; extra == 'dev'
32
+ Description-Content-Type: text/markdown
33
+
34
+ # rhiza-cli
35
+
36
+ [![Python 3.11+](https://img.shields.io/badge/python-3.11+-blue.svg)](https://www.python.org/downloads/)
37
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
38
+
39
+ Command-line interface for managing reusable configuration templates for modern Python projects.
40
+
41
+ ## Overview
42
+
43
+ Rhiza is a CLI tool that helps you maintain consistent configuration across multiple Python projects by using templates stored in a central repository. It allows you to:
44
+
45
+ - Initialize projects with standard configuration templates
46
+ - Materialize (inject) templates into target repositories
47
+ - Validate template configurations
48
+ - Keep project configurations synchronized with template repositories
49
+
50
+ ## Table of Contents
51
+
52
+ - [Overview](#overview)
53
+ - [Installation](#installation)
54
+ - [Quick Start](#quick-start)
55
+ - [Commands](#commands)
56
+ - [init](#rhiza-init)
57
+ - [materialize](#rhiza-materialize)
58
+ - [validate](#rhiza-validate)
59
+ - [Configuration](#configuration)
60
+ - [Examples](#examples)
61
+ - [Development](#development)
62
+ - [Additional Documentation](#additional-documentation)
63
+
64
+ ## Additional Documentation
65
+
66
+ For more detailed information, see:
67
+
68
+ - **[CLI Quick Reference](CLI.md)** - Command syntax and quick examples
69
+ - **[Usage Guide](USAGE.md)** - Practical tutorials and workflows
70
+ - **[Contributing Guidelines](CONTRIBUTING.md)** - How to contribute to the project
71
+ - **[Code of Conduct](CODE_OF_CONDUCT.md)** - Community guidelines
72
+
73
+ ## Installation
74
+
75
+ ### Using pip
76
+
77
+ ```bash
78
+ pip install rhiza
79
+ ```
80
+
81
+ ### From source
82
+
83
+ ```bash
84
+ git clone https://github.com/jebel-quant/rhiza-cli.git
85
+ cd rhiza-cli
86
+ pip install -e .
87
+ ```
88
+
89
+ ### Using uv (recommended for development)
90
+
91
+ ```bash
92
+ git clone https://github.com/jebel-quant/rhiza-cli.git
93
+ cd rhiza-cli
94
+ make install
95
+ ```
96
+
97
+ ### Verify installation
98
+
99
+ ```bash
100
+ rhiza --help
101
+ ```
102
+
103
+ ## Quick Start
104
+
105
+ 1. **Initialize a project with Rhiza templates:**
106
+
107
+ ```bash
108
+ cd your-project
109
+ rhiza init
110
+ ```
111
+
112
+ This creates a `.github/template.yml` file with default configuration.
113
+
114
+ 2. **Customize the template configuration:**
115
+
116
+ Edit `.github/template.yml` to specify which files/directories to include from your template repository.
117
+
118
+ 3. **Materialize templates into your project:**
119
+
120
+ ```bash
121
+ rhiza materialize
122
+ ```
123
+
124
+ This fetches and copies template files into your project.
125
+
126
+ 4. **Validate your configuration:**
127
+
128
+ ```bash
129
+ rhiza validate
130
+ ```
131
+
132
+ This checks that your `.github/template.yml` is correctly formatted and valid.
133
+
134
+ ## Commands
135
+
136
+ ### `rhiza init`
137
+
138
+ Initialize or validate `.github/template.yml` in a target directory.
139
+
140
+ **Usage:**
141
+
142
+ ```bash
143
+ rhiza init [TARGET]
144
+ ```
145
+
146
+ **Arguments:**
147
+
148
+ - `TARGET` - Target directory (defaults to current directory)
149
+
150
+ **Description:**
151
+
152
+ Creates a default `.github/template.yml` file if it doesn't exist, or validates an existing one. The default configuration includes common Python project files like `.github`, `.editorconfig`, `.gitignore`, `.pre-commit-config.yaml`, `Makefile`, and `pytest.ini`.
153
+
154
+ **Examples:**
155
+
156
+ ```bash
157
+ # Initialize in current directory
158
+ rhiza init
159
+
160
+ # Initialize in a specific directory
161
+ rhiza init /path/to/project
162
+
163
+ # Initialize in parent directory
164
+ rhiza init ..
165
+ ```
166
+
167
+ **Output:**
168
+
169
+ When creating a new template file:
170
+ ```
171
+ [INFO] Initializing Rhiza configuration in: /path/to/project
172
+ [INFO] Creating default .github/template.yml
173
+ ✓ Created .github/template.yml
174
+
175
+ Next steps:
176
+ 1. Review and customize .github/template.yml to match your project needs
177
+ 2. Run 'rhiza materialize' to inject templates into your repository
178
+ ```
179
+
180
+ When validating an existing file:
181
+ ```
182
+ [INFO] Validating template configuration in: /path/to/project
183
+ ✓ Found template file: /path/to/project/.github/template.yml
184
+ ✓ YAML syntax is valid
185
+ ✓ Field 'template-repository' is present and valid
186
+ ✓ Field 'include' is present and valid
187
+ ✓ template-repository format is valid: jebel-quant/rhiza
188
+ ✓ include list has 6 path(s)
189
+ ✓ Validation passed: template.yml is valid
190
+ ```
191
+
192
+ ---
193
+
194
+ ### `rhiza materialize`
195
+
196
+ Inject Rhiza configuration templates into a target repository.
197
+
198
+ **Usage:**
199
+
200
+ ```bash
201
+ rhiza materialize [OPTIONS] [TARGET]
202
+ ```
203
+
204
+ **Arguments:**
205
+
206
+ - `TARGET` - Target git repository directory (defaults to current directory)
207
+
208
+ **Options:**
209
+
210
+ - `--branch, -b TEXT` - Rhiza branch to use [default: main]
211
+ - `--force, -y` - Overwrite existing files without prompting
212
+ - `--help` - Show help message and exit
213
+
214
+ **Description:**
215
+
216
+ Materializes template files from the configured template repository into your target project. This command:
217
+
218
+ 1. Reads the `.github/template.yml` configuration
219
+ 2. Performs a sparse clone of the template repository
220
+ 3. Copies specified files/directories to your project
221
+ 4. Respects exclusion patterns defined in the configuration
222
+
223
+ **Examples:**
224
+
225
+ ```bash
226
+ # Materialize templates in current directory
227
+ rhiza materialize
228
+
229
+ # Materialize templates from a specific branch
230
+ rhiza materialize --branch develop
231
+
232
+ # Materialize and overwrite existing files
233
+ rhiza materialize --force
234
+
235
+ # Materialize in a specific directory with custom branch
236
+ rhiza materialize /path/to/project --branch v2.0 --force
237
+
238
+ # Short form with all options
239
+ rhiza materialize -b main -y
240
+ ```
241
+
242
+ **Output:**
243
+
244
+ ```
245
+ [INFO] Target repository: /path/to/project
246
+ [INFO] Rhiza branch: main
247
+ [INFO] Initializing Rhiza configuration in: /path/to/project
248
+ [INFO] Include paths:
249
+ - .github
250
+ - .editorconfig
251
+ - .gitignore
252
+ - .pre-commit-config.yaml
253
+ - Makefile
254
+ - pytest.ini
255
+ [INFO] Cloning jebel-quant/rhiza@main into temporary directory
256
+ [ADD] .github/workflows/ci.yml
257
+ [ADD] .editorconfig
258
+ [ADD] .gitignore
259
+ [ADD] Makefile
260
+ ✓ Rhiza templates materialized successfully
261
+
262
+ Next steps:
263
+ 1. Review changes:
264
+ git status
265
+ git diff
266
+
267
+ 2. Commit:
268
+ git add .
269
+ git commit -m "chore: import rhiza templates"
270
+
271
+ This is a one-shot snapshot.
272
+ Re-run this script to update templates explicitly.
273
+ ```
274
+
275
+ **Notes:**
276
+
277
+ - Files that already exist will not be overwritten unless `--force` is used
278
+ - The command performs a sparse clone for efficiency
279
+ - Template files are copied with their original permissions
280
+ - Excluded paths (if defined) are filtered out
281
+
282
+ ---
283
+
284
+ ### `rhiza validate`
285
+
286
+ Validate Rhiza template configuration.
287
+
288
+ **Usage:**
289
+
290
+ ```bash
291
+ rhiza validate [TARGET]
292
+ ```
293
+
294
+ **Arguments:**
295
+
296
+ - `TARGET` - Target git repository directory (defaults to current directory)
297
+
298
+ **Description:**
299
+
300
+ Validates the `.github/template.yml` file to ensure it is syntactically correct and semantically valid. This performs authoritative validation including:
301
+
302
+ - Checking if the file exists
303
+ - Validating YAML syntax
304
+ - Verifying required fields are present
305
+ - Checking field types and formats
306
+ - Validating repository name format
307
+ - Ensuring include paths are not empty
308
+
309
+ **Examples:**
310
+
311
+ ```bash
312
+ # Validate configuration in current directory
313
+ rhiza validate
314
+
315
+ # Validate configuration in a specific directory
316
+ rhiza validate /path/to/project
317
+
318
+ # Validate parent directory
319
+ rhiza validate ..
320
+ ```
321
+
322
+ **Exit codes:**
323
+
324
+ - `0` - Validation passed
325
+ - `1` - Validation failed
326
+
327
+ **Output (success):**
328
+
329
+ ```
330
+ [INFO] Validating template configuration in: /path/to/project
331
+ ✓ Found template file: /path/to/project/.github/template.yml
332
+ ✓ YAML syntax is valid
333
+ ✓ Field 'template-repository' is present and valid
334
+ ✓ Field 'include' is present and valid
335
+ ✓ template-repository format is valid: jebel-quant/rhiza
336
+ ✓ include list has 6 path(s)
337
+ - .github
338
+ - .editorconfig
339
+ - .gitignore
340
+ - .pre-commit-config.yaml
341
+ - Makefile
342
+ - pytest.ini
343
+ ✓ Validation passed: template.yml is valid
344
+ ```
345
+
346
+ **Output (failure):**
347
+
348
+ ```
349
+ [ERROR] Target directory is not a git repository: /path/to/project
350
+ ```
351
+
352
+ or
353
+
354
+ ```
355
+ [ERROR] Template file not found: /path/to/project/.github/template.yml
356
+ [INFO] Run 'rhiza materialize' or 'rhiza init' to create a default template.yml
357
+ ```
358
+
359
+ ---
360
+
361
+ ## Configuration
362
+
363
+ Rhiza uses a `.github/template.yml` file to define template sources and what to include in your project.
364
+
365
+ ### Configuration File Format
366
+
367
+ The `template.yml` file uses YAML format with the following structure:
368
+
369
+ ```yaml
370
+ # Required: GitHub repository containing templates (format: owner/repo)
371
+ template-repository: jebel-quant/rhiza
372
+
373
+ # Optional: Branch to use from template repository (default: main)
374
+ template-branch: main
375
+
376
+ # Required: List of paths to include from template repository
377
+ include:
378
+ - .github
379
+ - .editorconfig
380
+ - .gitignore
381
+ - .pre-commit-config.yaml
382
+ - Makefile
383
+ - pytest.ini
384
+ - ruff.toml
385
+
386
+ # Optional: List of paths to exclude (filters out from included paths)
387
+ exclude:
388
+ - .github/workflows/specific-workflow.yml
389
+ - .github/CODEOWNERS
390
+ ```
391
+
392
+ ### Configuration Fields
393
+
394
+ #### `template-repository` (required)
395
+
396
+ - **Type:** String
397
+ - **Format:** `owner/repository`
398
+ - **Description:** GitHub repository containing your configuration templates
399
+ - **Example:** `jebel-quant/rhiza`, `myorg/python-templates`
400
+
401
+ #### `template-branch` (optional)
402
+
403
+ - **Type:** String
404
+ - **Default:** `main`
405
+ - **Description:** Git branch to use when fetching templates
406
+ - **Example:** `main`, `develop`, `v2.0`
407
+
408
+ #### `include` (required)
409
+
410
+ - **Type:** List of strings
411
+ - **Description:** Paths (files or directories) to copy from the template repository
412
+ - **Notes:**
413
+ - Paths are relative to the repository root
414
+ - Can include both files and directories
415
+ - Directories are recursively copied
416
+ - Must contain at least one path
417
+
418
+ **Example:**
419
+ ```yaml
420
+ include:
421
+ - .github # Entire directory
422
+ - .editorconfig # Single file
423
+ - src/config # Subdirectory
424
+ ```
425
+
426
+ #### `exclude` (optional)
427
+
428
+ - **Type:** List of strings
429
+ - **Description:** Paths to exclude from the included set
430
+ - **Notes:**
431
+ - Useful for excluding specific files from broader directory includes
432
+ - Paths are relative to the repository root
433
+
434
+ **Example:**
435
+ ```yaml
436
+ exclude:
437
+ - .github/workflows/deploy.yml # Exclude specific workflow
438
+ - .github/CODEOWNERS # Exclude specific file
439
+ ```
440
+
441
+ ### Complete Configuration Example
442
+
443
+ ```yaml
444
+ template-repository: jebel-quant/rhiza
445
+ template-branch: main
446
+ include:
447
+ - .github
448
+ - .editorconfig
449
+ - .gitignore
450
+ - .pre-commit-config.yaml
451
+ - CODE_OF_CONDUCT.md
452
+ - CONTRIBUTING.md
453
+ - Makefile
454
+ - pytest.ini
455
+ - ruff.toml
456
+ exclude:
457
+ - .github/workflows/release.yml
458
+ - .github/CODEOWNERS
459
+ ```
460
+
461
+ ## Examples
462
+
463
+ ### Example 1: Setting up a new Python project
464
+
465
+ ```bash
466
+ # Create a new project directory
467
+ mkdir my-python-project
468
+ cd my-python-project
469
+
470
+ # Initialize git
471
+ git init
472
+
473
+ # Initialize Rhiza
474
+ rhiza init
475
+
476
+ # Review the generated template.yml
477
+ cat .github/template.yml
478
+
479
+ # Materialize templates
480
+ rhiza materialize
481
+
482
+ # Review the imported files
483
+ git status
484
+
485
+ # Commit the changes
486
+ git add .
487
+ git commit -m "chore: initialize project with rhiza templates"
488
+ ```
489
+
490
+ ### Example 2: Updating existing project templates
491
+
492
+ ```bash
493
+ # Navigate to your project
494
+ cd existing-project
495
+
496
+ # Validate current configuration
497
+ rhiza validate
498
+
499
+ # Update templates (overwrite existing)
500
+ rhiza materialize --force
501
+
502
+ # Review changes
503
+ git diff
504
+
505
+ # Commit if satisfied
506
+ git add .
507
+ git commit -m "chore: update rhiza templates"
508
+ ```
509
+
510
+ ### Example 3: Using a custom template repository
511
+
512
+ Edit `.github/template.yml`:
513
+
514
+ ```yaml
515
+ template-repository: myorg/my-templates
516
+ template-branch: production
517
+ include:
518
+ - .github/workflows
519
+ - pyproject.toml
520
+ - Makefile
521
+ - docker-compose.yml
522
+ exclude:
523
+ - .github/workflows/experimental.yml
524
+ ```
525
+
526
+ Then materialize:
527
+
528
+ ```bash
529
+ rhiza materialize --force
530
+ ```
531
+
532
+ ### Example 4: Validating before CI/CD
533
+
534
+ Add to your CI pipeline:
535
+
536
+ ```yaml
537
+ # .github/workflows/validate-rhiza.yml
538
+ name: Validate Rhiza Configuration
539
+
540
+ on: [push, pull_request]
541
+
542
+ jobs:
543
+ validate:
544
+ runs-on: ubuntu-latest
545
+ steps:
546
+ - uses: actions/checkout@v4
547
+ - uses: actions/setup-python@v5
548
+ with:
549
+ python-version: '3.11'
550
+ - name: Install rhiza
551
+ run: pip install rhiza
552
+ - name: Validate configuration
553
+ run: rhiza validate
554
+ ```
555
+
556
+ ## Development
557
+
558
+ ### Prerequisites
559
+
560
+ - Python 3.11 or higher
561
+ - `uv` package manager (recommended) or `pip`
562
+ - Git
563
+
564
+ ### Setup Development Environment
565
+
566
+ ```bash
567
+ # Clone the repository
568
+ git clone https://github.com/jebel-quant/rhiza-cli.git
569
+ cd rhiza-cli
570
+
571
+ # Install dependencies
572
+ make install
573
+
574
+ # Run tests
575
+ make test
576
+
577
+ # Run linters and formatters
578
+ make fmt
579
+
580
+ # Generate documentation
581
+ make docs
582
+ ```
583
+
584
+ ### Running Tests
585
+
586
+ ```bash
587
+ # Run all tests with coverage
588
+ make test
589
+
590
+ # Run specific test file
591
+ pytest tests/test_cli.py
592
+
593
+ # Run with verbose output
594
+ pytest -v
595
+ ```
596
+
597
+ ### Code Quality
598
+
599
+ The project uses:
600
+
601
+ - **Ruff** for linting and formatting
602
+ - **pytest** for testing
603
+ - **pre-commit** hooks for automated checks
604
+
605
+ ```bash
606
+ # Run all quality checks
607
+ make fmt
608
+
609
+ # Run dependency checks
610
+ make deptry
611
+ ```
612
+
613
+ ### Building Documentation
614
+
615
+ ```bash
616
+ # Generate API documentation
617
+ make docs
618
+
619
+ # Build complete documentation book
620
+ make book
621
+ ```
622
+
623
+ ## Makefile Targets
624
+
625
+ The project includes a comprehensive Makefile for common development tasks:
626
+
627
+ ```
628
+ Bootstrap
629
+ install-uv ensure uv/uvx is installed
630
+ install-extras run custom build script (if exists)
631
+ install install
632
+ clean clean
633
+
634
+ Development and Testing
635
+ test run all tests
636
+ marimo fire up Marimo server
637
+ marimushka export Marimo notebooks to HTML
638
+ deptry run deptry if pyproject.toml exists
639
+
640
+ Documentation
641
+ docs create documentation with pdoc
642
+ book compile the companion book
643
+ fmt check the pre-commit hooks and the linting
644
+ all Run everything
645
+
646
+ Releasing and Versioning
647
+ bump bump version
648
+ release create tag and push to remote with prompts
649
+ post-release perform post-release tasks
650
+
651
+ Meta
652
+ sync sync with template repository as defined in .github/template.yml
653
+ help Display this help message
654
+ customisations list available customisation scripts
655
+ update-readme update README.md with current Makefile help output
656
+ ```
657
+
658
+ Run `make help` to see this list in your terminal.
659
+
660
+ ## Contributing
661
+
662
+ Contributions are welcome! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.
663
+
664
+ ### Reporting Issues
665
+
666
+ If you find a bug or have a feature request, please open an issue on [GitHub](https://github.com/jebel-quant/rhiza-cli/issues).
667
+
668
+ ### Code of Conduct
669
+
670
+ This project follows a [Code of Conduct](CODE_OF_CONDUCT.md). By participating, you are expected to uphold this code.
671
+
672
+ ## License
673
+
674
+ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
675
+
676
+ ## Links
677
+
678
+ - **Repository:** https://github.com/jebel-quant/rhiza-cli
679
+ - **Issues:** https://github.com/jebel-quant/rhiza-cli/issues
680
+ - **Documentation:** Generated with `make docs`
681
+
682
+ ## Architecture
683
+
684
+ Rhiza follows a modular architecture:
685
+
686
+ ```
687
+ src/rhiza/
688
+ ├── __init__.py # Package initialization
689
+ ├── __main__.py # Entry point for python -m rhiza
690
+ ├── cli.py # Typer app and CLI command definitions
691
+ ├── models.py # Data models (RhizaTemplate)
692
+ └── commands/ # Command implementations
693
+ ├── __init__.py
694
+ ├── init.py # Initialize template.yml
695
+ ├── materialize.py # Materialize templates
696
+ └── validate.py # Validate configuration
697
+ ```
698
+
699
+ ### Design Principles
700
+
701
+ 1. **Thin CLI Layer:** Commands in `cli.py` are thin wrappers that delegate to implementations in `commands/`
702
+ 2. **Separation of Concerns:** Each command has its own module with focused functionality
703
+ 3. **Type Safety:** Uses `pathlib.Path` for file operations and Typer for type-checked CLI arguments
704
+ 4. **Clear Logging:** Uses `loguru` for structured, colored logging output
705
+ 5. **Validation First:** Always validates configuration before performing operations
706
+
707
+ ## Troubleshooting
708
+
709
+ ### Command not found: rhiza
710
+
711
+ Ensure the package is installed and your Python scripts directory is in your PATH:
712
+
713
+ ```bash
714
+ pip install --user rhiza
715
+ # Add ~/.local/bin to PATH if needed
716
+ export PATH="$HOME/.local/bin:$PATH"
717
+ ```
718
+
719
+ ### Template validation fails
720
+
721
+ Check that:
722
+ 1. Your `.github/template.yml` file exists
723
+ 2. The YAML syntax is valid
724
+ 3. Required fields (`template-repository` and `include`) are present
725
+ 4. The repository format is `owner/repo`
726
+
727
+ Run `rhiza validate` for detailed error messages.
728
+
729
+ ### Git clone fails during materialize
730
+
731
+ Ensure:
732
+ 1. The template repository exists and is accessible
733
+ 2. The specified branch exists
734
+ 3. You have network connectivity to GitHub
735
+ 4. The repository is public (or you have appropriate credentials configured)
736
+
737
+ ### Files not being copied
738
+
739
+ Check:
740
+ 1. The paths in `include` are correct relative to the template repository root
741
+ 2. The paths exist in the specified branch
742
+ 3. Any `exclude` patterns are not filtering out wanted files
743
+ 4. You're using `--force` if files already exist and need to be overwritten
744
+
745
+ ## FAQ
746
+
747
+ **Q: Can I use Rhiza with private template repositories?**
748
+
749
+ A: Yes, as long as you have Git credentials configured that allow access to the repository.
750
+
751
+ **Q: Does Rhiza support template repositories hosted outside GitHub?**
752
+
753
+ A: Currently, Rhiza is designed for GitHub repositories. Support for other Git hosting services could be added in the future.
754
+
755
+ **Q: Can I materialize templates from multiple repositories?**
756
+
757
+ A: Not directly. However, you can run `rhiza materialize` multiple times with different configurations, or combine templates manually.
758
+
759
+ **Q: What's the difference between `rhiza init` and `rhiza materialize`?**
760
+
761
+ A: `init` creates or validates the `.github/template.yml` configuration file. `materialize` reads that configuration and actually copies the template files into your project.
762
+
763
+ **Q: How do I update my project's templates?**
764
+
765
+ A: Simply run `rhiza materialize --force` to fetch and overwrite with the latest versions from your template repository.
766
+
767
+ **Q: Can I customize which files are included?**
768
+
769
+ A: Yes, edit the `include` and `exclude` lists in `.github/template.yml` to control exactly which files are copied.
770
+
771
+ ## Acknowledgments
772
+
773
+ Rhiza is developed and maintained by the Jebel Quant team as part of their effort to standardize Python project configurations across their portfolio.