env-module-manager 0.7.0__tar.gz → 0.9.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.7.0 → env_module_manager-0.9.0}/PKG-INFO +16 -1
- {env_module_manager-0.7.0 → env_module_manager-0.9.0}/README.md +15 -0
- env_module_manager-0.9.0/docs/collective-environments.md +198 -0
- {env_module_manager-0.7.0 → env_module_manager-0.9.0}/docs/configuration.md +6 -0
- {env_module_manager-0.7.0 → env_module_manager-0.9.0}/docs/python-tools.md +89 -3
- {env_module_manager-0.7.0 → env_module_manager-0.9.0}/docs/reference.md +13 -1
- {env_module_manager-0.7.0 → env_module_manager-0.9.0}/module_manager/__init__.py +1 -1
- {env_module_manager-0.7.0 → env_module_manager-0.9.0}/module_manager/cli.py +79 -1
- {env_module_manager-0.7.0 → env_module_manager-0.9.0}/module_manager/config.py +4 -0
- {env_module_manager-0.7.0 → env_module_manager-0.9.0}/module_manager/deploy.py +146 -9
- {env_module_manager-0.7.0 → env_module_manager-0.9.0}/pyproject.toml +1 -1
- {env_module_manager-0.7.0 → env_module_manager-0.9.0}/tests/test_cli.py +42 -0
- {env_module_manager-0.7.0 → env_module_manager-0.9.0}/tests/test_config.py +4 -0
- {env_module_manager-0.7.0 → env_module_manager-0.9.0}/tests/test_modulefile.py +88 -3
- {env_module_manager-0.7.0 → env_module_manager-0.9.0}/uv.lock +1 -1
- env_module_manager-0.7.0/docs/collective-environments.md +0 -85
- {env_module_manager-0.7.0 → env_module_manager-0.9.0}/.github/workflows/publish.yml +0 -0
- {env_module_manager-0.7.0 → env_module_manager-0.9.0}/.github/workflows/tag.yml +0 -0
- {env_module_manager-0.7.0 → env_module_manager-0.9.0}/.github/workflows/test.yml +0 -0
- {env_module_manager-0.7.0 → env_module_manager-0.9.0}/.gitignore +0 -0
- {env_module_manager-0.7.0 → env_module_manager-0.9.0}/.python-version +0 -0
- {env_module_manager-0.7.0 → env_module_manager-0.9.0}/.readthedocs.yaml +0 -0
- {env_module_manager-0.7.0 → env_module_manager-0.9.0}/AGENTS.md +0 -0
- {env_module_manager-0.7.0 → env_module_manager-0.9.0}/CONTRIBUTING.md +0 -0
- {env_module_manager-0.7.0 → env_module_manager-0.9.0}/LICENSE.md +0 -0
- {env_module_manager-0.7.0 → env_module_manager-0.9.0}/docs/development.md +0 -0
- {env_module_manager-0.7.0 → env_module_manager-0.9.0}/docs/environment-modules.md +0 -0
- {env_module_manager-0.7.0 → env_module_manager-0.9.0}/docs/index.md +0 -0
- {env_module_manager-0.7.0 → env_module_manager-0.9.0}/docs/installation.md +0 -0
- {env_module_manager-0.7.0 → env_module_manager-0.9.0}/docs/rust-tools.md +0 -0
- {env_module_manager-0.7.0 → env_module_manager-0.9.0}/docs/shell-tools.md +0 -0
- {env_module_manager-0.7.0 → env_module_manager-0.9.0}/docs/stylesheets/extra.css +0 -0
- {env_module_manager-0.7.0 → env_module_manager-0.9.0}/docs/uninstall.md +0 -0
- {env_module_manager-0.7.0 → env_module_manager-0.9.0}/example.bash +0 -0
- {env_module_manager-0.7.0 → env_module_manager-0.9.0}/mkdocs.yml +0 -0
- {env_module_manager-0.7.0 → env_module_manager-0.9.0}/module_manager/modulefile.py +0 -0
- {env_module_manager-0.7.0 → env_module_manager-0.9.0}/tests/test_integration.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: env-module-manager
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.9.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/
|
|
@@ -73,12 +73,17 @@ Deploy a Python CLI with `uv tool install`:
|
|
|
73
73
|
```sh
|
|
74
74
|
module-manager deploy-python ruff 0.8.0 \
|
|
75
75
|
--package 'ruff==0.8.0' \
|
|
76
|
+
--default-index https://packages.example/simple \
|
|
76
77
|
--constraints /prod/constraints/runtime.txt \
|
|
78
|
+
--uv-executable /opt/uv/bin/uv \
|
|
77
79
|
--prefix /prod/tools \
|
|
78
80
|
--module-root /prod/modulefiles \
|
|
79
81
|
--execute-install
|
|
80
82
|
```
|
|
81
83
|
|
|
84
|
+
Set `MODULE_MANAGER_UV_EXECUTABLE=/opt/uv/bin/uv` to use the same uv path by
|
|
85
|
+
default.
|
|
86
|
+
|
|
82
87
|
Deploy a Rust binary:
|
|
83
88
|
|
|
84
89
|
```sh
|
|
@@ -94,6 +99,16 @@ Generate a constraints file for a Python CLI:
|
|
|
94
99
|
module-manager auto-constraints ruff==0.8.0 --output constraints.txt
|
|
95
100
|
```
|
|
96
101
|
|
|
102
|
+
Deploy from a direct wheel or Git URL:
|
|
103
|
+
|
|
104
|
+
```sh
|
|
105
|
+
module-manager deploy-python my-tool 1.0.0 \
|
|
106
|
+
--package 'my-tool @ file:///prod/wheels/my_tool-1.0.0-py3-none-any.whl' \
|
|
107
|
+
--prefix /prod/tools \
|
|
108
|
+
--module-root /prod/modulefiles \
|
|
109
|
+
--execute-install
|
|
110
|
+
```
|
|
111
|
+
|
|
97
112
|
Deploy a shell script:
|
|
98
113
|
|
|
99
114
|
```sh
|
|
@@ -41,12 +41,17 @@ Deploy a Python CLI with `uv tool install`:
|
|
|
41
41
|
```sh
|
|
42
42
|
module-manager deploy-python ruff 0.8.0 \
|
|
43
43
|
--package 'ruff==0.8.0' \
|
|
44
|
+
--default-index https://packages.example/simple \
|
|
44
45
|
--constraints /prod/constraints/runtime.txt \
|
|
46
|
+
--uv-executable /opt/uv/bin/uv \
|
|
45
47
|
--prefix /prod/tools \
|
|
46
48
|
--module-root /prod/modulefiles \
|
|
47
49
|
--execute-install
|
|
48
50
|
```
|
|
49
51
|
|
|
52
|
+
Set `MODULE_MANAGER_UV_EXECUTABLE=/opt/uv/bin/uv` to use the same uv path by
|
|
53
|
+
default.
|
|
54
|
+
|
|
50
55
|
Deploy a Rust binary:
|
|
51
56
|
|
|
52
57
|
```sh
|
|
@@ -62,6 +67,16 @@ Generate a constraints file for a Python CLI:
|
|
|
62
67
|
module-manager auto-constraints ruff==0.8.0 --output constraints.txt
|
|
63
68
|
```
|
|
64
69
|
|
|
70
|
+
Deploy from a direct wheel or Git URL:
|
|
71
|
+
|
|
72
|
+
```sh
|
|
73
|
+
module-manager deploy-python my-tool 1.0.0 \
|
|
74
|
+
--package 'my-tool @ file:///prod/wheels/my_tool-1.0.0-py3-none-any.whl' \
|
|
75
|
+
--prefix /prod/tools \
|
|
76
|
+
--module-root /prod/modulefiles \
|
|
77
|
+
--execute-install
|
|
78
|
+
```
|
|
79
|
+
|
|
65
80
|
Deploy a shell script:
|
|
66
81
|
|
|
67
82
|
```sh
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
# Collective Environments
|
|
2
|
+
|
|
3
|
+
Collective environments package several tools behind one modulefile. Use them
|
|
4
|
+
when a shared workflow needs Python CLIs, Rust binaries, and shell scripts to
|
|
5
|
+
appear together from one `module load`.
|
|
6
|
+
|
|
7
|
+
Create a TOML manifest:
|
|
8
|
+
|
|
9
|
+
```toml
|
|
10
|
+
name = "dev-tools"
|
|
11
|
+
version = "2026.05"
|
|
12
|
+
description = "Shared developer command-line tools"
|
|
13
|
+
prefix = "/prod/tools"
|
|
14
|
+
module_root = "/prod/modulefiles"
|
|
15
|
+
default = true
|
|
16
|
+
|
|
17
|
+
[[tools]]
|
|
18
|
+
type = "python"
|
|
19
|
+
name = "ruff"
|
|
20
|
+
version = "0.8.0"
|
|
21
|
+
package = "ruff==0.8.0"
|
|
22
|
+
python = "3.12"
|
|
23
|
+
indexes = ["https://packages.example/simple"]
|
|
24
|
+
default_index = "https://packages.example/simple"
|
|
25
|
+
find_links = ["/prod/wheels"]
|
|
26
|
+
no_index = false
|
|
27
|
+
index_strategy = "first-index"
|
|
28
|
+
constraints = ["/prod/constraints/runtime.txt"]
|
|
29
|
+
no_cache = false
|
|
30
|
+
refresh = false
|
|
31
|
+
refresh_packages = ["ruff"]
|
|
32
|
+
force = false
|
|
33
|
+
reinstall = false
|
|
34
|
+
uv_config_file = "/prod/config/uv.toml"
|
|
35
|
+
uv_executable = "/opt/uv/bin/uv"
|
|
36
|
+
|
|
37
|
+
[[tools]]
|
|
38
|
+
type = "rust"
|
|
39
|
+
name = "ripgrep"
|
|
40
|
+
version = "14.1.1"
|
|
41
|
+
binary = "./target/release/rg"
|
|
42
|
+
|
|
43
|
+
[[tools]]
|
|
44
|
+
type = "script"
|
|
45
|
+
name = "lab-helper"
|
|
46
|
+
version = "1.0.0"
|
|
47
|
+
script = "./scripts/lab-helper"
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Deploy the environment:
|
|
51
|
+
|
|
52
|
+
```sh
|
|
53
|
+
module-manager deploy-env --file dev-tools.toml
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Use `--uv-executable` when all Python tools in the manifest should use a
|
|
57
|
+
specific uv executable:
|
|
58
|
+
|
|
59
|
+
```sh
|
|
60
|
+
module-manager deploy-env --file dev-tools.toml --uv-executable /opt/uv/bin/uv
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
You can also set the same default with `MODULE_MANAGER_UV_EXECUTABLE`, or set
|
|
64
|
+
`uv_executable` on an individual Python tool in the manifest when only that
|
|
65
|
+
entry needs a different executable.
|
|
66
|
+
|
|
67
|
+
This writes one shared environment:
|
|
68
|
+
|
|
69
|
+
```text
|
|
70
|
+
/prod/tools/dev-tools/2026.05/bin
|
|
71
|
+
/prod/modulefiles/dev-tools/2026.05
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
The generated modulefile prepends the shared `bin` directory to `PATH`, so all
|
|
75
|
+
tools in the manifest are available after:
|
|
76
|
+
|
|
77
|
+
```sh
|
|
78
|
+
module use /prod/modulefiles
|
|
79
|
+
module load dev-tools
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Relative `binary` and `script` paths are resolved relative to the manifest file.
|
|
83
|
+
Relative Python `constraints` paths are resolved the same way.
|
|
84
|
+
|
|
85
|
+
## Multiple Python Tools
|
|
86
|
+
|
|
87
|
+
A collective environment can install several Python CLIs into the same shared
|
|
88
|
+
`bin` directory. Each Python tool can use its own package spec and uv resolver
|
|
89
|
+
options:
|
|
90
|
+
|
|
91
|
+
```toml
|
|
92
|
+
name = "python-dev-tools"
|
|
93
|
+
version = "2026.05"
|
|
94
|
+
prefix = "/prod/tools"
|
|
95
|
+
module_root = "/prod/modulefiles"
|
|
96
|
+
|
|
97
|
+
[[tools]]
|
|
98
|
+
type = "python"
|
|
99
|
+
name = "ruff"
|
|
100
|
+
version = "0.8.0"
|
|
101
|
+
package = "ruff==0.8.0"
|
|
102
|
+
python = "3.12"
|
|
103
|
+
constraints = ["constraints.txt"]
|
|
104
|
+
|
|
105
|
+
[[tools]]
|
|
106
|
+
type = "python"
|
|
107
|
+
name = "gitconductor"
|
|
108
|
+
version = "0.7.0"
|
|
109
|
+
package = "gitconductor==0.7.0"
|
|
110
|
+
default_index = "https://packages.example/simple"
|
|
111
|
+
constraints = ["constraints.txt"]
|
|
112
|
+
refresh_packages = ["gitconductor"]
|
|
113
|
+
|
|
114
|
+
[[tools]]
|
|
115
|
+
type = "python"
|
|
116
|
+
name = "internal-review"
|
|
117
|
+
version = "1.4.2"
|
|
118
|
+
package = "internal-review @ file:///prod/wheels/internal_review-1.4.2-py3-none-any.whl"
|
|
119
|
+
find_links = ["/prod/wheels"]
|
|
120
|
+
no_index = true
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
Deploy it with:
|
|
124
|
+
|
|
125
|
+
```sh
|
|
126
|
+
module-manager deploy-env --file python-dev-tools.toml
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
After `module load python-dev-tools`, the `ruff`, `gitconductor`, and
|
|
130
|
+
`internal-review` executables are available from one module.
|
|
131
|
+
|
|
132
|
+
## Python Tools and Bash Scripts
|
|
133
|
+
|
|
134
|
+
Use script entries for Bash helpers that should live alongside Python CLIs:
|
|
135
|
+
|
|
136
|
+
```toml
|
|
137
|
+
name = "release-tools"
|
|
138
|
+
version = "2026.05"
|
|
139
|
+
description = "Release automation helpers"
|
|
140
|
+
prefix = "/prod/tools"
|
|
141
|
+
module_root = "/prod/modulefiles"
|
|
142
|
+
|
|
143
|
+
[[tools]]
|
|
144
|
+
type = "python"
|
|
145
|
+
name = "gitconductor"
|
|
146
|
+
version = "0.7.0"
|
|
147
|
+
package = "gitconductor==0.7.0"
|
|
148
|
+
constraints = ["constraints.txt"]
|
|
149
|
+
|
|
150
|
+
[[tools]]
|
|
151
|
+
type = "python"
|
|
152
|
+
name = "changelog-builder"
|
|
153
|
+
version = "2.1.0"
|
|
154
|
+
package = "changelog-builder @ git+https://github.com/org/changelog-builder.git@v2.1.0"
|
|
155
|
+
|
|
156
|
+
[[tools]]
|
|
157
|
+
type = "script"
|
|
158
|
+
name = "release-check"
|
|
159
|
+
version = "1.0.0"
|
|
160
|
+
script = "./scripts/release-check.sh"
|
|
161
|
+
|
|
162
|
+
[[tools]]
|
|
163
|
+
type = "script"
|
|
164
|
+
name = "publish-docs"
|
|
165
|
+
version = "1.0.0"
|
|
166
|
+
script = "./scripts/publish-docs.sh"
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
Deploy it with:
|
|
170
|
+
|
|
171
|
+
```sh
|
|
172
|
+
module-manager deploy-env --file release-tools.toml
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
The script files are copied into the shared environment `bin` directory and
|
|
176
|
+
marked executable, so they appear on `PATH` next to the Python entry points.
|
|
177
|
+
|
|
178
|
+
## Preview
|
|
179
|
+
|
|
180
|
+
Use `--dry-run` to preview the install, copy, and modulefile actions without
|
|
181
|
+
creating files:
|
|
182
|
+
|
|
183
|
+
```sh
|
|
184
|
+
module-manager deploy-env --file dev-tools.toml --dry-run
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
## Overrides
|
|
188
|
+
|
|
189
|
+
The manifest can define `prefix`, `module_root`, and `default`, but CLI options
|
|
190
|
+
can override them:
|
|
191
|
+
|
|
192
|
+
```sh
|
|
193
|
+
module-manager deploy-env \
|
|
194
|
+
--file dev-tools.toml \
|
|
195
|
+
--prefix /scratch/tools \
|
|
196
|
+
--module-root /scratch/modulefiles \
|
|
197
|
+
--no-default
|
|
198
|
+
```
|
|
@@ -18,6 +18,7 @@ module_root = "/prod/modulefiles"
|
|
|
18
18
|
indexes = ["https://packages.example/simple"]
|
|
19
19
|
find_links = ["/prod/wheels"]
|
|
20
20
|
uv_config_file = "/prod/config/uv.toml"
|
|
21
|
+
uv_executable = "/opt/uv/bin/uv"
|
|
21
22
|
```
|
|
22
23
|
|
|
23
24
|
`prefix` and `module_root` must resolve to different directories. Using the
|
|
@@ -37,10 +38,15 @@ export MODULE_MANAGER_PREFIX=/prod/tools
|
|
|
37
38
|
export MODULE_MANAGER_MODULE_ROOT=/prod/modulefiles
|
|
38
39
|
export MODULE_MANAGER_INDEXES=https://packages.example/simple,https://mirror.example/simple
|
|
39
40
|
export MODULE_MANAGER_FIND_LINKS=/prod/wheels,/prod/more-wheels
|
|
41
|
+
export MODULE_MANAGER_UV_EXECUTABLE=/opt/uv/bin/uv
|
|
40
42
|
```
|
|
41
43
|
|
|
42
44
|
`MODULE_MANAGER_CONFIG` can point to an alternate TOML config file.
|
|
43
45
|
|
|
46
|
+
`MODULE_MANAGER_UV_EXECUTABLE` sets the `uv` executable used by
|
|
47
|
+
`deploy-python`, `deploy-env`, and `auto-constraints`. CLI `--uv-executable`
|
|
48
|
+
options override it when provided.
|
|
49
|
+
|
|
44
50
|
There is no `MODULE_MANAGER_*` environment variable for uv configuration files.
|
|
45
51
|
Use uv's own `UV_CONFIG_FILE` environment variable when you want to set that via
|
|
46
52
|
the environment.
|
|
@@ -11,6 +11,24 @@ Other uv settings, including `UV_CONFIG_FILE`, are preserved.
|
|
|
11
11
|
Python package dependency because `module-manager` shells out to the `uv`
|
|
12
12
|
executable and is intended to be installable by `uv` itself.
|
|
13
13
|
|
|
14
|
+
If `uv` is not on `PATH`, or you want a pinned executable, pass
|
|
15
|
+
`--uv-executable`:
|
|
16
|
+
|
|
17
|
+
```sh
|
|
18
|
+
module-manager deploy-python ruff 0.8.0 \
|
|
19
|
+
--package 'ruff==0.8.0' \
|
|
20
|
+
--uv-executable /opt/uv/bin/uv \
|
|
21
|
+
--prefix /prod/tools \
|
|
22
|
+
--module-root /prod/modulefiles \
|
|
23
|
+
--execute-install
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
The same default can be set for Python workflows with an environment variable:
|
|
27
|
+
|
|
28
|
+
```sh
|
|
29
|
+
export MODULE_MANAGER_UV_EXECUTABLE=/opt/uv/bin/uv
|
|
30
|
+
```
|
|
31
|
+
|
|
14
32
|
## Deploy from PyPI
|
|
15
33
|
|
|
16
34
|
```sh
|
|
@@ -34,20 +52,37 @@ unchanged.
|
|
|
34
52
|
```sh
|
|
35
53
|
module-manager deploy-python gitconductor 0.1.0 \
|
|
36
54
|
--package gitconductor==0.1.0 \
|
|
55
|
+
--default-index https://packages.example/simple \
|
|
37
56
|
--index https://packages.example/simple \
|
|
38
57
|
--prefix /prod/tools \
|
|
39
58
|
--module-root /prod/modulefiles \
|
|
40
59
|
--execute-install
|
|
41
60
|
```
|
|
42
61
|
|
|
43
|
-
`--index` may be used more than once.
|
|
62
|
+
`--index` may be used more than once. Use `--default-index` to replace uv's
|
|
63
|
+
default package index, or `--no-index` when resolution should use only direct
|
|
64
|
+
URLs and `--find-links` locations.
|
|
44
65
|
|
|
45
66
|
## Deploy from a Wheelhouse
|
|
46
67
|
|
|
68
|
+
Use `--find-links` when wheels are staged in a directory or simple HTML page:
|
|
69
|
+
|
|
70
|
+
```sh
|
|
71
|
+
module-manager deploy-python gitconductor 0.1.0 \
|
|
72
|
+
--package gitconductor==0.1.0 \
|
|
73
|
+
--find-links /prod/wheels \
|
|
74
|
+
--prefix /prod/tools \
|
|
75
|
+
--module-root /prod/modulefiles \
|
|
76
|
+
--execute-install
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Add `--no-index` to make the install fully wheelhouse-only:
|
|
80
|
+
|
|
47
81
|
```sh
|
|
48
82
|
module-manager deploy-python gitconductor 0.1.0 \
|
|
49
83
|
--package gitconductor==0.1.0 \
|
|
50
84
|
--find-links /prod/wheels \
|
|
85
|
+
--no-index \
|
|
51
86
|
--prefix /prod/tools \
|
|
52
87
|
--module-root /prod/modulefiles \
|
|
53
88
|
--execute-install
|
|
@@ -55,6 +90,28 @@ module-manager deploy-python gitconductor 0.1.0 \
|
|
|
55
90
|
|
|
56
91
|
`--find-links` may be used more than once.
|
|
57
92
|
|
|
93
|
+
## Deploy from a Wheel URL
|
|
94
|
+
|
|
95
|
+
Pass a direct wheel URL or file URL as the package spec:
|
|
96
|
+
|
|
97
|
+
```sh
|
|
98
|
+
module-manager deploy-python gitconductor 0.1.0 \
|
|
99
|
+
--package 'gitconductor @ https://packages.example/files/gitconductor-0.1.0-py3-none-any.whl' \
|
|
100
|
+
--prefix /prod/tools \
|
|
101
|
+
--module-root /prod/modulefiles \
|
|
102
|
+
--execute-install
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
For a local wheel file:
|
|
106
|
+
|
|
107
|
+
```sh
|
|
108
|
+
module-manager deploy-python gitconductor 0.1.0 \
|
|
109
|
+
--package 'gitconductor @ file:///prod/wheels/gitconductor-0.1.0-py3-none-any.whl' \
|
|
110
|
+
--prefix /prod/tools \
|
|
111
|
+
--module-root /prod/modulefiles \
|
|
112
|
+
--execute-install
|
|
113
|
+
```
|
|
114
|
+
|
|
58
115
|
## Use Constraint Files
|
|
59
116
|
|
|
60
117
|
Pass requirement constraint files to `uv tool install`:
|
|
@@ -70,6 +127,24 @@ module-manager deploy-python gitconductor 0.1.0 \
|
|
|
70
127
|
|
|
71
128
|
`--constraints` may be used more than once.
|
|
72
129
|
|
|
130
|
+
## Cache and Refresh Controls
|
|
131
|
+
|
|
132
|
+
Pass uv cache controls through when you need fresh index or package metadata:
|
|
133
|
+
|
|
134
|
+
```sh
|
|
135
|
+
module-manager deploy-python gitconductor 0.1.0 \
|
|
136
|
+
--package gitconductor==0.1.0 \
|
|
137
|
+
--refresh \
|
|
138
|
+
--refresh-package gitconductor \
|
|
139
|
+
--no-cache \
|
|
140
|
+
--prefix /prod/tools \
|
|
141
|
+
--module-root /prod/modulefiles \
|
|
142
|
+
--execute-install
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
Use `--force` or `--reinstall` when re-running an install into an existing
|
|
146
|
+
versioned tool environment.
|
|
147
|
+
|
|
73
148
|
## Generate Constraint Files
|
|
74
149
|
|
|
75
150
|
Use `auto-constraints` to compile a package and its dependencies into a
|
|
@@ -78,6 +153,7 @@ constraints file:
|
|
|
78
153
|
```sh
|
|
79
154
|
module-manager auto-constraints gitconductor==0.7.0 \
|
|
80
155
|
--index https://packages.example/simple \
|
|
156
|
+
--uv-executable /opt/uv/bin/uv \
|
|
81
157
|
--output constraints.txt
|
|
82
158
|
```
|
|
83
159
|
|
|
@@ -111,8 +187,8 @@ through the environment.
|
|
|
111
187
|
|
|
112
188
|
## Deploy from VCS
|
|
113
189
|
|
|
114
|
-
`--package` is passed directly to `uv tool install`, so
|
|
115
|
-
supported.
|
|
190
|
+
`--package` is passed directly to `uv tool install`, so Git package specs are
|
|
191
|
+
supported. Pin a tag, branch, or commit to keep deployments reproducible.
|
|
116
192
|
|
|
117
193
|
```sh
|
|
118
194
|
module-manager deploy-python mytool 1.0.0 \
|
|
@@ -122,6 +198,16 @@ module-manager deploy-python mytool 1.0.0 \
|
|
|
122
198
|
--execute-install
|
|
123
199
|
```
|
|
124
200
|
|
|
201
|
+
For an SSH Git URL:
|
|
202
|
+
|
|
203
|
+
```sh
|
|
204
|
+
module-manager deploy-python mytool 1.0.0 \
|
|
205
|
+
--package 'git+ssh://git@github.com/org/repo.git@v1.0.0' \
|
|
206
|
+
--prefix /prod/tools \
|
|
207
|
+
--module-root /prod/modulefiles \
|
|
208
|
+
--execute-install
|
|
209
|
+
```
|
|
210
|
+
|
|
125
211
|
For a package in a repository subdirectory:
|
|
126
212
|
|
|
127
213
|
```sh
|
|
@@ -49,9 +49,19 @@ module-manager deploy-python NAME VERSION \
|
|
|
49
49
|
--package PACKAGE \
|
|
50
50
|
[--python PYTHON] \
|
|
51
51
|
[--index URL] \
|
|
52
|
+
[--default-index URL] \
|
|
52
53
|
[--find-links PATH_OR_URL] \
|
|
54
|
+
[--no-index] \
|
|
55
|
+
[--index-strategy STRATEGY] \
|
|
56
|
+
[--keyring-provider PROVIDER] \
|
|
53
57
|
[--constraints PATH] \
|
|
58
|
+
[--no-cache] \
|
|
59
|
+
[--refresh] \
|
|
60
|
+
[--refresh-package PACKAGE] \
|
|
61
|
+
[--force] \
|
|
62
|
+
[--reinstall] \
|
|
54
63
|
[--uv-config-file PATH] \
|
|
64
|
+
[--uv-executable PATH] \
|
|
55
65
|
[--prefix PATH] \
|
|
56
66
|
[--module-root PATH] \
|
|
57
67
|
[--no-default] \
|
|
@@ -66,7 +76,8 @@ module-manager auto-constraints PACKAGE \
|
|
|
66
76
|
[--python PYTHON] \
|
|
67
77
|
[--index URL] \
|
|
68
78
|
[--find-links PATH_OR_URL] \
|
|
69
|
-
[--uv-config-file PATH]
|
|
79
|
+
[--uv-config-file PATH] \
|
|
80
|
+
[--uv-executable PATH]
|
|
70
81
|
```
|
|
71
82
|
|
|
72
83
|
## Rust Command
|
|
@@ -77,6 +88,7 @@ module-manager deploy-rust NAME VERSION \
|
|
|
77
88
|
[--prefix PATH] \
|
|
78
89
|
[--module-root PATH] \
|
|
79
90
|
[--no-default] \
|
|
91
|
+
[--uv-executable PATH] \
|
|
80
92
|
[--dry-run]
|
|
81
93
|
```
|
|
82
94
|
|
|
@@ -203,23 +203,50 @@ def main(ctx: click.Context, config: Path | None) -> None:
|
|
|
203
203
|
multiple=True,
|
|
204
204
|
help="Additional package index URL passed to uv. May be used more than once.",
|
|
205
205
|
)
|
|
206
|
+
@click.option("--default-index", help="Default package index URL passed to uv.")
|
|
206
207
|
@click.option(
|
|
207
208
|
"--find-links",
|
|
208
209
|
"find_links",
|
|
209
210
|
multiple=True,
|
|
210
211
|
help="Directory or HTML page of packages passed to uv. May be used more than once.",
|
|
211
212
|
)
|
|
213
|
+
@click.option("--no-index", is_flag=True, help="Ignore registry indexes and use direct URLs or find-links.")
|
|
214
|
+
@click.option(
|
|
215
|
+
"--index-strategy",
|
|
216
|
+
type=click.Choice(["first-index", "unsafe-first-match", "unsafe-best-match"]),
|
|
217
|
+
help="Package index strategy passed to uv.",
|
|
218
|
+
)
|
|
219
|
+
@click.option(
|
|
220
|
+
"--keyring-provider",
|
|
221
|
+
type=click.Choice(["disabled", "subprocess"]),
|
|
222
|
+
help="Keyring provider passed to uv.",
|
|
223
|
+
)
|
|
212
224
|
@click.option(
|
|
213
225
|
"--constraints",
|
|
214
226
|
"constraints",
|
|
215
227
|
multiple=True,
|
|
216
228
|
help="Requirements constraint file passed to uv. May be used more than once.",
|
|
217
229
|
)
|
|
230
|
+
@click.option("--no-cache", is_flag=True, help="Avoid reading from or writing to the uv cache.")
|
|
231
|
+
@click.option("--refresh", is_flag=True, help="Refresh all uv cached data.")
|
|
232
|
+
@click.option(
|
|
233
|
+
"--refresh-package",
|
|
234
|
+
"refresh_packages",
|
|
235
|
+
multiple=True,
|
|
236
|
+
help="Refresh cached data for a package. May be used more than once.",
|
|
237
|
+
)
|
|
238
|
+
@click.option("--force", is_flag=True, help="Replace existing executable entries.")
|
|
239
|
+
@click.option("--reinstall", is_flag=True, help="Reinstall all packages in the tool environment.")
|
|
218
240
|
@click.option(
|
|
219
241
|
"--uv-config-file",
|
|
220
242
|
type=PATH,
|
|
221
243
|
help="uv.toml file passed to uv tool install with --config-file.",
|
|
222
244
|
)
|
|
245
|
+
@click.option(
|
|
246
|
+
"--uv-executable",
|
|
247
|
+
type=PATH,
|
|
248
|
+
help="uv executable path. Defaults to uv on PATH.",
|
|
249
|
+
)
|
|
223
250
|
@click.option(
|
|
224
251
|
"--execute-install",
|
|
225
252
|
is_flag=True,
|
|
@@ -238,9 +265,19 @@ def deploy_python(
|
|
|
238
265
|
package: str,
|
|
239
266
|
python: str | None,
|
|
240
267
|
indexes: tuple[str, ...],
|
|
268
|
+
default_index: str | None,
|
|
241
269
|
find_links: tuple[str, ...],
|
|
270
|
+
no_index: bool,
|
|
271
|
+
index_strategy: str | None,
|
|
272
|
+
keyring_provider: str | None,
|
|
242
273
|
constraints: tuple[str, ...],
|
|
274
|
+
no_cache: bool,
|
|
275
|
+
refresh: bool,
|
|
276
|
+
refresh_packages: tuple[str, ...],
|
|
277
|
+
force: bool,
|
|
278
|
+
reinstall: bool,
|
|
243
279
|
uv_config_file: Path | None,
|
|
280
|
+
uv_executable: Path | None,
|
|
244
281
|
execute_install: bool,
|
|
245
282
|
) -> None:
|
|
246
283
|
"""Write a modulefile for a [cyan]uv tool install[/cyan] Python CLI.
|
|
@@ -257,9 +294,19 @@ def deploy_python(
|
|
|
257
294
|
package: Package spec passed to `uv tool install`.
|
|
258
295
|
python: Optional Python interpreter or version passed to uv.
|
|
259
296
|
indexes: Additional package index URLs passed to uv.
|
|
297
|
+
default_index: Default package index URL passed to uv.
|
|
260
298
|
find_links: Wheelhouse directories or HTML package pages passed to uv.
|
|
299
|
+
no_index: Whether uv should ignore registry indexes.
|
|
300
|
+
index_strategy: Package index strategy passed to uv.
|
|
301
|
+
keyring_provider: Keyring provider passed to uv.
|
|
261
302
|
constraints: Requirements constraint files passed to uv.
|
|
303
|
+
no_cache: Whether uv should avoid reading from or writing to cache.
|
|
304
|
+
refresh: Whether uv should refresh cached data.
|
|
305
|
+
refresh_packages: Packages whose cached data uv should refresh.
|
|
306
|
+
force: Whether uv should replace existing executable entries.
|
|
307
|
+
reinstall: Whether uv should reinstall all packages.
|
|
262
308
|
uv_config_file: Optional uv configuration file passed to `uv tool`.
|
|
309
|
+
uv_executable: Optional uv executable path.
|
|
263
310
|
execute_install: Whether to run `uv tool install` immediately.
|
|
264
311
|
|
|
265
312
|
Raises:
|
|
@@ -282,9 +329,19 @@ def deploy_python(
|
|
|
282
329
|
homepage=homepage,
|
|
283
330
|
python=python,
|
|
284
331
|
indexes=indexes or config.indexes,
|
|
332
|
+
default_index=default_index,
|
|
285
333
|
find_links=find_links or config.find_links,
|
|
334
|
+
no_index=no_index,
|
|
335
|
+
index_strategy=index_strategy,
|
|
336
|
+
keyring_provider=keyring_provider,
|
|
286
337
|
constraints=constraints,
|
|
338
|
+
no_cache=no_cache,
|
|
339
|
+
refresh=refresh,
|
|
340
|
+
refresh_packages=refresh_packages,
|
|
341
|
+
force=force,
|
|
342
|
+
reinstall=reinstall,
|
|
287
343
|
uv_config_file=(uv_config_file.expanduser() if uv_config_file else config.uv_config_file),
|
|
344
|
+
uv_executable=(uv_executable.expanduser() if uv_executable else config.uv_executable),
|
|
288
345
|
execute_install=execute_install,
|
|
289
346
|
make_default=make_default,
|
|
290
347
|
)
|
|
@@ -325,6 +382,11 @@ def deploy_python(
|
|
|
325
382
|
type=PATH,
|
|
326
383
|
help="uv.toml file passed to uv with --config-file.",
|
|
327
384
|
)
|
|
385
|
+
@click.option(
|
|
386
|
+
"--uv-executable",
|
|
387
|
+
type=PATH,
|
|
388
|
+
help="uv executable path. Defaults to uv on PATH.",
|
|
389
|
+
)
|
|
328
390
|
@click.pass_obj
|
|
329
391
|
def auto_constraints(
|
|
330
392
|
config: AppConfig,
|
|
@@ -334,6 +396,7 @@ def auto_constraints(
|
|
|
334
396
|
indexes: tuple[str, ...],
|
|
335
397
|
find_links: tuple[str, ...],
|
|
336
398
|
uv_config_file: Path | None,
|
|
399
|
+
uv_executable: Path | None,
|
|
337
400
|
) -> None:
|
|
338
401
|
"""Generate a constraints file for a Python package.
|
|
339
402
|
|
|
@@ -345,6 +408,7 @@ def auto_constraints(
|
|
|
345
408
|
indexes: Additional package index URLs passed to uv.
|
|
346
409
|
find_links: Wheelhouse directories or HTML package pages passed to uv.
|
|
347
410
|
uv_config_file: Optional uv configuration file passed to uv.
|
|
411
|
+
uv_executable: Optional uv executable path.
|
|
348
412
|
|
|
349
413
|
Raises:
|
|
350
414
|
click.ClickException: If uv cannot generate constraints.
|
|
@@ -358,6 +422,7 @@ def auto_constraints(
|
|
|
358
422
|
indexes=indexes or config.indexes,
|
|
359
423
|
find_links=find_links or config.find_links,
|
|
360
424
|
uv_config_file=(uv_config_file.expanduser() if uv_config_file else config.uv_config_file),
|
|
425
|
+
uv_executable=(uv_executable.expanduser() if uv_executable else config.uv_executable),
|
|
361
426
|
)
|
|
362
427
|
except ConstraintGenerationError as error:
|
|
363
428
|
raise click.ClickException(str(error)) from error
|
|
@@ -543,6 +608,11 @@ def deploy_script(
|
|
|
543
608
|
is_flag=True,
|
|
544
609
|
help="Print actions that would run without creating files.",
|
|
545
610
|
)
|
|
611
|
+
@click.option(
|
|
612
|
+
"--uv-executable",
|
|
613
|
+
type=PATH,
|
|
614
|
+
help="uv executable path for Python tools. Defaults to uv on PATH.",
|
|
615
|
+
)
|
|
546
616
|
@click.pass_obj
|
|
547
617
|
def deploy_env(
|
|
548
618
|
config: AppConfig,
|
|
@@ -551,6 +621,7 @@ def deploy_env(
|
|
|
551
621
|
prefix: Path | None,
|
|
552
622
|
make_default: bool | None,
|
|
553
623
|
dry_run: bool,
|
|
624
|
+
uv_executable: Path | None,
|
|
554
625
|
) -> None:
|
|
555
626
|
"""Deploy a collective environment from a TOML manifest.
|
|
556
627
|
|
|
@@ -562,6 +633,7 @@ def deploy_env(
|
|
|
562
633
|
prefix: Optional install prefix overriding manifest and configuration.
|
|
563
634
|
make_default: Optional override for manifest default behavior.
|
|
564
635
|
dry_run: Whether to report actions without mutating the filesystem.
|
|
636
|
+
uv_executable: Optional uv executable path for Python tools.
|
|
565
637
|
|
|
566
638
|
Raises:
|
|
567
639
|
click.ClickException: If the manifest cannot be parsed.
|
|
@@ -588,7 +660,13 @@ def deploy_env(
|
|
|
588
660
|
make_default=make_default,
|
|
589
661
|
)
|
|
590
662
|
|
|
591
|
-
result = deploy_environment(
|
|
663
|
+
result = deploy_environment(
|
|
664
|
+
spec=spec,
|
|
665
|
+
module_root=resolved_module_root,
|
|
666
|
+
prefix=resolved_prefix,
|
|
667
|
+
uv_executable=(uv_executable.expanduser() if uv_executable else config.uv_executable),
|
|
668
|
+
dry_run=dry_run,
|
|
669
|
+
)
|
|
592
670
|
print_environment_result(result, dry_run)
|
|
593
671
|
|
|
594
672
|
|