rhiza 0.5.4__tar.gz → 0.5.6__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.5.4 → rhiza-0.5.6}/PKG-INFO +1 -1
- {rhiza-0.5.4 → rhiza-0.5.6}/pyproject.toml +1 -1
- {rhiza-0.5.4 → rhiza-0.5.6}/src/rhiza/cli.py +15 -0
- {rhiza-0.5.4 → rhiza-0.5.6}/src/rhiza/commands/materialize.py +76 -43
- rhiza-0.5.6/src/rhiza/commands/welcome.py +55 -0
- {rhiza-0.5.4 → rhiza-0.5.6}/tests/test_cli_commands.py +32 -62
- {rhiza-0.5.4 → rhiza-0.5.6}/uv.lock +1 -1
- {rhiza-0.5.4 → rhiza-0.5.6}/.editorconfig +0 -0
- {rhiza-0.5.4 → rhiza-0.5.6}/.github/README.md +0 -0
- {rhiza-0.5.4 → rhiza-0.5.6}/.github/TOKEN_SETUP.md +0 -0
- {rhiza-0.5.4 → rhiza-0.5.6}/.github/actions/setup-project/action.yml +0 -0
- {rhiza-0.5.4 → rhiza-0.5.6}/.github/copilot-instructions.md +0 -0
- {rhiza-0.5.4 → rhiza-0.5.6}/.github/renovate.json +0 -0
- {rhiza-0.5.4 → rhiza-0.5.6}/.github/scripts/book.sh +0 -0
- {rhiza-0.5.4 → rhiza-0.5.6}/.github/scripts/bump.sh +0 -0
- {rhiza-0.5.4 → rhiza-0.5.6}/.github/scripts/customisations/build-extras.sh +0 -0
- {rhiza-0.5.4 → rhiza-0.5.6}/.github/scripts/customisations/post-release.sh +0 -0
- {rhiza-0.5.4 → rhiza-0.5.6}/.github/scripts/marimushka.sh +0 -0
- {rhiza-0.5.4 → rhiza-0.5.6}/.github/scripts/release.sh +0 -0
- {rhiza-0.5.4 → rhiza-0.5.6}/.github/scripts/update-readme-help.sh +0 -0
- {rhiza-0.5.4 → rhiza-0.5.6}/.github/template.yml +0 -0
- {rhiza-0.5.4 → rhiza-0.5.6}/.github/workflows/book.yml +0 -0
- {rhiza-0.5.4 → rhiza-0.5.6}/.github/workflows/ci.yml +0 -0
- {rhiza-0.5.4 → rhiza-0.5.6}/.github/workflows/deptry.yml +0 -0
- {rhiza-0.5.4 → rhiza-0.5.6}/.github/workflows/marimo.yml +0 -0
- {rhiza-0.5.4 → rhiza-0.5.6}/.github/workflows/pre-commit.yml +0 -0
- {rhiza-0.5.4 → rhiza-0.5.6}/.github/workflows/release.yml +0 -0
- {rhiza-0.5.4 → rhiza-0.5.6}/.github/workflows/scripts/version_matrix.py +0 -0
- {rhiza-0.5.4 → rhiza-0.5.6}/.github/workflows/scripts/version_max.py +0 -0
- {rhiza-0.5.4 → rhiza-0.5.6}/.github/workflows/structure.yml +0 -0
- {rhiza-0.5.4 → rhiza-0.5.6}/.github/workflows/sym2.yml +0 -0
- {rhiza-0.5.4 → rhiza-0.5.6}/.github/workflows/sync.yml +0 -0
- {rhiza-0.5.4 → rhiza-0.5.6}/.gitignore +0 -0
- {rhiza-0.5.4 → rhiza-0.5.6}/.pre-commit-config.yaml +0 -0
- {rhiza-0.5.4 → rhiza-0.5.6}/.rhiza.history +0 -0
- {rhiza-0.5.4 → rhiza-0.5.6}/CLI.md +0 -0
- {rhiza-0.5.4 → rhiza-0.5.6}/CODE_OF_CONDUCT.md +0 -0
- {rhiza-0.5.4 → rhiza-0.5.6}/CONTRIBUTING.md +0 -0
- {rhiza-0.5.4 → rhiza-0.5.6}/LICENSE +0 -0
- {rhiza-0.5.4 → rhiza-0.5.6}/Makefile +0 -0
- {rhiza-0.5.4 → rhiza-0.5.6}/README.md +0 -0
- {rhiza-0.5.4 → rhiza-0.5.6}/USAGE.md +0 -0
- {rhiza-0.5.4 → rhiza-0.5.6}/book/marimo/.gitkeep +0 -0
- {rhiza-0.5.4 → rhiza-0.5.6}/pytest.ini +0 -0
- {rhiza-0.5.4 → rhiza-0.5.6}/ruff.toml +0 -0
- {rhiza-0.5.4 → rhiza-0.5.6}/src/rhiza/__init__.py +0 -0
- {rhiza-0.5.4 → rhiza-0.5.6}/src/rhiza/__main__.py +0 -0
- {rhiza-0.5.4 → rhiza-0.5.6}/src/rhiza/commands/__init__.py +0 -0
- {rhiza-0.5.4 → rhiza-0.5.6}/src/rhiza/commands/init.py +0 -0
- {rhiza-0.5.4 → rhiza-0.5.6}/src/rhiza/commands/validate.py +0 -0
- {rhiza-0.5.4 → rhiza-0.5.6}/src/rhiza/models.py +0 -0
- {rhiza-0.5.4 → rhiza-0.5.6}/tests/test_commands/test_init.py +0 -0
- {rhiza-0.5.4 → rhiza-0.5.6}/tests/test_commands/test_materialize.py +0 -0
- {rhiza-0.5.4 → rhiza-0.5.6}/tests/test_commands/test_validate.py +0 -0
- {rhiza-0.5.4 → rhiza-0.5.6}/tests/test_models.py +0 -0
- {rhiza-0.5.4 → rhiza-0.5.6}/tests/test_package.py +0 -0
- {rhiza-0.5.4 → rhiza-0.5.6}/tests/test_rhiza/README.md +0 -0
- {rhiza-0.5.4 → rhiza-0.5.6}/tests/test_rhiza/conftest.py +0 -0
- {rhiza-0.5.4 → rhiza-0.5.6}/tests/test_rhiza/test_bump_script.py +0 -0
- {rhiza-0.5.4 → rhiza-0.5.6}/tests/test_rhiza/test_docstrings.py +0 -0
- {rhiza-0.5.4 → rhiza-0.5.6}/tests/test_rhiza/test_git_repo_fixture.py +0 -0
- {rhiza-0.5.4 → rhiza-0.5.6}/tests/test_rhiza/test_makefile.py +0 -0
- {rhiza-0.5.4 → rhiza-0.5.6}/tests/test_rhiza/test_marimushka_script.py +0 -0
- {rhiza-0.5.4 → rhiza-0.5.6}/tests/test_rhiza/test_readme.py +0 -0
- {rhiza-0.5.4 → rhiza-0.5.6}/tests/test_rhiza/test_release_script.py +0 -0
- {rhiza-0.5.4 → rhiza-0.5.6}/tests/test_rhiza/test_structure.py +0 -0
- {rhiza-0.5.4 → rhiza-0.5.6}/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.
|
|
3
|
+
Version: 0.5.6
|
|
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
|
|
@@ -12,6 +12,7 @@ from rhiza import __version__
|
|
|
12
12
|
from rhiza.commands import init as init_cmd
|
|
13
13
|
from rhiza.commands import materialize as materialize_cmd
|
|
14
14
|
from rhiza.commands import validate as validate_cmd
|
|
15
|
+
from rhiza.commands.welcome import welcome as welcome_cmd
|
|
15
16
|
|
|
16
17
|
app = typer.Typer(
|
|
17
18
|
help=(
|
|
@@ -171,3 +172,17 @@ def validate(
|
|
|
171
172
|
"""
|
|
172
173
|
if not validate_cmd(target):
|
|
173
174
|
raise typer.Exit(code=1)
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
@app.command()
|
|
178
|
+
def welcome():
|
|
179
|
+
r"""Display a friendly welcome message and explain what Rhiza is.
|
|
180
|
+
|
|
181
|
+
Shows a welcome message, explains Rhiza's purpose, key features,
|
|
182
|
+
and provides guidance on getting started with the tool.
|
|
183
|
+
|
|
184
|
+
\b
|
|
185
|
+
Examples:
|
|
186
|
+
rhiza welcome
|
|
187
|
+
"""
|
|
188
|
+
welcome_cmd()
|
|
@@ -6,6 +6,7 @@ into the target Git repository, and records managed files in
|
|
|
6
6
|
`.rhiza.history`. Use this to take a one-shot snapshot of template files.
|
|
7
7
|
"""
|
|
8
8
|
|
|
9
|
+
import os
|
|
9
10
|
import shutil
|
|
10
11
|
import subprocess
|
|
11
12
|
import sys
|
|
@@ -18,7 +19,7 @@ from rhiza.commands import init
|
|
|
18
19
|
from rhiza.models import RhizaTemplate
|
|
19
20
|
|
|
20
21
|
|
|
21
|
-
def
|
|
22
|
+
def __expand_paths(base_dir: Path, paths: list[str]) -> list[Path]:
|
|
22
23
|
"""Expand files/directories relative to base_dir into a flat list of files.
|
|
23
24
|
|
|
24
25
|
Given a list of paths relative to ``base_dir``, return a flat list of all
|
|
@@ -40,26 +41,26 @@ def expand_paths(base_dir: Path, paths: list[str]) -> list[Path]:
|
|
|
40
41
|
def materialize(target: Path, branch: str, target_branch: str | None, force: bool) -> None:
|
|
41
42
|
"""Materialize Rhiza templates into the target repository.
|
|
42
43
|
|
|
43
|
-
This performs a sparse checkout of the template repository and copies
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
target_branch:
|
|
54
|
-
Optional branch name to create/checkout in target repository.
|
|
55
|
-
force:
|
|
56
|
-
Whether to overwrite existing files.
|
|
44
|
+
This performs a sparse checkout of the template repository and copies the
|
|
45
|
+
selected files into the target repository, recording all files under
|
|
46
|
+
template control in `.rhiza.history`.
|
|
47
|
+
|
|
48
|
+
Args:
|
|
49
|
+
target (Path): Path to the target repository.
|
|
50
|
+
branch (str): The Rhiza template branch to use.
|
|
51
|
+
target_branch (str | None): Optional branch name to create/checkout in
|
|
52
|
+
the target repository.
|
|
53
|
+
force (bool): Whether to overwrite existing files.
|
|
57
54
|
"""
|
|
58
55
|
target = target.resolve()
|
|
59
56
|
|
|
60
57
|
logger.info(f"Target repository: {target}")
|
|
61
58
|
logger.info(f"Rhiza branch: {branch}")
|
|
62
59
|
|
|
60
|
+
# Set environment to prevent git from prompting for credentials
|
|
61
|
+
git_env = os.environ.copy()
|
|
62
|
+
git_env["GIT_TERMINAL_PROMPT"] = "0"
|
|
63
|
+
|
|
63
64
|
# -----------------------
|
|
64
65
|
# Handle target branch creation/checkout if specified
|
|
65
66
|
# -----------------------
|
|
@@ -72,6 +73,7 @@ def materialize(target: Path, branch: str, target_branch: str | None, force: boo
|
|
|
72
73
|
cwd=target,
|
|
73
74
|
capture_output=True,
|
|
74
75
|
text=True,
|
|
76
|
+
env=git_env,
|
|
75
77
|
)
|
|
76
78
|
|
|
77
79
|
if result.returncode == 0:
|
|
@@ -81,6 +83,7 @@ def materialize(target: Path, branch: str, target_branch: str | None, force: boo
|
|
|
81
83
|
["git", "checkout", target_branch],
|
|
82
84
|
cwd=target,
|
|
83
85
|
check=True,
|
|
86
|
+
env=git_env,
|
|
84
87
|
)
|
|
85
88
|
else:
|
|
86
89
|
# Branch doesn't exist, create and checkout
|
|
@@ -89,6 +92,7 @@ def materialize(target: Path, branch: str, target_branch: str | None, force: boo
|
|
|
89
92
|
["git", "checkout", "-b", target_branch],
|
|
90
93
|
cwd=target,
|
|
91
94
|
check=True,
|
|
95
|
+
env=git_env,
|
|
92
96
|
)
|
|
93
97
|
except subprocess.CalledProcessError as e:
|
|
94
98
|
logger.error(f"Failed to create/checkout branch '{target_branch}': {e}")
|
|
@@ -138,41 +142,70 @@ def materialize(target: Path, branch: str, target_branch: str | None, force: boo
|
|
|
138
142
|
logger.info(f"Cloning {rhiza_repo}@{rhiza_branch} from {rhiza_host} into temporary directory")
|
|
139
143
|
|
|
140
144
|
try:
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
145
|
+
# Clone the repository - capture output to avoid blocking
|
|
146
|
+
try:
|
|
147
|
+
subprocess.run(
|
|
148
|
+
[
|
|
149
|
+
"git",
|
|
150
|
+
"clone",
|
|
151
|
+
"--depth",
|
|
152
|
+
"1",
|
|
153
|
+
"--filter=blob:none",
|
|
154
|
+
"--sparse",
|
|
155
|
+
"--branch",
|
|
156
|
+
rhiza_branch,
|
|
157
|
+
git_url,
|
|
158
|
+
str(tmp_dir),
|
|
159
|
+
],
|
|
160
|
+
check=True,
|
|
161
|
+
capture_output=True,
|
|
162
|
+
text=True,
|
|
163
|
+
env=git_env,
|
|
164
|
+
)
|
|
165
|
+
except subprocess.CalledProcessError as e:
|
|
166
|
+
logger.error(f"Failed to clone repository: {e}")
|
|
167
|
+
if e.stderr:
|
|
168
|
+
logger.error(f"Git error: {e.stderr.strip()}")
|
|
169
|
+
raise
|
|
157
170
|
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
171
|
+
# Initialize sparse checkout
|
|
172
|
+
try:
|
|
173
|
+
subprocess.run(
|
|
174
|
+
["git", "sparse-checkout", "init", "--cone"],
|
|
175
|
+
cwd=tmp_dir,
|
|
176
|
+
check=True,
|
|
177
|
+
capture_output=True,
|
|
178
|
+
text=True,
|
|
179
|
+
env=git_env,
|
|
180
|
+
)
|
|
181
|
+
except subprocess.CalledProcessError as e:
|
|
182
|
+
logger.error(f"Failed to initialize sparse checkout: {e}")
|
|
183
|
+
if e.stderr:
|
|
184
|
+
logger.error(f"Git error: {e.stderr.strip()}")
|
|
185
|
+
raise
|
|
163
186
|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
187
|
+
# Set sparse checkout paths
|
|
188
|
+
try:
|
|
189
|
+
subprocess.run(
|
|
190
|
+
["git", "sparse-checkout", "set", "--skip-checks", *include_paths],
|
|
191
|
+
cwd=tmp_dir,
|
|
192
|
+
check=True,
|
|
193
|
+
capture_output=True,
|
|
194
|
+
text=True,
|
|
195
|
+
env=git_env,
|
|
196
|
+
)
|
|
197
|
+
except subprocess.CalledProcessError as e:
|
|
198
|
+
logger.error(f"Failed to set sparse checkout paths: {e}")
|
|
199
|
+
if e.stderr:
|
|
200
|
+
logger.error(f"Git error: {e.stderr.strip()}")
|
|
201
|
+
raise
|
|
169
202
|
|
|
170
203
|
# -----------------------
|
|
171
204
|
# Expand include/exclude paths
|
|
172
205
|
# -----------------------
|
|
173
|
-
all_files =
|
|
206
|
+
all_files = __expand_paths(tmp_dir, include_paths)
|
|
174
207
|
|
|
175
|
-
excluded_files = {f.resolve() for f in
|
|
208
|
+
excluded_files = {f.resolve() for f in __expand_paths(tmp_dir, excluded_paths)}
|
|
176
209
|
|
|
177
210
|
files_to_copy = [f for f in all_files if f.resolve() not in excluded_files]
|
|
178
211
|
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# This file is part of the jebel-quant/rhiza repository
|
|
2
|
+
# (https://github.com/jebel-quant/rhiza).
|
|
3
|
+
#
|
|
4
|
+
"""Command to display a welcome message and explain Rhiza.
|
|
5
|
+
|
|
6
|
+
This module provides the welcome command that displays a friendly greeting
|
|
7
|
+
and explains what Rhiza is and how it can help manage configuration templates.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from rhiza import __version__
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def welcome():
|
|
14
|
+
"""Display a welcome message and explain what Rhiza is.
|
|
15
|
+
|
|
16
|
+
Shows a friendly greeting, explains Rhiza's purpose, and provides
|
|
17
|
+
next steps for getting started with the tool.
|
|
18
|
+
"""
|
|
19
|
+
welcome_message = f"""
|
|
20
|
+
╭───────────────────────────────────────────────────────────────╮
|
|
21
|
+
│ │
|
|
22
|
+
│ 🌿 Welcome to Rhiza v{__version__:<43} │
|
|
23
|
+
│ │
|
|
24
|
+
╰───────────────────────────────────────────────────────────────╯
|
|
25
|
+
|
|
26
|
+
Rhiza helps you maintain consistent configuration across multiple
|
|
27
|
+
Python projects using reusable templates stored in a central repository.
|
|
28
|
+
|
|
29
|
+
✨ What Rhiza can do for you:
|
|
30
|
+
|
|
31
|
+
• Initialize projects with standard configuration templates
|
|
32
|
+
• Materialize (inject) templates into target repositories
|
|
33
|
+
• Validate template configurations
|
|
34
|
+
• Keep project configurations synchronized
|
|
35
|
+
|
|
36
|
+
🚀 Getting started:
|
|
37
|
+
|
|
38
|
+
1. Initialize a project:
|
|
39
|
+
$ rhiza init
|
|
40
|
+
|
|
41
|
+
2. Customize .github/template.yml to match your needs
|
|
42
|
+
|
|
43
|
+
3. Materialize templates into your project:
|
|
44
|
+
$ rhiza materialize
|
|
45
|
+
|
|
46
|
+
📚 Learn more:
|
|
47
|
+
|
|
48
|
+
• View all commands: rhiza --help
|
|
49
|
+
• Project repository: https://github.com/jebel-quant/rhiza-cli
|
|
50
|
+
• Documentation: https://jebel-quant.github.io/rhiza-cli/
|
|
51
|
+
|
|
52
|
+
Happy templating! 🎉
|
|
53
|
+
"""
|
|
54
|
+
|
|
55
|
+
print(welcome_message)
|
|
@@ -14,7 +14,6 @@ import typer
|
|
|
14
14
|
|
|
15
15
|
from rhiza import __version__
|
|
16
16
|
from rhiza.cli import version_callback
|
|
17
|
-
from rhiza.commands.materialize import expand_paths
|
|
18
17
|
|
|
19
18
|
|
|
20
19
|
class TestCliApp:
|
|
@@ -59,67 +58,6 @@ class TestCliApp:
|
|
|
59
58
|
version_callback(False) # Should not raise
|
|
60
59
|
|
|
61
60
|
|
|
62
|
-
class TestExpandPaths:
|
|
63
|
-
"""Tests for the expand_paths utility function."""
|
|
64
|
-
|
|
65
|
-
def test_expand_single_file(self, tmp_path):
|
|
66
|
-
"""Test expanding a single file path."""
|
|
67
|
-
test_file = tmp_path / "test.txt"
|
|
68
|
-
test_file.write_text("content")
|
|
69
|
-
|
|
70
|
-
result = expand_paths(tmp_path, ["test.txt"])
|
|
71
|
-
assert result == [test_file]
|
|
72
|
-
|
|
73
|
-
def test_expand_directory(self, tmp_path):
|
|
74
|
-
"""Test expanding a directory into all its files."""
|
|
75
|
-
test_dir = tmp_path / "dir"
|
|
76
|
-
test_dir.mkdir()
|
|
77
|
-
file1 = test_dir / "file1.txt"
|
|
78
|
-
file2 = test_dir / "file2.txt"
|
|
79
|
-
file1.write_text("content1")
|
|
80
|
-
file2.write_text("content2")
|
|
81
|
-
|
|
82
|
-
result = expand_paths(tmp_path, ["dir"])
|
|
83
|
-
assert len(result) == 2
|
|
84
|
-
assert file1 in result
|
|
85
|
-
assert file2 in result
|
|
86
|
-
|
|
87
|
-
def test_expand_nested_directory(self, tmp_path):
|
|
88
|
-
"""Test expanding a directory with nested subdirectories."""
|
|
89
|
-
test_dir = tmp_path / "dir"
|
|
90
|
-
sub_dir = test_dir / "subdir"
|
|
91
|
-
sub_dir.mkdir(parents=True)
|
|
92
|
-
file1 = test_dir / "file1.txt"
|
|
93
|
-
file2 = sub_dir / "file2.txt"
|
|
94
|
-
file1.write_text("content1")
|
|
95
|
-
file2.write_text("content2")
|
|
96
|
-
|
|
97
|
-
result = expand_paths(tmp_path, ["dir"])
|
|
98
|
-
assert len(result) == 2
|
|
99
|
-
assert file1 in result
|
|
100
|
-
assert file2 in result
|
|
101
|
-
|
|
102
|
-
def test_expand_nonexistent_path(self, tmp_path):
|
|
103
|
-
"""Test that nonexistent paths are skipped."""
|
|
104
|
-
result = expand_paths(tmp_path, ["nonexistent.txt"])
|
|
105
|
-
assert result == []
|
|
106
|
-
|
|
107
|
-
def test_expand_mixed_paths(self, tmp_path):
|
|
108
|
-
"""Test expanding a mix of files and directories."""
|
|
109
|
-
file1 = tmp_path / "file1.txt"
|
|
110
|
-
file1.write_text("content1")
|
|
111
|
-
|
|
112
|
-
test_dir = tmp_path / "dir"
|
|
113
|
-
test_dir.mkdir()
|
|
114
|
-
file2 = test_dir / "file2.txt"
|
|
115
|
-
file2.write_text("content2")
|
|
116
|
-
|
|
117
|
-
result = expand_paths(tmp_path, ["file1.txt", "dir"])
|
|
118
|
-
assert len(result) == 2
|
|
119
|
-
assert file1 in result
|
|
120
|
-
assert file2 in result
|
|
121
|
-
|
|
122
|
-
|
|
123
61
|
class TestMainEntry:
|
|
124
62
|
"""Tests for the __main__.py entry point."""
|
|
125
63
|
|
|
@@ -153,3 +91,35 @@ class TestMainEntry:
|
|
|
153
91
|
assert "rhiza" in captured.out.lower()
|
|
154
92
|
finally:
|
|
155
93
|
sys.argv = original_argv
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
class TestWelcomeCommand:
|
|
97
|
+
"""Tests for the welcome command."""
|
|
98
|
+
|
|
99
|
+
def test_welcome_command(self, capsys):
|
|
100
|
+
"""Test that the welcome command displays welcome message."""
|
|
101
|
+
result = subprocess.run(
|
|
102
|
+
[sys.executable, "-m", "rhiza", "welcome"],
|
|
103
|
+
capture_output=True,
|
|
104
|
+
text=True,
|
|
105
|
+
)
|
|
106
|
+
assert result.returncode == 0
|
|
107
|
+
output = result.stdout
|
|
108
|
+
|
|
109
|
+
# Check for key elements of the welcome message
|
|
110
|
+
assert "Welcome to Rhiza" in output
|
|
111
|
+
assert __version__ in output
|
|
112
|
+
assert "What Rhiza can do" in output
|
|
113
|
+
assert "Getting started" in output
|
|
114
|
+
assert "rhiza init" in output
|
|
115
|
+
assert "rhiza materialize" in output
|
|
116
|
+
|
|
117
|
+
def test_welcome_command_function_coverage(self, capsys):
|
|
118
|
+
"""Test the welcome command function directly for coverage."""
|
|
119
|
+
from rhiza.commands.welcome import welcome
|
|
120
|
+
|
|
121
|
+
welcome()
|
|
122
|
+
|
|
123
|
+
captured = capsys.readouterr()
|
|
124
|
+
assert "Welcome to Rhiza" in captured.out
|
|
125
|
+
assert __version__ in captured.out
|
|
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
|