rhiza 0.8.3__py3-none-any.whl → 0.8.5__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.
- rhiza/__main__.py +22 -0
- rhiza/commands/init.py +213 -162
- rhiza/commands/materialize.py +328 -267
- rhiza/commands/migrate.py +99 -46
- rhiza/commands/uninstall.py +136 -57
- rhiza/commands/validate.py +182 -71
- rhiza/subprocess_utils.py +26 -0
- {rhiza-0.8.3.dist-info → rhiza-0.8.5.dist-info}/METADATA +8 -10
- rhiza-0.8.5.dist-info/RECORD +20 -0
- rhiza-0.8.3.dist-info/RECORD +0 -19
- {rhiza-0.8.3.dist-info → rhiza-0.8.5.dist-info}/WHEEL +0 -0
- {rhiza-0.8.3.dist-info → rhiza-0.8.5.dist-info}/entry_points.txt +0 -0
- {rhiza-0.8.3.dist-info → rhiza-0.8.5.dist-info}/licenses/LICENSE +0 -0
rhiza/commands/validate.py
CHANGED
|
@@ -10,37 +10,28 @@ import yaml
|
|
|
10
10
|
from loguru import logger
|
|
11
11
|
|
|
12
12
|
|
|
13
|
-
def
|
|
14
|
-
"""
|
|
15
|
-
|
|
16
|
-
Performs authoritative validation of the template configuration:
|
|
17
|
-
- Checks if target is a git repository
|
|
18
|
-
- Checks for standard project structure (src and tests folders)
|
|
19
|
-
- Checks for pyproject.toml (required)
|
|
20
|
-
- Checks if template.yml exists
|
|
21
|
-
- Validates YAML syntax
|
|
22
|
-
- Validates required fields
|
|
23
|
-
- Validates field values are appropriate
|
|
13
|
+
def _check_git_repository(target: Path) -> bool:
|
|
14
|
+
"""Check if target is a git repository.
|
|
24
15
|
|
|
25
16
|
Args:
|
|
26
|
-
target: Path to
|
|
17
|
+
target: Path to check.
|
|
27
18
|
|
|
28
19
|
Returns:
|
|
29
|
-
True if
|
|
20
|
+
True if valid git repository, False otherwise.
|
|
30
21
|
"""
|
|
31
|
-
# Convert to absolute path to avoid path resolution issues
|
|
32
|
-
target = target.resolve()
|
|
33
|
-
|
|
34
|
-
# Check if target is a git repository by looking for .git directory
|
|
35
|
-
# Rhiza only works with git repositories
|
|
36
22
|
if not (target / ".git").is_dir():
|
|
37
23
|
logger.error(f"Target directory is not a git repository: {target}")
|
|
38
24
|
logger.error("Initialize a git repository with 'git init' first")
|
|
39
25
|
return False
|
|
26
|
+
return True
|
|
40
27
|
|
|
41
|
-
logger.info(f"Validating template configuration in: {target}")
|
|
42
28
|
|
|
43
|
-
|
|
29
|
+
def _check_project_structure(target: Path) -> None:
|
|
30
|
+
"""Check for standard project structure.
|
|
31
|
+
|
|
32
|
+
Args:
|
|
33
|
+
target: Path to project.
|
|
34
|
+
"""
|
|
44
35
|
logger.debug("Validating project structure")
|
|
45
36
|
src_dir = target / "src"
|
|
46
37
|
tests_dir = target / "tests"
|
|
@@ -57,7 +48,16 @@ def validate(target: Path) -> bool:
|
|
|
57
48
|
else:
|
|
58
49
|
logger.success(f"'tests' folder exists: {tests_dir}")
|
|
59
50
|
|
|
60
|
-
|
|
51
|
+
|
|
52
|
+
def _check_pyproject_toml(target: Path) -> bool:
|
|
53
|
+
"""Check for pyproject.toml file.
|
|
54
|
+
|
|
55
|
+
Args:
|
|
56
|
+
target: Path to project.
|
|
57
|
+
|
|
58
|
+
Returns:
|
|
59
|
+
True if pyproject.toml exists, False otherwise.
|
|
60
|
+
"""
|
|
61
61
|
logger.debug("Validating pyproject.toml")
|
|
62
62
|
pyproject_file = target / "pyproject.toml"
|
|
63
63
|
|
|
@@ -68,8 +68,18 @@ def validate(target: Path) -> bool:
|
|
|
68
68
|
return False
|
|
69
69
|
else:
|
|
70
70
|
logger.success(f"pyproject.toml exists: {pyproject_file}")
|
|
71
|
+
return True
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def _check_template_file_exists(target: Path) -> tuple[bool, Path]:
|
|
75
|
+
"""Check if template file exists.
|
|
71
76
|
|
|
72
|
-
|
|
77
|
+
Args:
|
|
78
|
+
target: Path to project.
|
|
79
|
+
|
|
80
|
+
Returns:
|
|
81
|
+
Tuple of (exists, template_file_path).
|
|
82
|
+
"""
|
|
73
83
|
template_file = target / ".rhiza" / "template.yml"
|
|
74
84
|
|
|
75
85
|
if not template_file.exists():
|
|
@@ -82,11 +92,21 @@ def validate(target: Path) -> bool:
|
|
|
82
92
|
logger.info("")
|
|
83
93
|
logger.info("The 'rhiza migrate' command will move your configuration from")
|
|
84
94
|
logger.info(" .github/rhiza/template.yml → .rhiza/template.yml")
|
|
85
|
-
return False
|
|
95
|
+
return False, template_file
|
|
86
96
|
|
|
87
97
|
logger.success(f"Template file exists: {template_file.relative_to(target)}")
|
|
98
|
+
return True, template_file
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
def _parse_yaml_file(template_file: Path) -> tuple[bool, dict | None]:
|
|
102
|
+
"""Parse YAML file and return configuration.
|
|
88
103
|
|
|
89
|
-
|
|
104
|
+
Args:
|
|
105
|
+
template_file: Path to template file.
|
|
106
|
+
|
|
107
|
+
Returns:
|
|
108
|
+
Tuple of (success, config_dict).
|
|
109
|
+
"""
|
|
90
110
|
logger.debug(f"Parsing YAML file: {template_file}")
|
|
91
111
|
try:
|
|
92
112
|
with open(template_file) as f:
|
|
@@ -94,19 +114,26 @@ def validate(target: Path) -> bool:
|
|
|
94
114
|
except yaml.YAMLError as e:
|
|
95
115
|
logger.error(f"Invalid YAML syntax in template.yml: {e}")
|
|
96
116
|
logger.error("Fix the YAML syntax errors and try again")
|
|
97
|
-
return False
|
|
117
|
+
return False, None
|
|
98
118
|
|
|
99
|
-
# Check if the file is completely empty
|
|
100
119
|
if config is None:
|
|
101
120
|
logger.error("template.yml is empty")
|
|
102
121
|
logger.error("Add configuration to template.yml or run 'rhiza init' to generate defaults")
|
|
103
|
-
return False
|
|
122
|
+
return False, None
|
|
104
123
|
|
|
105
124
|
logger.success("YAML syntax is valid")
|
|
125
|
+
return True, config
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
def _validate_required_fields(config: dict) -> bool:
|
|
129
|
+
"""Validate required fields exist and have correct types.
|
|
106
130
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
131
|
+
Args:
|
|
132
|
+
config: Configuration dictionary.
|
|
133
|
+
|
|
134
|
+
Returns:
|
|
135
|
+
True if all validations pass, False otherwise.
|
|
136
|
+
"""
|
|
110
137
|
logger.debug("Validating required fields")
|
|
111
138
|
required_fields = {
|
|
112
139
|
"template-repository": str,
|
|
@@ -115,7 +142,6 @@ def validate(target: Path) -> bool:
|
|
|
115
142
|
|
|
116
143
|
validation_passed = True
|
|
117
144
|
|
|
118
|
-
# Check each required field
|
|
119
145
|
for field, expected_type in required_fields.items():
|
|
120
146
|
if field not in config:
|
|
121
147
|
logger.error(f"Missing required field: {field}")
|
|
@@ -130,47 +156,77 @@ def validate(target: Path) -> bool:
|
|
|
130
156
|
else:
|
|
131
157
|
logger.success(f"Field '{field}' is present and valid")
|
|
132
158
|
|
|
133
|
-
|
|
134
|
-
|
|
159
|
+
return validation_passed
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
def _validate_repository_format(config: dict) -> bool:
|
|
163
|
+
"""Validate template-repository format.
|
|
164
|
+
|
|
165
|
+
Args:
|
|
166
|
+
config: Configuration dictionary.
|
|
167
|
+
|
|
168
|
+
Returns:
|
|
169
|
+
True if valid, False otherwise.
|
|
170
|
+
"""
|
|
135
171
|
logger.debug("Validating template-repository format")
|
|
136
|
-
if "template-repository" in config:
|
|
137
|
-
|
|
138
|
-
if not isinstance(repo, str):
|
|
139
|
-
logger.error(f"template-repository must be a string, got {type(repo).__name__}")
|
|
140
|
-
logger.error("Example: 'owner/repository'")
|
|
141
|
-
validation_passed = False
|
|
142
|
-
elif "/" not in repo:
|
|
143
|
-
logger.error(f"template-repository must be in format 'owner/repo', got: {repo}")
|
|
144
|
-
logger.error("Example: 'jebel-quant/rhiza'")
|
|
145
|
-
validation_passed = False
|
|
146
|
-
else:
|
|
147
|
-
logger.success(f"template-repository format is valid: {repo}")
|
|
172
|
+
if "template-repository" not in config:
|
|
173
|
+
return True
|
|
148
174
|
|
|
149
|
-
|
|
150
|
-
|
|
175
|
+
repo = config["template-repository"]
|
|
176
|
+
if not isinstance(repo, str):
|
|
177
|
+
logger.error(f"template-repository must be a string, got {type(repo).__name__}")
|
|
178
|
+
logger.error("Example: 'owner/repository'")
|
|
179
|
+
return False
|
|
180
|
+
elif "/" not in repo:
|
|
181
|
+
logger.error(f"template-repository must be in format 'owner/repo', got: {repo}")
|
|
182
|
+
logger.error("Example: 'jebel-quant/rhiza'")
|
|
183
|
+
return False
|
|
184
|
+
else:
|
|
185
|
+
logger.success(f"template-repository format is valid: {repo}")
|
|
186
|
+
return True
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
def _validate_include_paths(config: dict) -> bool:
|
|
190
|
+
"""Validate include paths.
|
|
191
|
+
|
|
192
|
+
Args:
|
|
193
|
+
config: Configuration dictionary.
|
|
194
|
+
|
|
195
|
+
Returns:
|
|
196
|
+
True if valid, False otherwise.
|
|
197
|
+
"""
|
|
151
198
|
logger.debug("Validating include paths")
|
|
152
|
-
if "include" in config:
|
|
153
|
-
|
|
154
|
-
if not isinstance(include, list):
|
|
155
|
-
logger.error(f"include must be a list, got {type(include).__name__}")
|
|
156
|
-
logger.error("Example: include: ['.github', '.gitignore']")
|
|
157
|
-
validation_passed = False
|
|
158
|
-
elif len(include) == 0:
|
|
159
|
-
logger.error("include list cannot be empty")
|
|
160
|
-
logger.error("Add at least one path to materialize")
|
|
161
|
-
validation_passed = False
|
|
162
|
-
else:
|
|
163
|
-
logger.success(f"include list has {len(include)} path(s)")
|
|
164
|
-
# Log each included path for transparency
|
|
165
|
-
for path in include:
|
|
166
|
-
if not isinstance(path, str):
|
|
167
|
-
logger.warning(f"include path should be a string, got {type(path).__name__}: {path}")
|
|
168
|
-
else:
|
|
169
|
-
logger.info(f" - {path}")
|
|
199
|
+
if "include" not in config:
|
|
200
|
+
return True
|
|
170
201
|
|
|
171
|
-
|
|
172
|
-
|
|
202
|
+
include = config["include"]
|
|
203
|
+
if not isinstance(include, list):
|
|
204
|
+
logger.error(f"include must be a list, got {type(include).__name__}")
|
|
205
|
+
logger.error("Example: include: ['.github', '.gitignore']")
|
|
206
|
+
return False
|
|
207
|
+
elif len(include) == 0:
|
|
208
|
+
logger.error("include list cannot be empty")
|
|
209
|
+
logger.error("Add at least one path to materialize")
|
|
210
|
+
return False
|
|
211
|
+
else:
|
|
212
|
+
logger.success(f"include list has {len(include)} path(s)")
|
|
213
|
+
for path in include:
|
|
214
|
+
if not isinstance(path, str):
|
|
215
|
+
logger.warning(f"include path should be a string, got {type(path).__name__}: {path}")
|
|
216
|
+
else:
|
|
217
|
+
logger.info(f" - {path}")
|
|
218
|
+
return True
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
def _validate_optional_fields(config: dict) -> None:
|
|
222
|
+
"""Validate optional fields if present.
|
|
223
|
+
|
|
224
|
+
Args:
|
|
225
|
+
config: Configuration dictionary.
|
|
226
|
+
"""
|
|
173
227
|
logger.debug("Validating optional fields")
|
|
228
|
+
|
|
229
|
+
# template-branch
|
|
174
230
|
if "template-branch" in config:
|
|
175
231
|
branch = config["template-branch"]
|
|
176
232
|
if not isinstance(branch, str):
|
|
@@ -179,7 +235,7 @@ def validate(target: Path) -> bool:
|
|
|
179
235
|
else:
|
|
180
236
|
logger.success(f"template-branch is valid: {branch}")
|
|
181
237
|
|
|
182
|
-
# template-host
|
|
238
|
+
# template-host
|
|
183
239
|
if "template-host" in config:
|
|
184
240
|
host = config["template-host"]
|
|
185
241
|
if not isinstance(host, str):
|
|
@@ -191,7 +247,7 @@ def validate(target: Path) -> bool:
|
|
|
191
247
|
else:
|
|
192
248
|
logger.success(f"template-host is valid: {host}")
|
|
193
249
|
|
|
194
|
-
# exclude
|
|
250
|
+
# exclude
|
|
195
251
|
if "exclude" in config:
|
|
196
252
|
exclude = config["exclude"]
|
|
197
253
|
if not isinstance(exclude, list):
|
|
@@ -199,14 +255,69 @@ def validate(target: Path) -> bool:
|
|
|
199
255
|
logger.warning("Example: exclude: ['.github/workflows/ci.yml']")
|
|
200
256
|
else:
|
|
201
257
|
logger.success(f"exclude list has {len(exclude)} path(s)")
|
|
202
|
-
# Log each excluded path for transparency
|
|
203
258
|
for path in exclude:
|
|
204
259
|
if not isinstance(path, str):
|
|
205
260
|
logger.warning(f"exclude path should be a string, got {type(path).__name__}: {path}")
|
|
206
261
|
else:
|
|
207
262
|
logger.info(f" - {path}")
|
|
208
263
|
|
|
209
|
-
|
|
264
|
+
|
|
265
|
+
def validate(target: Path) -> bool:
|
|
266
|
+
"""Validate template.yml configuration in the target repository.
|
|
267
|
+
|
|
268
|
+
Performs authoritative validation of the template configuration:
|
|
269
|
+
- Checks if target is a git repository
|
|
270
|
+
- Checks for standard project structure (src and tests folders)
|
|
271
|
+
- Checks for pyproject.toml (required)
|
|
272
|
+
- Checks if template.yml exists
|
|
273
|
+
- Validates YAML syntax
|
|
274
|
+
- Validates required fields
|
|
275
|
+
- Validates field values are appropriate
|
|
276
|
+
|
|
277
|
+
Args:
|
|
278
|
+
target: Path to the target Git repository directory.
|
|
279
|
+
|
|
280
|
+
Returns:
|
|
281
|
+
True if validation passes, False otherwise.
|
|
282
|
+
"""
|
|
283
|
+
target = target.resolve()
|
|
284
|
+
logger.info(f"Validating template configuration in: {target}")
|
|
285
|
+
|
|
286
|
+
# Check if target is a git repository
|
|
287
|
+
if not _check_git_repository(target):
|
|
288
|
+
return False
|
|
289
|
+
|
|
290
|
+
# Check for standard project structure
|
|
291
|
+
_check_project_structure(target)
|
|
292
|
+
|
|
293
|
+
# Check for pyproject.toml
|
|
294
|
+
if not _check_pyproject_toml(target):
|
|
295
|
+
return False
|
|
296
|
+
|
|
297
|
+
# Check for template file
|
|
298
|
+
exists, template_file = _check_template_file_exists(target)
|
|
299
|
+
if not exists:
|
|
300
|
+
return False
|
|
301
|
+
|
|
302
|
+
# Parse YAML file
|
|
303
|
+
success, config = _parse_yaml_file(template_file)
|
|
304
|
+
if not success or config is None:
|
|
305
|
+
return False
|
|
306
|
+
|
|
307
|
+
# Validate required fields
|
|
308
|
+
validation_passed = _validate_required_fields(config)
|
|
309
|
+
|
|
310
|
+
# Validate specific field formats
|
|
311
|
+
if not _validate_repository_format(config):
|
|
312
|
+
validation_passed = False
|
|
313
|
+
|
|
314
|
+
if not _validate_include_paths(config):
|
|
315
|
+
validation_passed = False
|
|
316
|
+
|
|
317
|
+
# Validate optional fields
|
|
318
|
+
_validate_optional_fields(config)
|
|
319
|
+
|
|
320
|
+
# Final verdict
|
|
210
321
|
logger.debug("Validation complete, determining final result")
|
|
211
322
|
if validation_passed:
|
|
212
323
|
logger.success("✓ Validation passed: template.yml is valid")
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"""Utilities for secure subprocess execution.
|
|
2
|
+
|
|
3
|
+
This module provides helper functions to resolve executable paths
|
|
4
|
+
to prevent PATH manipulation security vulnerabilities.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import shutil
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def get_git_executable() -> str:
|
|
11
|
+
"""Get the absolute path to the git executable.
|
|
12
|
+
|
|
13
|
+
This function ensures we use the full path to git to prevent
|
|
14
|
+
security issues related to PATH manipulation.
|
|
15
|
+
|
|
16
|
+
Returns:
|
|
17
|
+
str: Absolute path to the git executable.
|
|
18
|
+
|
|
19
|
+
Raises:
|
|
20
|
+
RuntimeError: If git executable is not found in PATH.
|
|
21
|
+
"""
|
|
22
|
+
git_path = shutil.which("git")
|
|
23
|
+
if git_path is None:
|
|
24
|
+
msg = "git executable not found in PATH. Please ensure git is installed and available."
|
|
25
|
+
raise RuntimeError(msg)
|
|
26
|
+
return git_path
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: rhiza
|
|
3
|
-
Version: 0.8.
|
|
3
|
+
Version: 0.8.5
|
|
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
|
|
@@ -23,26 +23,24 @@ Requires-Dist: jinja2>=3.1.0
|
|
|
23
23
|
Requires-Dist: loguru>=0.7.3
|
|
24
24
|
Requires-Dist: pyyaml==6.0.3
|
|
25
25
|
Requires-Dist: typer>=0.20.0
|
|
26
|
-
Provides-Extra: dev
|
|
27
|
-
Requires-Dist: marimo==0.18.4; extra == 'dev'
|
|
28
|
-
Requires-Dist: pdoc>=16.0.0; extra == 'dev'
|
|
29
|
-
Requires-Dist: pre-commit==4.5.1; extra == 'dev'
|
|
30
|
-
Requires-Dist: pytest-cov>=7.0.0; extra == 'dev'
|
|
31
|
-
Requires-Dist: pytest-html>=4.1.1; extra == 'dev'
|
|
32
|
-
Requires-Dist: pytest==9.0.2; extra == 'dev'
|
|
33
26
|
Description-Content-Type: text/markdown
|
|
34
27
|
|
|
35
|
-
|
|
28
|
+
<div align="center">
|
|
29
|
+
|
|
30
|
+
# <img src="https://raw.githubusercontent.com/Jebel-Quant/rhiza/main/assets/rhiza-logo.svg" alt="Rhiza Logo" width="30" style="vertical-align: middle;"> rhiza-cli
|
|
31
|
+

|
|
36
32
|
|
|
37
33
|
[](https://www.python.org/downloads/)
|
|
38
34
|
[](https://opensource.org/licenses/MIT)
|
|
39
35
|
[](https://pypi.org/project/rhiza/)
|
|
40
|
-
[](https://jebel-quant.github.io/rhiza-cli/tests/html-coverage/index.html)
|
|
41
37
|
[](https://pepy.tech/project/rhiza)
|
|
38
|
+
[](https://www.codefactor.io/repository/github/jebel-quant/rhiza-cli)
|
|
42
39
|
|
|
43
40
|
Command-line interface for managing reusable configuration templates for modern Python projects.
|
|
44
41
|
|
|
45
42
|
**📖 New to Rhiza? Check out the [Getting Started Guide](GETTING_STARTED.md) for a beginner-friendly introduction!**
|
|
43
|
+
</div>
|
|
46
44
|
|
|
47
45
|
## Overview
|
|
48
46
|
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
rhiza/__init__.py,sha256=iW3niLBjwRKxcMhIV_1eb78putjUTo2tbZsadofluJk,1939
|
|
2
|
+
rhiza/__main__.py,sha256=Q02upTGaJceknkDABdCwq5_vdMdGY8Cg3ej6WZIHs_s,829
|
|
3
|
+
rhiza/cli.py,sha256=xIsyfKjSFjVLjCS7o2om5o_YLZx9lIhsI0MTMI5Zs2k,8594
|
|
4
|
+
rhiza/models.py,sha256=fW9lofkkid-bghk2bXEgBdGbZ4scSqG726fMrVfKX_M,3454
|
|
5
|
+
rhiza/subprocess_utils.py,sha256=Pr5TysIKP76hc64fmqhTd6msMGn5DU43hOSR_v_GFb8,745
|
|
6
|
+
rhiza/_templates/basic/__init__.py.jinja2,sha256=gs8qN4LAKcdFd6iO9gZVLuVetODmZP_TGuEjWrbinC0,27
|
|
7
|
+
rhiza/_templates/basic/main.py.jinja2,sha256=uTCahxf9Bftao1IghHue4cSZ9YzBYmBEXeIhEmK9UXQ,362
|
|
8
|
+
rhiza/_templates/basic/pyproject.toml.jinja2,sha256=Mizpnnd_kFQd-pCWOxG-KWhvg4_ZhZaQppTt2pz0WOc,695
|
|
9
|
+
rhiza/commands/__init__.py,sha256=Z5CeMh7ylX27H6dvwqRbEKzYo5pwQq-5TyTxABUSaQg,1848
|
|
10
|
+
rhiza/commands/init.py,sha256=73MLPLp-M8U4fP8J5RXghS6FsZjx2PpeeBbKRZvLQ7U,8882
|
|
11
|
+
rhiza/commands/materialize.py,sha256=CgT6x1huRCWKrRQ_-YUoRFGHSB_mpt6M6shObKna_rY,17716
|
|
12
|
+
rhiza/commands/migrate.py,sha256=pT8izKuX2eXCAkmNfcy4AU5HTB1DoOZoBXcZo2AOpXs,7520
|
|
13
|
+
rhiza/commands/uninstall.py,sha256=MJbQtmdTgbzMvQz0gGLW3aw6S1dSV8nLv0SqWSDpyPk,7469
|
|
14
|
+
rhiza/commands/validate.py,sha256=pg7SpgavvrjDyuZIphJ_GOMnXkwdVs9WtL2caa1XjcM,10811
|
|
15
|
+
rhiza/commands/welcome.py,sha256=w3BziR042o6oYincd3EqDsFzF6qqInU7iYhWjF3yJqY,2382
|
|
16
|
+
rhiza-0.8.5.dist-info/METADATA,sha256=97aC7M8n0EQ8EWZmNCIEGe2465TyPmJhwTpBUPn-nGo,25321
|
|
17
|
+
rhiza-0.8.5.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
18
|
+
rhiza-0.8.5.dist-info/entry_points.txt,sha256=NAwZUpbXvfKv50a_Qq-PxMHl3lcjAyZO63IBeuUNgfY,45
|
|
19
|
+
rhiza-0.8.5.dist-info/licenses/LICENSE,sha256=4m5X7LhqX-6D0Ks79Ys8CLpmza8cxDG34g4S9XSNAGY,1077
|
|
20
|
+
rhiza-0.8.5.dist-info/RECORD,,
|
rhiza-0.8.3.dist-info/RECORD
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
rhiza/__init__.py,sha256=iW3niLBjwRKxcMhIV_1eb78putjUTo2tbZsadofluJk,1939
|
|
2
|
-
rhiza/__main__.py,sha256=Lx0GqVZo6ymm0f18_uYB6E7_SOWwJNYjb73Vr31oLoM,236
|
|
3
|
-
rhiza/cli.py,sha256=xIsyfKjSFjVLjCS7o2om5o_YLZx9lIhsI0MTMI5Zs2k,8594
|
|
4
|
-
rhiza/models.py,sha256=fW9lofkkid-bghk2bXEgBdGbZ4scSqG726fMrVfKX_M,3454
|
|
5
|
-
rhiza/_templates/basic/__init__.py.jinja2,sha256=gs8qN4LAKcdFd6iO9gZVLuVetODmZP_TGuEjWrbinC0,27
|
|
6
|
-
rhiza/_templates/basic/main.py.jinja2,sha256=uTCahxf9Bftao1IghHue4cSZ9YzBYmBEXeIhEmK9UXQ,362
|
|
7
|
-
rhiza/_templates/basic/pyproject.toml.jinja2,sha256=Mizpnnd_kFQd-pCWOxG-KWhvg4_ZhZaQppTt2pz0WOc,695
|
|
8
|
-
rhiza/commands/__init__.py,sha256=Z5CeMh7ylX27H6dvwqRbEKzYo5pwQq-5TyTxABUSaQg,1848
|
|
9
|
-
rhiza/commands/init.py,sha256=sSNLtERaBXLrZ1g6fe78yk5VVTXcAO4YiyAQdVD5I4A,9636
|
|
10
|
-
rhiza/commands/materialize.py,sha256=AbVXJrR8faa3t7m_Xl5TR8VE3ODmkh2oiAwCYFA36wA,17343
|
|
11
|
-
rhiza/commands/migrate.py,sha256=hhSkj2iafCCxKrrVOfnPWDjK7fTJ5ReAJsWNDGz71s0,6307
|
|
12
|
-
rhiza/commands/uninstall.py,sha256=z95xqamV7wGPr8PBveWzaRmtD5bPhOrTLI0GcOvpnAo,5371
|
|
13
|
-
rhiza/commands/validate.py,sha256=1HMQWF9Syv7JKC31AkaPYMTnqy8HOvAMxMLrYty36FQ,9112
|
|
14
|
-
rhiza/commands/welcome.py,sha256=w3BziR042o6oYincd3EqDsFzF6qqInU7iYhWjF3yJqY,2382
|
|
15
|
-
rhiza-0.8.3.dist-info/METADATA,sha256=KCV-nTc54f3k5cix84ldW355IF_LX2tdwxImgZebg9c,25156
|
|
16
|
-
rhiza-0.8.3.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
17
|
-
rhiza-0.8.3.dist-info/entry_points.txt,sha256=NAwZUpbXvfKv50a_Qq-PxMHl3lcjAyZO63IBeuUNgfY,45
|
|
18
|
-
rhiza-0.8.3.dist-info/licenses/LICENSE,sha256=4m5X7LhqX-6D0Ks79Ys8CLpmza8cxDG34g4S9XSNAGY,1077
|
|
19
|
-
rhiza-0.8.3.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|