env-module-manager 0.3.0__tar.gz → 0.4.0__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.
- {env_module_manager-0.3.0 → env_module_manager-0.4.0}/AGENTS.md +3 -0
- {env_module_manager-0.3.0 → env_module_manager-0.4.0}/PKG-INFO +17 -10
- {env_module_manager-0.3.0 → env_module_manager-0.4.0}/README.md +16 -9
- {env_module_manager-0.3.0 → env_module_manager-0.4.0}/docs/collective-environments.md +1 -0
- {env_module_manager-0.3.0 → env_module_manager-0.4.0}/docs/configuration.md +5 -0
- {env_module_manager-0.3.0 → env_module_manager-0.4.0}/docs/installation.md +9 -3
- {env_module_manager-0.3.0 → env_module_manager-0.4.0}/docs/python-tools.md +23 -0
- {env_module_manager-0.3.0 → env_module_manager-0.4.0}/docs/reference.md +1 -0
- {env_module_manager-0.3.0 → env_module_manager-0.4.0}/module_manager/__init__.py +1 -1
- {env_module_manager-0.3.0 → env_module_manager-0.4.0}/module_manager/cli.py +85 -9
- {env_module_manager-0.3.0 → env_module_manager-0.4.0}/module_manager/config.py +4 -0
- {env_module_manager-0.3.0 → env_module_manager-0.4.0}/module_manager/deploy.py +26 -4
- {env_module_manager-0.3.0 → env_module_manager-0.4.0}/pyproject.toml +1 -1
- {env_module_manager-0.3.0 → env_module_manager-0.4.0}/tests/test_cli.py +7 -0
- {env_module_manager-0.3.0 → env_module_manager-0.4.0}/tests/test_config.py +2 -0
- {env_module_manager-0.3.0 → env_module_manager-0.4.0}/tests/test_modulefile.py +27 -1
- {env_module_manager-0.3.0 → env_module_manager-0.4.0}/uv.lock +1 -1
- {env_module_manager-0.3.0 → env_module_manager-0.4.0}/.github/workflows/publish.yml +0 -0
- {env_module_manager-0.3.0 → env_module_manager-0.4.0}/.github/workflows/tag.yml +0 -0
- {env_module_manager-0.3.0 → env_module_manager-0.4.0}/.github/workflows/test.yml +0 -0
- {env_module_manager-0.3.0 → env_module_manager-0.4.0}/.gitignore +0 -0
- {env_module_manager-0.3.0 → env_module_manager-0.4.0}/.python-version +0 -0
- {env_module_manager-0.3.0 → env_module_manager-0.4.0}/.readthedocs.yaml +0 -0
- {env_module_manager-0.3.0 → env_module_manager-0.4.0}/CONTRIBUTING.md +0 -0
- {env_module_manager-0.3.0 → env_module_manager-0.4.0}/LICENSE.md +0 -0
- {env_module_manager-0.3.0 → env_module_manager-0.4.0}/docs/development.md +0 -0
- {env_module_manager-0.3.0 → env_module_manager-0.4.0}/docs/environment-modules.md +0 -0
- {env_module_manager-0.3.0 → env_module_manager-0.4.0}/docs/index.md +0 -0
- {env_module_manager-0.3.0 → env_module_manager-0.4.0}/docs/rust-tools.md +0 -0
- {env_module_manager-0.3.0 → env_module_manager-0.4.0}/docs/shell-tools.md +0 -0
- {env_module_manager-0.3.0 → env_module_manager-0.4.0}/docs/stylesheets/extra.css +0 -0
- {env_module_manager-0.3.0 → env_module_manager-0.4.0}/docs/uninstall.md +0 -0
- {env_module_manager-0.3.0 → env_module_manager-0.4.0}/example.bash +0 -0
- {env_module_manager-0.3.0 → env_module_manager-0.4.0}/mkdocs.yml +0 -0
- {env_module_manager-0.3.0 → env_module_manager-0.4.0}/module_manager/modulefile.py +0 -0
|
@@ -90,6 +90,9 @@ Common settings:
|
|
|
90
90
|
* `module_root` or `MODULE_MANAGER_MODULE_ROOT`
|
|
91
91
|
* `[python].indexes`, `MODULE_MANAGER_INDEX`, or `MODULE_MANAGER_INDEXES`
|
|
92
92
|
* `[python].find_links` or `MODULE_MANAGER_FIND_LINKS`
|
|
93
|
+
* `[python].uv_config_file` for the uv `--config-file` option. Do not add a
|
|
94
|
+
`MODULE_MANAGER_*` wrapper for this; users should use uv's `UV_CONFIG_FILE`
|
|
95
|
+
environment variable when they want environment-based uv configuration.
|
|
93
96
|
|
|
94
97
|
## Documentation
|
|
95
98
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: env-module-manager
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.4.0
|
|
4
4
|
Summary: Deploy Python, Rust, shell, and collective CLI environments behind GNU environment modulefiles
|
|
5
5
|
Project-URL: Homepage, https://github.com/ejb90/module-manager
|
|
6
6
|
Project-URL: Documentation, https://module-manager.readthedocs.io/
|
|
@@ -50,6 +50,20 @@ It writes tools and modulefiles into predictable versioned locations:
|
|
|
50
50
|
/prod/modulefiles/<name>/<version>
|
|
51
51
|
```
|
|
52
52
|
|
|
53
|
+
## Installation
|
|
54
|
+
|
|
55
|
+
Install from PyPI:
|
|
56
|
+
|
|
57
|
+
```sh
|
|
58
|
+
pip install env-module-manager
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Or install as a uv-managed tool:
|
|
62
|
+
|
|
63
|
+
```sh
|
|
64
|
+
uv tool install env-module-manager
|
|
65
|
+
```
|
|
66
|
+
|
|
53
67
|
## Quick Start
|
|
54
68
|
|
|
55
69
|
Deploy a Python CLI with `uv tool install`:
|
|
@@ -108,12 +122,5 @@ module-manager uninstall ruff 0.8.0 \
|
|
|
108
122
|
|
|
109
123
|
## Documentation
|
|
110
124
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
```sh
|
|
114
|
-
uv run mkdocs serve
|
|
115
|
-
```
|
|
116
|
-
|
|
117
|
-
Start with `docs/index.md` for installation, configuration, Python tools, Rust
|
|
118
|
-
tools, shell scripts, collective environments, uninstall, and local development
|
|
119
|
-
notes.
|
|
125
|
+
Read the full documentation on
|
|
126
|
+
[Read the Docs](https://module-manager.readthedocs.io/).
|
|
@@ -18,6 +18,20 @@ It writes tools and modulefiles into predictable versioned locations:
|
|
|
18
18
|
/prod/modulefiles/<name>/<version>
|
|
19
19
|
```
|
|
20
20
|
|
|
21
|
+
## Installation
|
|
22
|
+
|
|
23
|
+
Install from PyPI:
|
|
24
|
+
|
|
25
|
+
```sh
|
|
26
|
+
pip install env-module-manager
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Or install as a uv-managed tool:
|
|
30
|
+
|
|
31
|
+
```sh
|
|
32
|
+
uv tool install env-module-manager
|
|
33
|
+
```
|
|
34
|
+
|
|
21
35
|
## Quick Start
|
|
22
36
|
|
|
23
37
|
Deploy a Python CLI with `uv tool install`:
|
|
@@ -76,12 +90,5 @@ module-manager uninstall ruff 0.8.0 \
|
|
|
76
90
|
|
|
77
91
|
## Documentation
|
|
78
92
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
```sh
|
|
82
|
-
uv run mkdocs serve
|
|
83
|
-
```
|
|
84
|
-
|
|
85
|
-
Start with `docs/index.md` for installation, configuration, Python tools, Rust
|
|
86
|
-
tools, shell scripts, collective environments, uninstall, and local development
|
|
87
|
-
notes.
|
|
93
|
+
Read the full documentation on
|
|
94
|
+
[Read the Docs](https://module-manager.readthedocs.io/).
|
|
@@ -17,6 +17,7 @@ module_root = "/prod/modulefiles"
|
|
|
17
17
|
[python]
|
|
18
18
|
indexes = ["https://packages.example/simple"]
|
|
19
19
|
find_links = ["/prod/wheels"]
|
|
20
|
+
uv_config_file = "/prod/config/uv.toml"
|
|
20
21
|
```
|
|
21
22
|
|
|
22
23
|
Use a different config file with `--config`:
|
|
@@ -36,6 +37,10 @@ export MODULE_MANAGER_FIND_LINKS=/prod/wheels,/prod/more-wheels
|
|
|
36
37
|
|
|
37
38
|
`MODULE_MANAGER_CONFIG` can point to an alternate TOML config file.
|
|
38
39
|
|
|
40
|
+
There is no `MODULE_MANAGER_*` environment variable for uv configuration files.
|
|
41
|
+
Use uv's own `UV_CONFIG_FILE` environment variable when you want to set that via
|
|
42
|
+
the environment.
|
|
43
|
+
|
|
39
44
|
## CLI Precedence
|
|
40
45
|
|
|
41
46
|
CLI options override both environment variables and TOML config:
|
|
@@ -38,18 +38,24 @@ in every new shell.
|
|
|
38
38
|
|
|
39
39
|
## Install module-manager
|
|
40
40
|
|
|
41
|
-
From
|
|
41
|
+
From PyPI with pip:
|
|
42
42
|
|
|
43
43
|
```sh
|
|
44
|
-
|
|
44
|
+
pip install env-module-manager
|
|
45
45
|
```
|
|
46
46
|
|
|
47
|
-
|
|
47
|
+
As a uv-managed tool:
|
|
48
48
|
|
|
49
49
|
```sh
|
|
50
50
|
uv tool install env-module-manager
|
|
51
51
|
```
|
|
52
52
|
|
|
53
|
+
From a local checkout:
|
|
54
|
+
|
|
55
|
+
```sh
|
|
56
|
+
uv tool install .
|
|
57
|
+
```
|
|
58
|
+
|
|
53
59
|
During development, use:
|
|
54
60
|
|
|
55
61
|
```sh
|
|
@@ -51,6 +51,29 @@ module-manager deploy-python gitconductor 0.1.0 \
|
|
|
51
51
|
|
|
52
52
|
`--find-links` may be used more than once.
|
|
53
53
|
|
|
54
|
+
## Use a uv Config File
|
|
55
|
+
|
|
56
|
+
Pass a specific uv configuration file to `uv tool install`:
|
|
57
|
+
|
|
58
|
+
```sh
|
|
59
|
+
module-manager deploy-python internal-tool 1.2.3 \
|
|
60
|
+
--package internal-tool==1.2.3 \
|
|
61
|
+
--uv-config-file /prod/config/uv.toml \
|
|
62
|
+
--prefix /prod/tools \
|
|
63
|
+
--module-root /prod/modulefiles \
|
|
64
|
+
--execute-install
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
The same option can be set in the module-manager config file:
|
|
68
|
+
|
|
69
|
+
```toml
|
|
70
|
+
[python]
|
|
71
|
+
uv_config_file = "/prod/config/uv.toml"
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Use uv's own `UV_CONFIG_FILE` environment variable if you want to configure uv
|
|
75
|
+
through the environment.
|
|
76
|
+
|
|
54
77
|
## Deploy from VCS
|
|
55
78
|
|
|
56
79
|
`--package` is passed directly to `uv tool install`, so VCS package specs are
|
|
@@ -29,14 +29,61 @@ click.rich_click.STYLE_ARGUMENT = "bold yellow"
|
|
|
29
29
|
click.rich_click.STYLE_SWITCH = "bold magenta"
|
|
30
30
|
click.rich_click.STYLE_METAVAR = "yellow"
|
|
31
31
|
click.rich_click.HEADER_TEXT = "module-manager"
|
|
32
|
-
click.rich_click.FOOTER_TEXT = (
|
|
33
|
-
"Examples: [cyan]module-manager deploy-python ruff 0.8.0 --package "
|
|
34
|
-
"ruff==0.8.0 --prefix /prod/tools --module-root /prod/modulefiles[/cyan]"
|
|
35
|
-
)
|
|
36
32
|
|
|
37
33
|
PATH = click.Path(path_type=Path)
|
|
38
34
|
ClickCommand = TypeVar("ClickCommand", bound=Command)
|
|
39
35
|
|
|
36
|
+
TOP_LEVEL_EXAMPLES = (
|
|
37
|
+
"Examples:\n\n"
|
|
38
|
+
"[cyan]module-manager deploy-python ruff 0.8.0 --package ruff==0.8.0 "
|
|
39
|
+
"--prefix /prod/tools --module-root /prod/modulefiles[/cyan]\n\n"
|
|
40
|
+
"[cyan]module-manager deploy-rust ripgrep 14.1.1 --binary ./target/release/rg "
|
|
41
|
+
"--prefix /prod/tools --module-root /prod/modulefiles[/cyan]\n\n"
|
|
42
|
+
"[cyan]module-manager deploy-script my-tool 1.0.0 --script ./scripts/my-tool "
|
|
43
|
+
"--prefix /prod/tools --module-root /prod/modulefiles[/cyan]\n\n"
|
|
44
|
+
"[cyan]module-manager deploy-env --file dev-tools.toml[/cyan]\n\n"
|
|
45
|
+
"[cyan]module-manager uninstall ruff 0.8.0 --prefix /prod/tools --module-root /prod/modulefiles[/cyan]"
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
DEPLOY_PYTHON_EXAMPLES = (
|
|
49
|
+
"Examples:\n\n"
|
|
50
|
+
"[cyan]module-manager deploy-python ruff 0.8.0 --package ruff==0.8.0 "
|
|
51
|
+
"--prefix /prod/tools --module-root /prod/modulefiles --execute-install[/cyan]\n\n"
|
|
52
|
+
"[cyan]module-manager deploy-python internal-tool 1.2.3 --package internal-tool==1.2.3 "
|
|
53
|
+
"--uv-config-file /prod/config/uv.toml --prefix /prod/tools --module-root /prod/modulefiles[/cyan]"
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
DEPLOY_RUST_EXAMPLES = (
|
|
57
|
+
"Examples:\n\n"
|
|
58
|
+
"[cyan]module-manager deploy-rust ripgrep 14.1.1 --binary ./target/release/rg "
|
|
59
|
+
"--prefix /prod/tools --module-root /prod/modulefiles[/cyan]\n\n"
|
|
60
|
+
"[cyan]module-manager deploy-rust ripgrep 14.1.1 --binary ./target/release/rg "
|
|
61
|
+
"--prefix /prod/tools --module-root /prod/modulefiles --dry-run[/cyan]"
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
DEPLOY_SCRIPT_EXAMPLES = (
|
|
65
|
+
"Examples:\n\n"
|
|
66
|
+
"[cyan]module-manager deploy-script my-tool 1.0.0 --script ./scripts/my-tool "
|
|
67
|
+
"--prefix /prod/tools --module-root /prod/modulefiles[/cyan]\n\n"
|
|
68
|
+
"[cyan]module-manager deploy-script my-tool 1.0.0 --script ./scripts/my-tool "
|
|
69
|
+
"--prefix /prod/tools --module-root /prod/modulefiles --dry-run[/cyan]"
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
DEPLOY_ENV_EXAMPLES = (
|
|
73
|
+
"Examples:\n\n"
|
|
74
|
+
"[cyan]module-manager deploy-env --file dev-tools.toml[/cyan]\n\n"
|
|
75
|
+
"[cyan]module-manager deploy-env --file dev-tools.toml --prefix /scratch/tools "
|
|
76
|
+
"--module-root /scratch/modulefiles --dry-run[/cyan]"
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
UNINSTALL_EXAMPLES = (
|
|
80
|
+
"Examples:\n\n"
|
|
81
|
+
"[cyan]module-manager uninstall ruff 0.8.0 --prefix /prod/tools "
|
|
82
|
+
"--module-root /prod/modulefiles[/cyan]\n\n"
|
|
83
|
+
"[cyan]module-manager uninstall ruff 0.8.0 --prefix /prod/tools "
|
|
84
|
+
"--module-root /prod/modulefiles --dry-run[/cyan]"
|
|
85
|
+
)
|
|
86
|
+
|
|
40
87
|
|
|
41
88
|
def common_options(command: ClickCommand) -> ClickCommand:
|
|
42
89
|
"""Attach options shared by deployment commands.
|
|
@@ -108,6 +155,7 @@ def location_options(command: ClickCommand) -> ClickCommand:
|
|
|
108
155
|
"Build versioned modulefiles for Python tools, Rust binaries, shell scripts, "
|
|
109
156
|
"and collective environments."
|
|
110
157
|
),
|
|
158
|
+
epilog=TOP_LEVEL_EXAMPLES,
|
|
111
159
|
)
|
|
112
160
|
@click.version_option(__version__)
|
|
113
161
|
@click.option(
|
|
@@ -131,7 +179,11 @@ def main(ctx: click.Context, config: Path | None) -> None:
|
|
|
131
179
|
ctx.obj = load_config(config)
|
|
132
180
|
|
|
133
181
|
|
|
134
|
-
@main.command(
|
|
182
|
+
@main.command(
|
|
183
|
+
"deploy-python",
|
|
184
|
+
help="Write a modulefile for a uv tool install Python CLI.",
|
|
185
|
+
epilog=DEPLOY_PYTHON_EXAMPLES,
|
|
186
|
+
)
|
|
135
187
|
@common_options
|
|
136
188
|
@click.option("--package", "package", required=True, help="Package spec passed to uv tool install.")
|
|
137
189
|
@click.option("--python", "python", help="Python interpreter/version passed to uv.")
|
|
@@ -147,6 +199,11 @@ def main(ctx: click.Context, config: Path | None) -> None:
|
|
|
147
199
|
multiple=True,
|
|
148
200
|
help="Directory or HTML page of packages passed to uv. May be used more than once.",
|
|
149
201
|
)
|
|
202
|
+
@click.option(
|
|
203
|
+
"--uv-config-file",
|
|
204
|
+
type=PATH,
|
|
205
|
+
help="uv.toml file passed to uv tool install with --config-file.",
|
|
206
|
+
)
|
|
150
207
|
@click.option(
|
|
151
208
|
"--execute-install",
|
|
152
209
|
is_flag=True,
|
|
@@ -166,6 +223,7 @@ def deploy_python(
|
|
|
166
223
|
python: str | None,
|
|
167
224
|
indexes: tuple[str, ...],
|
|
168
225
|
find_links: tuple[str, ...],
|
|
226
|
+
uv_config_file: Path | None,
|
|
169
227
|
execute_install: bool,
|
|
170
228
|
) -> None:
|
|
171
229
|
"""Write a modulefile for a [cyan]uv tool install[/cyan] Python CLI.
|
|
@@ -183,6 +241,7 @@ def deploy_python(
|
|
|
183
241
|
python: Optional Python interpreter or version passed to uv.
|
|
184
242
|
indexes: Additional package index URLs passed to uv.
|
|
185
243
|
find_links: Wheelhouse directories or HTML package pages passed to uv.
|
|
244
|
+
uv_config_file: Optional uv configuration file passed to `uv tool`.
|
|
186
245
|
execute_install: Whether to run `uv tool install` immediately.
|
|
187
246
|
|
|
188
247
|
Raises:
|
|
@@ -204,6 +263,7 @@ def deploy_python(
|
|
|
204
263
|
python=python,
|
|
205
264
|
indexes=indexes or config.indexes,
|
|
206
265
|
find_links=find_links or config.find_links,
|
|
266
|
+
uv_config_file=(uv_config_file.expanduser() if uv_config_file else config.uv_config_file),
|
|
207
267
|
execute_install=execute_install,
|
|
208
268
|
make_default=make_default,
|
|
209
269
|
)
|
|
@@ -212,7 +272,11 @@ def deploy_python(
|
|
|
212
272
|
)
|
|
213
273
|
|
|
214
274
|
|
|
215
|
-
@main.command(
|
|
275
|
+
@main.command(
|
|
276
|
+
"deploy-rust",
|
|
277
|
+
help="Copy a Rust CLI binary and write a modulefile for it.",
|
|
278
|
+
epilog=DEPLOY_RUST_EXAMPLES,
|
|
279
|
+
)
|
|
216
280
|
@common_options
|
|
217
281
|
@click.option(
|
|
218
282
|
"--binary",
|
|
@@ -277,7 +341,11 @@ def deploy_rust(
|
|
|
277
341
|
)
|
|
278
342
|
|
|
279
343
|
|
|
280
|
-
@main.command(
|
|
344
|
+
@main.command(
|
|
345
|
+
"deploy-script",
|
|
346
|
+
help="Copy a shell script and write a modulefile for it.",
|
|
347
|
+
epilog=DEPLOY_SCRIPT_EXAMPLES,
|
|
348
|
+
)
|
|
281
349
|
@common_options
|
|
282
350
|
@click.option(
|
|
283
351
|
"--script",
|
|
@@ -341,7 +409,11 @@ def deploy_script(
|
|
|
341
409
|
)
|
|
342
410
|
|
|
343
411
|
|
|
344
|
-
@main.command(
|
|
412
|
+
@main.command(
|
|
413
|
+
"deploy-env",
|
|
414
|
+
help="Deploy a collective environment from a TOML manifest.",
|
|
415
|
+
epilog=DEPLOY_ENV_EXAMPLES,
|
|
416
|
+
)
|
|
345
417
|
@click.option(
|
|
346
418
|
"--file",
|
|
347
419
|
"manifest",
|
|
@@ -421,7 +493,11 @@ def deploy_env(
|
|
|
421
493
|
print_environment_result(result, dry_run)
|
|
422
494
|
|
|
423
495
|
|
|
424
|
-
@main.command(
|
|
496
|
+
@main.command(
|
|
497
|
+
"uninstall",
|
|
498
|
+
help="Remove a deployed tool version and its modulefile.",
|
|
499
|
+
epilog=UNINSTALL_EXAMPLES,
|
|
500
|
+
)
|
|
425
501
|
@location_options
|
|
426
502
|
@click.option(
|
|
427
503
|
"--keep-default",
|
|
@@ -22,12 +22,14 @@ class AppConfig:
|
|
|
22
22
|
indexes: Default Python package indexes passed to `uv tool install`.
|
|
23
23
|
find_links: Default Python package locations passed to
|
|
24
24
|
`uv tool install`.
|
|
25
|
+
uv_config_file: Default uv configuration file passed to `uv tool`.
|
|
25
26
|
"""
|
|
26
27
|
|
|
27
28
|
prefix: Path | None = None
|
|
28
29
|
module_root: Path | None = None
|
|
29
30
|
indexes: tuple[str, ...] = ()
|
|
30
31
|
find_links: tuple[str, ...] = ()
|
|
32
|
+
uv_config_file: Path | None = None
|
|
31
33
|
|
|
32
34
|
|
|
33
35
|
def default_config_path() -> Path:
|
|
@@ -81,6 +83,7 @@ def load_file_config(path: Path) -> AppConfig:
|
|
|
81
83
|
module_root=optional_path(data.get("module_root"), "module_root"),
|
|
82
84
|
indexes=string_tuple(python_data.get("indexes"), "python.indexes"),
|
|
83
85
|
find_links=string_tuple(python_data.get("find_links"), "python.find_links"),
|
|
86
|
+
uv_config_file=optional_path(python_data.get("uv_config_file"), "python.uv_config_file"),
|
|
84
87
|
)
|
|
85
88
|
|
|
86
89
|
|
|
@@ -98,6 +101,7 @@ def overlay_env_config(config: AppConfig) -> AppConfig:
|
|
|
98
101
|
module_root=env_path("MODULE_MANAGER_MODULE_ROOT") or config.module_root,
|
|
99
102
|
indexes=env_tuple("MODULE_MANAGER_INDEXES") or env_tuple("MODULE_MANAGER_INDEX") or config.indexes,
|
|
100
103
|
find_links=env_tuple("MODULE_MANAGER_FIND_LINKS") or config.find_links,
|
|
104
|
+
uv_config_file=config.uv_config_file,
|
|
101
105
|
)
|
|
102
106
|
|
|
103
107
|
|
|
@@ -62,6 +62,7 @@ class EnvironmentToolSpec:
|
|
|
62
62
|
name: Tool name used for copied binaries and reporting.
|
|
63
63
|
version: Optional source tool version for documentation.
|
|
64
64
|
package: Python package spec passed to `uv tool install`.
|
|
65
|
+
uv_config_file: uv configuration file passed to `uv tool`.
|
|
65
66
|
binary: Rust binary path to copy into the shared `bin` directory.
|
|
66
67
|
script: Shell script path to copy into the shared `bin` directory.
|
|
67
68
|
python: Optional Python interpreter or version passed to uv.
|
|
@@ -75,6 +76,7 @@ class EnvironmentToolSpec:
|
|
|
75
76
|
name: str
|
|
76
77
|
version: str | None = None
|
|
77
78
|
package: str | None = None
|
|
79
|
+
uv_config_file: Path | None = None
|
|
78
80
|
binary: Path | None = None
|
|
79
81
|
script: Path | None = None
|
|
80
82
|
python: str | None = None
|
|
@@ -148,6 +150,7 @@ def uv_install_command(
|
|
|
148
150
|
python: str | None = None,
|
|
149
151
|
indexes: tuple[str, ...] = (),
|
|
150
152
|
find_links: tuple[str, ...] = (),
|
|
153
|
+
uv_config_file: Path | None = None,
|
|
151
154
|
) -> list[str]:
|
|
152
155
|
"""Build the uv command used to install a Python CLI tool.
|
|
153
156
|
|
|
@@ -156,11 +159,15 @@ def uv_install_command(
|
|
|
156
159
|
python: Optional Python interpreter or version passed to uv.
|
|
157
160
|
indexes: Additional package index URLs.
|
|
158
161
|
find_links: Wheelhouse directories or HTML package pages.
|
|
162
|
+
uv_config_file: Optional uv configuration file passed to `uv tool`.
|
|
159
163
|
|
|
160
164
|
Returns:
|
|
161
165
|
Tokenized uv command suitable for `subprocess.run`.
|
|
162
166
|
"""
|
|
163
|
-
command = ["uv", "tool"
|
|
167
|
+
command = ["uv", "tool"]
|
|
168
|
+
if uv_config_file:
|
|
169
|
+
command.extend(["--config-file", str(uv_config_file)])
|
|
170
|
+
command.append("install")
|
|
164
171
|
if python:
|
|
165
172
|
command.extend(["--python", python])
|
|
166
173
|
for index in indexes:
|
|
@@ -482,6 +489,7 @@ def parse_environment_tool(data: object, base_dir: Path, index: int) -> Environm
|
|
|
482
489
|
name=name,
|
|
483
490
|
version=optional_string(data, "version"),
|
|
484
491
|
package=optional_string(data, "package"),
|
|
492
|
+
uv_config_file=optional_manifest_path(data, "uv_config_file", base_dir),
|
|
485
493
|
binary=optional_manifest_path(data, "binary", base_dir),
|
|
486
494
|
script=optional_manifest_path(data, "script", base_dir),
|
|
487
495
|
python=optional_string(data, "python"),
|
|
@@ -540,7 +548,13 @@ def environment_actions(spec: EnvironmentSpec, paths: DeploymentPaths) -> tuple[
|
|
|
540
548
|
tool_dir = paths.install_root / "uv-tools"
|
|
541
549
|
for tool in spec.tools:
|
|
542
550
|
if tool.tool_type == "python" and tool.package:
|
|
543
|
-
command = uv_install_command(
|
|
551
|
+
command = uv_install_command(
|
|
552
|
+
tool.package,
|
|
553
|
+
tool.python,
|
|
554
|
+
tool.indexes,
|
|
555
|
+
tool.find_links,
|
|
556
|
+
tool.uv_config_file,
|
|
557
|
+
)
|
|
544
558
|
actions.append(
|
|
545
559
|
f"install python {tool.name}: "
|
|
546
560
|
f"UV_TOOL_DIR={shlex.quote(str(tool_dir))} "
|
|
@@ -595,7 +609,13 @@ def deploy_environment(
|
|
|
595
609
|
env["UV_TOOL_DIR"] = str(tool_dir)
|
|
596
610
|
env["UV_TOOL_BIN_DIR"] = str(paths.bin_dir)
|
|
597
611
|
subprocess.run(
|
|
598
|
-
uv_install_command(
|
|
612
|
+
uv_install_command(
|
|
613
|
+
tool.package,
|
|
614
|
+
tool.python,
|
|
615
|
+
tool.indexes,
|
|
616
|
+
tool.find_links,
|
|
617
|
+
tool.uv_config_file,
|
|
618
|
+
),
|
|
599
619
|
check=True,
|
|
600
620
|
env=env,
|
|
601
621
|
)
|
|
@@ -634,6 +654,7 @@ def deploy_python_tool(
|
|
|
634
654
|
python: str | None = None,
|
|
635
655
|
indexes: tuple[str, ...] = (),
|
|
636
656
|
find_links: tuple[str, ...] = (),
|
|
657
|
+
uv_config_file: Path | None = None,
|
|
637
658
|
execute_install: bool = False,
|
|
638
659
|
make_default: bool = True,
|
|
639
660
|
) -> DeploymentPaths:
|
|
@@ -650,6 +671,7 @@ def deploy_python_tool(
|
|
|
650
671
|
python: Optional Python interpreter or version passed to uv.
|
|
651
672
|
indexes: Additional package index URLs passed to uv.
|
|
652
673
|
find_links: Wheelhouse directories or HTML package pages passed to uv.
|
|
674
|
+
uv_config_file: Optional uv configuration file passed to `uv tool`.
|
|
653
675
|
execute_install: Whether to run `uv tool install` immediately.
|
|
654
676
|
make_default: Whether to make this version the module default.
|
|
655
677
|
|
|
@@ -664,7 +686,7 @@ def deploy_python_tool(
|
|
|
664
686
|
paths = deployment_paths(module_root, prefix, name, version)
|
|
665
687
|
paths.bin_dir.mkdir(parents=True, exist_ok=True)
|
|
666
688
|
tool_dir = paths.install_root / "uv-tools"
|
|
667
|
-
command = uv_install_command(package, python, indexes, find_links)
|
|
689
|
+
command = uv_install_command(package, python, indexes, find_links, uv_config_file)
|
|
668
690
|
|
|
669
691
|
if execute_install:
|
|
670
692
|
require_executable("uv")
|
|
@@ -56,12 +56,16 @@ def test_deploy_python_command_writes_modulefile() -> None:
|
|
|
56
56
|
"https://packages.example/simple",
|
|
57
57
|
"--find-links",
|
|
58
58
|
"/prod/wheels",
|
|
59
|
+
"--uv-config-file",
|
|
60
|
+
"/prod/uv.toml",
|
|
59
61
|
],
|
|
60
62
|
)
|
|
63
|
+
modulefile = Path("modules/ruff/0.8.0").read_text(encoding="utf-8")
|
|
61
64
|
|
|
62
65
|
assert result.exit_code == 0
|
|
63
66
|
assert "modulefile: modules/ruff/0.8.0" in result.output
|
|
64
67
|
assert "default version: modules/ruff/.version" in result.output
|
|
68
|
+
assert "--config-file /prod/uv.toml" in modulefile
|
|
65
69
|
|
|
66
70
|
|
|
67
71
|
def test_deploy_python_command_uses_config_defaults() -> None:
|
|
@@ -78,6 +82,7 @@ module_root = "modules"
|
|
|
78
82
|
[python]
|
|
79
83
|
indexes = ["https://packages.example/simple"]
|
|
80
84
|
find_links = ["/prod/wheels"]
|
|
85
|
+
uv_config_file = "uv.toml"
|
|
81
86
|
""".strip(),
|
|
82
87
|
encoding="utf-8",
|
|
83
88
|
)
|
|
@@ -93,9 +98,11 @@ find_links = ["/prod/wheels"]
|
|
|
93
98
|
"ruff==0.8.0",
|
|
94
99
|
],
|
|
95
100
|
)
|
|
101
|
+
modulefile = Path("modules/ruff/0.8.0").read_text(encoding="utf-8")
|
|
96
102
|
|
|
97
103
|
assert result.exit_code == 0
|
|
98
104
|
assert "modulefile: modules/ruff/0.8.0" in result.output
|
|
105
|
+
assert "--config-file uv.toml" in modulefile
|
|
99
106
|
|
|
100
107
|
|
|
101
108
|
def test_cli_options_override_config_defaults() -> None:
|
|
@@ -22,6 +22,7 @@ module_root = "/scratch/modules"
|
|
|
22
22
|
[python]
|
|
23
23
|
indexes = ["https://packages.example/simple"]
|
|
24
24
|
find_links = ["/scratch/wheels"]
|
|
25
|
+
uv_config_file = "/scratch/uv.toml"
|
|
25
26
|
""".strip(),
|
|
26
27
|
encoding="utf-8",
|
|
27
28
|
)
|
|
@@ -31,6 +32,7 @@ find_links = ["/scratch/wheels"]
|
|
|
31
32
|
module_root=Path("/scratch/modules"),
|
|
32
33
|
indexes=("https://packages.example/simple",),
|
|
33
34
|
find_links=("/scratch/wheels",),
|
|
35
|
+
uv_config_file=Path("/scratch/uv.toml"),
|
|
34
36
|
)
|
|
35
37
|
|
|
36
38
|
|
|
@@ -109,6 +109,18 @@ def test_python_tool_install_command_accepts_python() -> None:
|
|
|
109
109
|
]
|
|
110
110
|
|
|
111
111
|
|
|
112
|
+
def test_python_tool_install_command_accepts_uv_config_file() -> None:
|
|
113
|
+
"""Uv install commands should include a requested uv config file."""
|
|
114
|
+
assert uv_install_command("ruff==0.8.0", uv_config_file=Path("/prod/uv.toml")) == [
|
|
115
|
+
"uv",
|
|
116
|
+
"tool",
|
|
117
|
+
"--config-file",
|
|
118
|
+
"/prod/uv.toml",
|
|
119
|
+
"install",
|
|
120
|
+
"ruff==0.8.0",
|
|
121
|
+
]
|
|
122
|
+
|
|
123
|
+
|
|
112
124
|
def test_deploy_python_tool_writes_package_sources_to_install_hint(tmp_path: Path) -> None:
|
|
113
125
|
"""Generated module help should show the package source options.
|
|
114
126
|
|
|
@@ -123,9 +135,11 @@ def test_deploy_python_tool_writes_package_sources_to_install_hint(tmp_path: Pat
|
|
|
123
135
|
prefix=tmp_path / "tools",
|
|
124
136
|
indexes=("https://packages.example/simple",),
|
|
125
137
|
find_links=("/prod/wheels",),
|
|
138
|
+
uv_config_file=Path("/prod/uv.toml"),
|
|
126
139
|
)
|
|
127
140
|
|
|
128
141
|
modulefile = paths.modulefile.read_text(encoding="utf-8")
|
|
142
|
+
assert "--config-file /prod/uv.toml" in modulefile
|
|
129
143
|
assert "--index https://packages.example/simple" in modulefile
|
|
130
144
|
assert "--find-links /prod/wheels" in modulefile
|
|
131
145
|
|
|
@@ -366,6 +380,7 @@ package = "ruff==0.8.0"
|
|
|
366
380
|
python = "3.12"
|
|
367
381
|
indexes = ["https://packages.example/simple"]
|
|
368
382
|
find_links = ["/prod/wheels"]
|
|
383
|
+
uv_config_file = "uv.toml"
|
|
369
384
|
|
|
370
385
|
[[tools]]
|
|
371
386
|
type = "script"
|
|
@@ -384,6 +399,7 @@ script = "scripts/helper"
|
|
|
384
399
|
assert not spec.make_default
|
|
385
400
|
assert spec.tools[0].package == "ruff==0.8.0"
|
|
386
401
|
assert spec.tools[0].indexes == ("https://packages.example/simple",)
|
|
402
|
+
assert spec.tools[0].uv_config_file == tmp_path / "uv.toml"
|
|
387
403
|
assert spec.tools[1].script == tmp_path / "scripts/helper"
|
|
388
404
|
|
|
389
405
|
|
|
@@ -491,6 +507,7 @@ type = "python"
|
|
|
491
507
|
name = "ruff"
|
|
492
508
|
package = "ruff==0.8.0"
|
|
493
509
|
python = "3.12"
|
|
510
|
+
uv_config_file = "uv.toml"
|
|
494
511
|
""".strip(),
|
|
495
512
|
encoding="utf-8",
|
|
496
513
|
)
|
|
@@ -502,7 +519,16 @@ python = "3.12"
|
|
|
502
519
|
prefix=tmp_path / "tools",
|
|
503
520
|
)
|
|
504
521
|
|
|
505
|
-
assert calls[0][0] == [
|
|
522
|
+
assert calls[0][0] == [
|
|
523
|
+
"uv",
|
|
524
|
+
"tool",
|
|
525
|
+
"--config-file",
|
|
526
|
+
str(tmp_path / "uv.toml"),
|
|
527
|
+
"install",
|
|
528
|
+
"--python",
|
|
529
|
+
"3.12",
|
|
530
|
+
"ruff==0.8.0",
|
|
531
|
+
]
|
|
506
532
|
assert calls[0][1]["UV_TOOL_DIR"] == str(result.paths.install_root / "uv-tools")
|
|
507
533
|
assert calls[0][1]["UV_TOOL_BIN_DIR"] == str(result.paths.bin_dir)
|
|
508
534
|
assert result.paths.modulefile.exists()
|
|
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
|