Jarvis-Forge 1.0.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.
- jarvis_forge-1.0.0/CHANGELOG.md +49 -0
- jarvis_forge-1.0.0/LICENSE +22 -0
- jarvis_forge-1.0.0/MANIFEST.in +16 -0
- jarvis_forge-1.0.0/PKG-INFO +213 -0
- jarvis_forge-1.0.0/README.md +184 -0
- jarvis_forge-1.0.0/pyproject.toml +45 -0
- jarvis_forge-1.0.0/setup.cfg +4 -0
- jarvis_forge-1.0.0/src/Jarvis_Forge.egg-info/PKG-INFO +213 -0
- jarvis_forge-1.0.0/src/Jarvis_Forge.egg-info/SOURCES.txt +37 -0
- jarvis_forge-1.0.0/src/Jarvis_Forge.egg-info/dependency_links.txt +1 -0
- jarvis_forge-1.0.0/src/Jarvis_Forge.egg-info/entry_points.txt +2 -0
- jarvis_forge-1.0.0/src/Jarvis_Forge.egg-info/requires.txt +11 -0
- jarvis_forge-1.0.0/src/Jarvis_Forge.egg-info/top_level.txt +1 -0
- jarvis_forge-1.0.0/src/jarvis_forge/__init__.py +4 -0
- jarvis_forge-1.0.0/src/jarvis_forge/__main__.py +4 -0
- jarvis_forge-1.0.0/src/jarvis_forge/apt_cli.py +234 -0
- jarvis_forge-1.0.0/src/jarvis_forge/catalog.py +171 -0
- jarvis_forge-1.0.0/src/jarvis_forge/cli.py +354 -0
- jarvis_forge-1.0.0/src/jarvis_forge/comparison.py +90 -0
- jarvis_forge-1.0.0/src/jarvis_forge/downloads.py +87 -0
- jarvis_forge-1.0.0/src/jarvis_forge/env_cli.py +65 -0
- jarvis_forge-1.0.0/src/jarvis_forge/environment.py +158 -0
- jarvis_forge-1.0.0/src/jarvis_forge/environment_registry.py +252 -0
- jarvis_forge-1.0.0/src/jarvis_forge/examples/smoke.yaml +24 -0
- jarvis_forge-1.0.0/src/jarvis_forge/official.py +366 -0
- jarvis_forge-1.0.0/src/jarvis_forge/packages.py +498 -0
- jarvis_forge-1.0.0/src/jarvis_forge/recipes/eigen.yaml +22 -0
- jarvis_forge-1.0.0/src/jarvis_forge/recipes/redis.yaml +20 -0
- jarvis_forge-1.0.0/src/jarvis_forge/runner.py +203 -0
- jarvis_forge-1.0.0/src/jarvis_forge/schemas/recipe.schema.json +46 -0
- jarvis_forge-1.0.0/src/jarvis_forge/schemas/suite.schema.json +143 -0
- jarvis_forge-1.0.0/src/jarvis_forge/storage.py +151 -0
- jarvis_forge-1.0.0/src/jarvis_forge/suite.py +144 -0
- jarvis_forge-1.0.0/tests/test_apt.py +346 -0
- jarvis_forge-1.0.0/tests/test_cli.py +89 -0
- jarvis_forge-1.0.0/tests/test_env_registry.py +235 -0
- jarvis_forge-1.0.0/tests/test_environment.py +126 -0
- jarvis_forge-1.0.0/tests/test_official.py +252 -0
- jarvis_forge-1.0.0/tests/test_workflow.py +212 -0
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 1.0.0
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- Provide the independent `jforge` CLI for user-space package installation, environment inspection and command-based acceptance workflows, with structured JSON output.
|
|
8
|
+
- Keep software receipts, named environments and run history in one shared user directory, independent of the Python installation running Forge.
|
|
9
|
+
- Install, reinstall, remove and upgrade source packages under private user prefixes with `jforge apt`; include pinned Eigen and Redis recipes, version constraints, dependency resolution and activation scripts.
|
|
10
|
+
- Import Debian and Ubuntu source metadata and quilt patches through reviewed build adapters, then track upstream versions and packaging revisions with `apt update` and `apt upgrade`.
|
|
11
|
+
- Register, list and inspect named environments with `env add/list/show`; preserve private shell copies and immutable revisions, with explicit executable or pyenv selections through `env set-python`.
|
|
12
|
+
- Inspect compiler paths and versions, Python interpreters and packages, and selected pyenv/module variables with `doctor`; select a registered environment explicitly using `--env` or acceptance YAML.
|
|
13
|
+
- Run versioned YAML command suites with step dependencies, environment scripts, explicit working directories, timeouts, process cleanup and declared output checks.
|
|
14
|
+
- Archive suite configurations, inputs, commands, activated environments, stdout/stderr, exit status and output files for each run; query history and compare recorded evidence with `compare` and `compare --check`.
|
|
15
|
+
|
|
16
|
+
### Compatibility and upgrade notes
|
|
17
|
+
|
|
18
|
+
- Forge requires Python 3.10 or newer and a POSIX system with Bash. Use existing compiler tools, site modules and pyenv environments; target Python environments do not need Forge installed.
|
|
19
|
+
- Environment selection is explicit. `${python}` refers to Forge's own interpreter; use `python` or `python3` for the interpreter selected by an environment script or named environment.
|
|
20
|
+
- Existing prototype user directories remain in use. Comparisons include activated tool and Python versions; missing activation evidence makes a comparison not comparable.
|
|
21
|
+
- Package installation uses recipe-defined source builds. Bundled official-source adapters cover Eigen and Redis; other imports may require a reviewed recipe. Official metadata uses HTTPS and checksum verification by default; provide `--keyring` to require archive-signature verification.
|
|
22
|
+
- Commands run locally in the foreground. Slurm submission, SSH-disconnect recovery, automatic service management and scientific comparison policies are not included. Installing Redis does not start a server.
|
|
23
|
+
|
|
24
|
+
## 0.1.2
|
|
25
|
+
|
|
26
|
+
- Import and track source metadata from official Debian and Ubuntu repositories.
|
|
27
|
+
- Refresh tracked recipes with `apt update` and detect Debian patch/revision changes with `apt upgrade`.
|
|
28
|
+
- Preserve and apply quilt patch series before building source packages into user prefixes.
|
|
29
|
+
- Record repository origin, suite, source versions, index/archive checksums and signature-verification status.
|
|
30
|
+
- Keep unsupported imports pending and save standard CMake/configure drafts without activating them.
|
|
31
|
+
|
|
32
|
+
## 0.1.1
|
|
33
|
+
|
|
34
|
+
- Add the user-local `jforge apt` command group with catalog search, package details, installation, reinstall, removal, autoremove, source updates, upgrades and version constraints.
|
|
35
|
+
- Bundle pinned Eigen and Redis source recipes and support local and HTTPS recipe indexes.
|
|
36
|
+
- Verify archive checksums, reject unsafe archive entries, resolve recipe dependencies and record real installations under user prefixes.
|
|
37
|
+
- Generate versioned activation scripts and preserve working instances across failed builds and upgrades.
|
|
38
|
+
- Record source recipes, commands, stdout/stderr, checks and removed receipts for package operations.
|
|
39
|
+
|
|
40
|
+
## 0.1.0
|
|
41
|
+
|
|
42
|
+
- Create the independent Jarvis-Forge distribution and `jforge` CLI.
|
|
43
|
+
- Add private user-directory initialization, tool discovery and package-manifest queries.
|
|
44
|
+
- Validate versioned YAML command suites and preview execution without running commands.
|
|
45
|
+
- Execute local acceptance steps with dependency ordering, environment scripts, timeouts and process-group cleanup.
|
|
46
|
+
- Preserve configuration, commands, input snapshots, stdout/stderr, exit status and output artifacts for every run.
|
|
47
|
+
- Query run history and compare archived evidence without repeating tests.
|
|
48
|
+
- Bundle a Python-only smoke suite and a host CLI integration entry point.
|
|
49
|
+
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Jarvis-Forge Developers
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
22
|
+
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
include CHANGELOG.md
|
|
2
|
+
recursive-include tests *.py
|
|
3
|
+
|
|
4
|
+
# Git ignores do not control source distributions.
|
|
5
|
+
exclude jfrel
|
|
6
|
+
prune .github
|
|
7
|
+
prune .agents
|
|
8
|
+
prune .codex
|
|
9
|
+
prune .claude
|
|
10
|
+
prune .venv
|
|
11
|
+
prune .pytest_cache
|
|
12
|
+
prune .aws
|
|
13
|
+
prune .ssh
|
|
14
|
+
prune .pypi
|
|
15
|
+
prune .twine
|
|
16
|
+
global-exclude .DS_Store *.py[cod] .env .env.* .envrc .pypirc .pypirc.* .twinerc .pypi-token* release.env twine.env
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: Jarvis-Forge
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: User-space environments and reproducible command acceptance runs for scientific software
|
|
5
|
+
Author: Jarvis-Forge Developers
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Repository, https://github.com/Pengxuan-Zhu-Phys/Jarvis-Forge
|
|
8
|
+
Project-URL: Issues, https://github.com/Pengxuan-Zhu-Phys/Jarvis-Forge/issues
|
|
9
|
+
Project-URL: Documentation, https://github.com/Pengxuan-Zhu-Phys/Jarvis-Books/tree/main/Docs/Jarvis-Forge
|
|
10
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
11
|
+
Classifier: Environment :: Console
|
|
12
|
+
Classifier: Operating System :: POSIX
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Topic :: Software Development :: Testing
|
|
15
|
+
Requires-Python: >=3.10
|
|
16
|
+
Description-Content-Type: text/markdown
|
|
17
|
+
License-File: LICENSE
|
|
18
|
+
Requires-Dist: typer>=0.16
|
|
19
|
+
Requires-Dist: click>=8.1
|
|
20
|
+
Requires-Dist: rich>=13
|
|
21
|
+
Requires-Dist: PyYAML>=6
|
|
22
|
+
Requires-Dist: jsonschema>=4.18
|
|
23
|
+
Requires-Dist: packaging>=23
|
|
24
|
+
Provides-Extra: dev
|
|
25
|
+
Requires-Dist: pytest>=7; extra == "dev"
|
|
26
|
+
Requires-Dist: build>=1; extra == "dev"
|
|
27
|
+
Requires-Dist: twine>=6; extra == "dev"
|
|
28
|
+
Dynamic: license-file
|
|
29
|
+
|
|
30
|
+
# Jarvis-Forge
|
|
31
|
+
|
|
32
|
+
Jarvis-Forge is an independent Python package for user-space software environments and command-based acceptance workflows on scientific workstations and HPC systems. Its CLI is `jforge`.
|
|
33
|
+
|
|
34
|
+
Forge runs local command suites and preserves their evidence. Its `jforge apt` command downloads, verifies and builds recipe-defined software into private user prefixes. Named environments keep private, versioned shell copies and explicit target Python selections in one shared user directory. Managed services, Slurm submission, scientific comparison policies, and the `Jarvis forge` forwarding command are planned extensions.
|
|
35
|
+
|
|
36
|
+
## Install
|
|
37
|
+
|
|
38
|
+
Python 3.10 or newer and a POSIX system with Bash are required for execution. Use WSL on Windows. Forge does not depend on Jarvis-HEP.
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
python3 -m pip install Jarvis-Forge
|
|
42
|
+
jforge --version
|
|
43
|
+
jforge --help
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
The distribution name is `Jarvis-Forge`. For development from a checkout:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
python3 -m pip install -e '.[dev]'
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Build source and wheel distributions with:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
python3 -m build
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Try the acceptance workflow
|
|
59
|
+
|
|
60
|
+
These commands create a private Forge user directory under the current directory and write a smoke-suite YAML. The demo uses Python only; it does not download software or start services.
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
jforge --home .forge-home init
|
|
64
|
+
jforge example --output smoke.yaml
|
|
65
|
+
jforge validate smoke.yaml
|
|
66
|
+
jforge plan smoke.yaml
|
|
67
|
+
jforge --home .forge-home run smoke.yaml
|
|
68
|
+
jforge --home .forge-home run smoke.yaml
|
|
69
|
+
jforge --home .forge-home history --suite forge-smoke
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Copy the run IDs printed by `run` or listed by `history`:
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
jforge --home .forge-home show <run-id>
|
|
76
|
+
jforge --home .forge-home logs <run-id> --step calculate
|
|
77
|
+
jforge --home .forge-home compare <older-run-id> <newer-run-id>
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
`--json`, `--home` and `--debug` work before or after the command. `--json` emits one JSON object on stdout, while progress goes to stderr. `compare --check` fails on changed, missing, corrupted or unsuccessful evidence; ordinary comparison only describes differences. Comparison uses exact artifact bytes; scientific equivalence and performance regression policies remain outside the current comparison mode.
|
|
81
|
+
|
|
82
|
+
## User directories and package queries
|
|
83
|
+
|
|
84
|
+
Forge uses `~/.jarvis-forge` by default. `--home` overrides `JFORGE_HOME`, which overrides that default. `paths`, `doctor`, `list`, `info`, `validate`, `plan`, `history`, `show` and `logs` do not initialize a user directory or install software.
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
jforge paths
|
|
88
|
+
jforge doctor
|
|
89
|
+
jforge doctor --shell /path/to/cbs-env.sh
|
|
90
|
+
jforge doctor --shell /path/to/cbs-env.sh --json
|
|
91
|
+
jforge list
|
|
92
|
+
jforge info eigen
|
|
93
|
+
jforge info eigen --package-version 3.4.0 --instance <install-id> --path
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
`info` queries JSON installation manifests under `packages/<name>/<version>/<install-id>/manifest.json`. `jforge apt install` creates those records after installation checks pass. Multiple instances are listed explicitly; `--path` requires a unique match. `--package-version` selects installed software; `--version` remains Forge's version query.
|
|
97
|
+
|
|
98
|
+
You select and prepare Python environments with pyenv or your existing tools. `doctor --shell` sources your trusted Bash script and reports the resulting CC/CXX/FC selections, compiler and build-tool paths and versions, Python interpreter paths and versions, virtual environment prefixes, installed Python packages, and selected module/pyenv variables. It does not choose an environment or switch to a fallback. Without `--shell`, it inspects the inherited environment. Missing tools and failed version probes are reported individually; activation errors fail the command. `--timeout` limits the complete inspection, including activation. Shell output is kept separate from JSON results. Inspection creates no Forge user state.
|
|
99
|
+
|
|
100
|
+
## Named environments and target Python
|
|
101
|
+
|
|
102
|
+
All Forge installations for the same user share `~/.jarvis-forge`, independently of the Python version running the CLI. `JFORGE_HOME` and `--home` can explicitly select a different store. Target Python environments do not need Forge installed.
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
jforge env add cbs --shell /path/to/cbs-env.sh
|
|
106
|
+
jforge env list
|
|
107
|
+
jforge env show cbs
|
|
108
|
+
jforge env show cbs --path
|
|
109
|
+
jforge env set-python cbs --python /path/to/existing/venv/bin/python
|
|
110
|
+
# Alternatively, select an existing pyenv environment:
|
|
111
|
+
jforge env set-python cbs --pyenv cbs-python
|
|
112
|
+
jforge doctor --env cbs
|
|
113
|
+
jforge run acceptance.yaml --env cbs
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
`env add` copies the script into `environments/<name>/revisions/<revision>/source.sh` and generates `activate.sh`. It checks Bash syntax without sourcing the script. Registration and Python configuration do not activate an environment in your current shell or set a default for later runs. Choose a profile explicitly with `--env`, `environment.name` in YAML, or `source "$(jforge env show cbs --path)"` in your own shell.
|
|
117
|
+
|
|
118
|
+
`set-python` changes the target Python for that named environment only. Use `--python` for an existing executable, or `--pyenv` for one existing pyenv version/environment; `--pyenv-root` locates non-default version storage. Forge records the actual pyenv program separately from its storage root, supporting package-manager installations. It does not install Python, change pyenv global/local settings, or switch the interpreter running Forge. `--inherit` removes the Python override and uses the script's PATH again. When overridden, both `python` and `python3` use the chosen interpreter; the configured environment's bin directory is also put on PATH.
|
|
119
|
+
|
|
120
|
+
Every `env add ... --replace` or `set-python` saves a new revision and preserves previous scripts. Use `env show cbs --revision <revision>` to inspect an older revision. `env list/show` do not execute scripts. Missing or modified managed files are reported and cannot be selected for execution. Runs archive the chosen revision, original script copy and generated wrappers. The reserved `apt` environment appears in the list after package activation and remains managed by `jforge apt`.
|
|
121
|
+
|
|
122
|
+
Scripts are copied, not relocated together with their dependencies: use stable absolute paths for external files. If the original script changes, register the update with `env add cbs --shell /path/to/cbs-env.sh --replace`. For reproducibility, files in published revisions are not intended for direct editing. Full usage and storage details are in [the environment guide](https://github.com/Pengxuan-Zhu-Phys/Jarvis-Books/blob/main/Docs/Jarvis-Forge/ENVIRONMENTS.md).
|
|
123
|
+
|
|
124
|
+
## User-local package manager
|
|
125
|
+
|
|
126
|
+
`jforge apt` follows familiar apt command names and operates on Forge recipes and user prefixes. It does not invoke system apt, request sudo, or edit shell startup files. Official source-package metadata can be tracked through `apt import`.
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
jforge apt --help
|
|
130
|
+
jforge apt update
|
|
131
|
+
jforge apt search eigen
|
|
132
|
+
jforge apt show eigen
|
|
133
|
+
jforge apt install eigen redis --jobs 2
|
|
134
|
+
jforge apt list --installed
|
|
135
|
+
jforge info eigen
|
|
136
|
+
source "$(jforge apt env --path)"
|
|
137
|
+
redis-server --version
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
Bundled recipes pin Eigen 3.4.0 and Redis 7.2.17 to official source archives and SHA-256 checksums. Eigen needs CMake and C/C++ compilers; Redis needs make and a C compiler. Use your site's existing modules for build tools. Installs do not start a Redis server.
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
jforge apt install eigen=3.4.0 --dry-run
|
|
144
|
+
jforge apt satisfy 'eigen>=3.4' --dry-run
|
|
145
|
+
jforge apt reinstall eigen
|
|
146
|
+
jforge apt upgrade --dry-run
|
|
147
|
+
jforge apt full-upgrade --dry-run
|
|
148
|
+
jforge apt remove eigen=3.4.0 --dry-run
|
|
149
|
+
jforge apt remove eigen=3.4.0 --yes
|
|
150
|
+
jforge apt autoremove --dry-run
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
Every successful instance gets an immutable receipt and activation script; source downloads, recipe snapshots, command logs and checks live in the operation record. Reinstall and upgrade create separate prefixes and preserve old instances. Build or check failure leaves the previous active environment selected. Valid dependencies completed before a later package fails can remain as inactive installations.
|
|
154
|
+
|
|
155
|
+
The catalog contains only configured recipes. Add your own `recipes/*.yaml`, or register a local recipe directory/file or HTTPS YAML index, then refresh it:
|
|
156
|
+
|
|
157
|
+
```bash
|
|
158
|
+
jforge apt edit-sources --add /path/to/recipes
|
|
159
|
+
jforge apt update
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
Bundled recipes change with Forge releases; `update` refreshes configured external sources. `upgrade` resolves newer compatible versions from that catalog. `full-upgrade` uses the same source-recipe resolver and retains old instances; it performs no system-wide removals. Recipe commands are trusted build instructions, not sandboxed code. See the [package manager design and recipe format](https://github.com/Pengxuan-Zhu-Phys/Jarvis-Books/blob/main/Docs/Jarvis-Forge/APT.md).
|
|
163
|
+
|
|
164
|
+
### Track official Debian and Ubuntu source packages
|
|
165
|
+
|
|
166
|
+
```bash
|
|
167
|
+
jforge apt import libeigen3-dev --origin debian --suite bookworm --name eigen
|
|
168
|
+
jforge apt update
|
|
169
|
+
jforge apt list --upgradable
|
|
170
|
+
jforge apt upgrade --dry-run
|
|
171
|
+
jforge apt upgrade
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
Import maps a binary or source package name through the official `Sources` index, records source versions and SHA-256, and preserves Debian quilt patches. A reviewed Forge template supplies user-prefix build options and checks. Built-in source adapters cover Eigen and Redis; `--template NAME` reuses a custom Forge recipe. Ubuntu sources use `--origin ubuntu --suite <codename>`.
|
|
175
|
+
|
|
176
|
+
`update` refreshes these tracked imports without compiling. `upgrade` detects both upstream changes and Debian revision/patch changes, creates new instances, and keeps old ones. Identical official metadata does not force a rebuild. Packages without an adapter are reported as pending; standard CMake/configure layouts receive a draft YAML for review. Drafts do not enter the install catalog or silently become valid updates. Debian Build-Depends fields are retained in the report; they are not blindly translated into Forge dependencies.
|
|
177
|
+
|
|
178
|
+
Default metadata trust is official HTTPS plus Release/index/archive checksums, reported as `apt_signature_verified: false`. To require archive-signature verification, supply `--keyring /path/to/trusted-archive-keyring.gpg`; this requires `gpgv` and fails if verification cannot be completed. The importer builds upstream projects with quilt patches; it does not execute `debian/rules` or reproduce the full Debian binary-package build.
|
|
179
|
+
|
|
180
|
+
## Suite format
|
|
181
|
+
|
|
182
|
+
Suites use `schema_version: 1`, a stable `id`, and ordered command steps. Each step chooses either `argv` or an explicit Bash `script`, with optional `needs`, `cwd`, `timeout_seconds`, `expect_exit_code` and required `artifacts`. Commands and scripts are trusted user code.
|
|
183
|
+
|
|
184
|
+
The default working directory is the run's shared `workspace/`. Declared artifacts are relative file paths within the step's working directory; each is copied into the run archive. Supported placeholders are `${python}`, `${suite_dir}`, `${run_dir}`, `${step_dir}` and `${input:name}`. Inputs are declared as named file paths relative to the suite file and copied before execution.
|
|
185
|
+
|
|
186
|
+
Use `environment.name: cbs` to select a registered environment, optionally pinned with `environment.revision`. A CLI `--env` explicitly overrides the suite selection and uses the named environment's current revision. Alternatively, `environment.shell` points to a Bash script, relative to the suite file. These two YAML selections are mutually exclusive. It is snapshotted and sourced before each command, in the same shell. `environment.variables` supplies string-valued variables. The recorded plan and raw logs may include values supplied by the user; keep credentials out of suite files and command arguments.
|
|
187
|
+
|
|
188
|
+
The script must initialize your selected environment in a noninteractive Bash; login shell startup files are not loaded. Different suites may select different scripts. For example:
|
|
189
|
+
|
|
190
|
+
```yaml
|
|
191
|
+
schema_version: 1
|
|
192
|
+
id: cbs-environment
|
|
193
|
+
environment:
|
|
194
|
+
shell: ./cbs-env.sh
|
|
195
|
+
steps:
|
|
196
|
+
- id: python
|
|
197
|
+
argv: [python, --version]
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
Use `python` or `python3` for the interpreter selected by that script. `${python}` always refers to the interpreter running Forge itself, which can be different. Each executed step saves `activation.json` and includes its environment report in `show --step`; reports contain actual tool versions and target Python package inventories. Comparisons include these activated environments, so changing a compiler or Python environment is visible even when commands and script contents are unchanged. Missing activation records make the affected comparison not comparable. Version probes do not compile code or establish that dependencies meet a particular project's requirements.
|
|
201
|
+
|
|
202
|
+
Every run has a new ID and saves configuration, environment observations, actual commands, activation details, logs, exit status, elapsed time, and declared output files. Source code and arbitrary undeclared outputs are not archived automatically. These records support comparison; they are not a complete machine image or automatic source backup. Failed prerequisites block dependent steps; independent steps continue. Foreground execution does not promise survival after SSH disconnection.
|
|
203
|
+
|
|
204
|
+
## Development and integration
|
|
205
|
+
|
|
206
|
+
```bash
|
|
207
|
+
python3 -m pytest
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
The host integration point is `jarvis_forge.cli.main(argv, prog="Jarvis forge")`; it returns an exit code and owns the single parser. The standalone console script is operational. Jarvis-HEP forwarding is not yet integrated.
|
|
211
|
+
|
|
212
|
+
Project design and implementation scope live in [Jarvis-Books](https://github.com/Pengxuan-Zhu-Phys/Jarvis-Books/tree/main/Docs/Jarvis-Forge). CLI behavior follows the [Jarvis ecosystem CLI specification](https://github.com/Pengxuan-Zhu-Phys/Jarvis-Books/blob/main/Docs/Ecosystem/JARVIS_CLI_DESIGN.md).
|
|
213
|
+
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
# Jarvis-Forge
|
|
2
|
+
|
|
3
|
+
Jarvis-Forge is an independent Python package for user-space software environments and command-based acceptance workflows on scientific workstations and HPC systems. Its CLI is `jforge`.
|
|
4
|
+
|
|
5
|
+
Forge runs local command suites and preserves their evidence. Its `jforge apt` command downloads, verifies and builds recipe-defined software into private user prefixes. Named environments keep private, versioned shell copies and explicit target Python selections in one shared user directory. Managed services, Slurm submission, scientific comparison policies, and the `Jarvis forge` forwarding command are planned extensions.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
Python 3.10 or newer and a POSIX system with Bash are required for execution. Use WSL on Windows. Forge does not depend on Jarvis-HEP.
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
python3 -m pip install Jarvis-Forge
|
|
13
|
+
jforge --version
|
|
14
|
+
jforge --help
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
The distribution name is `Jarvis-Forge`. For development from a checkout:
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
python3 -m pip install -e '.[dev]'
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Build source and wheel distributions with:
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
python3 -m build
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Try the acceptance workflow
|
|
30
|
+
|
|
31
|
+
These commands create a private Forge user directory under the current directory and write a smoke-suite YAML. The demo uses Python only; it does not download software or start services.
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
jforge --home .forge-home init
|
|
35
|
+
jforge example --output smoke.yaml
|
|
36
|
+
jforge validate smoke.yaml
|
|
37
|
+
jforge plan smoke.yaml
|
|
38
|
+
jforge --home .forge-home run smoke.yaml
|
|
39
|
+
jforge --home .forge-home run smoke.yaml
|
|
40
|
+
jforge --home .forge-home history --suite forge-smoke
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Copy the run IDs printed by `run` or listed by `history`:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
jforge --home .forge-home show <run-id>
|
|
47
|
+
jforge --home .forge-home logs <run-id> --step calculate
|
|
48
|
+
jforge --home .forge-home compare <older-run-id> <newer-run-id>
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
`--json`, `--home` and `--debug` work before or after the command. `--json` emits one JSON object on stdout, while progress goes to stderr. `compare --check` fails on changed, missing, corrupted or unsuccessful evidence; ordinary comparison only describes differences. Comparison uses exact artifact bytes; scientific equivalence and performance regression policies remain outside the current comparison mode.
|
|
52
|
+
|
|
53
|
+
## User directories and package queries
|
|
54
|
+
|
|
55
|
+
Forge uses `~/.jarvis-forge` by default. `--home` overrides `JFORGE_HOME`, which overrides that default. `paths`, `doctor`, `list`, `info`, `validate`, `plan`, `history`, `show` and `logs` do not initialize a user directory or install software.
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
jforge paths
|
|
59
|
+
jforge doctor
|
|
60
|
+
jforge doctor --shell /path/to/cbs-env.sh
|
|
61
|
+
jforge doctor --shell /path/to/cbs-env.sh --json
|
|
62
|
+
jforge list
|
|
63
|
+
jforge info eigen
|
|
64
|
+
jforge info eigen --package-version 3.4.0 --instance <install-id> --path
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
`info` queries JSON installation manifests under `packages/<name>/<version>/<install-id>/manifest.json`. `jforge apt install` creates those records after installation checks pass. Multiple instances are listed explicitly; `--path` requires a unique match. `--package-version` selects installed software; `--version` remains Forge's version query.
|
|
68
|
+
|
|
69
|
+
You select and prepare Python environments with pyenv or your existing tools. `doctor --shell` sources your trusted Bash script and reports the resulting CC/CXX/FC selections, compiler and build-tool paths and versions, Python interpreter paths and versions, virtual environment prefixes, installed Python packages, and selected module/pyenv variables. It does not choose an environment or switch to a fallback. Without `--shell`, it inspects the inherited environment. Missing tools and failed version probes are reported individually; activation errors fail the command. `--timeout` limits the complete inspection, including activation. Shell output is kept separate from JSON results. Inspection creates no Forge user state.
|
|
70
|
+
|
|
71
|
+
## Named environments and target Python
|
|
72
|
+
|
|
73
|
+
All Forge installations for the same user share `~/.jarvis-forge`, independently of the Python version running the CLI. `JFORGE_HOME` and `--home` can explicitly select a different store. Target Python environments do not need Forge installed.
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
jforge env add cbs --shell /path/to/cbs-env.sh
|
|
77
|
+
jforge env list
|
|
78
|
+
jforge env show cbs
|
|
79
|
+
jforge env show cbs --path
|
|
80
|
+
jforge env set-python cbs --python /path/to/existing/venv/bin/python
|
|
81
|
+
# Alternatively, select an existing pyenv environment:
|
|
82
|
+
jforge env set-python cbs --pyenv cbs-python
|
|
83
|
+
jforge doctor --env cbs
|
|
84
|
+
jforge run acceptance.yaml --env cbs
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
`env add` copies the script into `environments/<name>/revisions/<revision>/source.sh` and generates `activate.sh`. It checks Bash syntax without sourcing the script. Registration and Python configuration do not activate an environment in your current shell or set a default for later runs. Choose a profile explicitly with `--env`, `environment.name` in YAML, or `source "$(jforge env show cbs --path)"` in your own shell.
|
|
88
|
+
|
|
89
|
+
`set-python` changes the target Python for that named environment only. Use `--python` for an existing executable, or `--pyenv` for one existing pyenv version/environment; `--pyenv-root` locates non-default version storage. Forge records the actual pyenv program separately from its storage root, supporting package-manager installations. It does not install Python, change pyenv global/local settings, or switch the interpreter running Forge. `--inherit` removes the Python override and uses the script's PATH again. When overridden, both `python` and `python3` use the chosen interpreter; the configured environment's bin directory is also put on PATH.
|
|
90
|
+
|
|
91
|
+
Every `env add ... --replace` or `set-python` saves a new revision and preserves previous scripts. Use `env show cbs --revision <revision>` to inspect an older revision. `env list/show` do not execute scripts. Missing or modified managed files are reported and cannot be selected for execution. Runs archive the chosen revision, original script copy and generated wrappers. The reserved `apt` environment appears in the list after package activation and remains managed by `jforge apt`.
|
|
92
|
+
|
|
93
|
+
Scripts are copied, not relocated together with their dependencies: use stable absolute paths for external files. If the original script changes, register the update with `env add cbs --shell /path/to/cbs-env.sh --replace`. For reproducibility, files in published revisions are not intended for direct editing. Full usage and storage details are in [the environment guide](https://github.com/Pengxuan-Zhu-Phys/Jarvis-Books/blob/main/Docs/Jarvis-Forge/ENVIRONMENTS.md).
|
|
94
|
+
|
|
95
|
+
## User-local package manager
|
|
96
|
+
|
|
97
|
+
`jforge apt` follows familiar apt command names and operates on Forge recipes and user prefixes. It does not invoke system apt, request sudo, or edit shell startup files. Official source-package metadata can be tracked through `apt import`.
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
jforge apt --help
|
|
101
|
+
jforge apt update
|
|
102
|
+
jforge apt search eigen
|
|
103
|
+
jforge apt show eigen
|
|
104
|
+
jforge apt install eigen redis --jobs 2
|
|
105
|
+
jforge apt list --installed
|
|
106
|
+
jforge info eigen
|
|
107
|
+
source "$(jforge apt env --path)"
|
|
108
|
+
redis-server --version
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
Bundled recipes pin Eigen 3.4.0 and Redis 7.2.17 to official source archives and SHA-256 checksums. Eigen needs CMake and C/C++ compilers; Redis needs make and a C compiler. Use your site's existing modules for build tools. Installs do not start a Redis server.
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
jforge apt install eigen=3.4.0 --dry-run
|
|
115
|
+
jforge apt satisfy 'eigen>=3.4' --dry-run
|
|
116
|
+
jforge apt reinstall eigen
|
|
117
|
+
jforge apt upgrade --dry-run
|
|
118
|
+
jforge apt full-upgrade --dry-run
|
|
119
|
+
jforge apt remove eigen=3.4.0 --dry-run
|
|
120
|
+
jforge apt remove eigen=3.4.0 --yes
|
|
121
|
+
jforge apt autoremove --dry-run
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
Every successful instance gets an immutable receipt and activation script; source downloads, recipe snapshots, command logs and checks live in the operation record. Reinstall and upgrade create separate prefixes and preserve old instances. Build or check failure leaves the previous active environment selected. Valid dependencies completed before a later package fails can remain as inactive installations.
|
|
125
|
+
|
|
126
|
+
The catalog contains only configured recipes. Add your own `recipes/*.yaml`, or register a local recipe directory/file or HTTPS YAML index, then refresh it:
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
jforge apt edit-sources --add /path/to/recipes
|
|
130
|
+
jforge apt update
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
Bundled recipes change with Forge releases; `update` refreshes configured external sources. `upgrade` resolves newer compatible versions from that catalog. `full-upgrade` uses the same source-recipe resolver and retains old instances; it performs no system-wide removals. Recipe commands are trusted build instructions, not sandboxed code. See the [package manager design and recipe format](https://github.com/Pengxuan-Zhu-Phys/Jarvis-Books/blob/main/Docs/Jarvis-Forge/APT.md).
|
|
134
|
+
|
|
135
|
+
### Track official Debian and Ubuntu source packages
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
jforge apt import libeigen3-dev --origin debian --suite bookworm --name eigen
|
|
139
|
+
jforge apt update
|
|
140
|
+
jforge apt list --upgradable
|
|
141
|
+
jforge apt upgrade --dry-run
|
|
142
|
+
jforge apt upgrade
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
Import maps a binary or source package name through the official `Sources` index, records source versions and SHA-256, and preserves Debian quilt patches. A reviewed Forge template supplies user-prefix build options and checks. Built-in source adapters cover Eigen and Redis; `--template NAME` reuses a custom Forge recipe. Ubuntu sources use `--origin ubuntu --suite <codename>`.
|
|
146
|
+
|
|
147
|
+
`update` refreshes these tracked imports without compiling. `upgrade` detects both upstream changes and Debian revision/patch changes, creates new instances, and keeps old ones. Identical official metadata does not force a rebuild. Packages without an adapter are reported as pending; standard CMake/configure layouts receive a draft YAML for review. Drafts do not enter the install catalog or silently become valid updates. Debian Build-Depends fields are retained in the report; they are not blindly translated into Forge dependencies.
|
|
148
|
+
|
|
149
|
+
Default metadata trust is official HTTPS plus Release/index/archive checksums, reported as `apt_signature_verified: false`. To require archive-signature verification, supply `--keyring /path/to/trusted-archive-keyring.gpg`; this requires `gpgv` and fails if verification cannot be completed. The importer builds upstream projects with quilt patches; it does not execute `debian/rules` or reproduce the full Debian binary-package build.
|
|
150
|
+
|
|
151
|
+
## Suite format
|
|
152
|
+
|
|
153
|
+
Suites use `schema_version: 1`, a stable `id`, and ordered command steps. Each step chooses either `argv` or an explicit Bash `script`, with optional `needs`, `cwd`, `timeout_seconds`, `expect_exit_code` and required `artifacts`. Commands and scripts are trusted user code.
|
|
154
|
+
|
|
155
|
+
The default working directory is the run's shared `workspace/`. Declared artifacts are relative file paths within the step's working directory; each is copied into the run archive. Supported placeholders are `${python}`, `${suite_dir}`, `${run_dir}`, `${step_dir}` and `${input:name}`. Inputs are declared as named file paths relative to the suite file and copied before execution.
|
|
156
|
+
|
|
157
|
+
Use `environment.name: cbs` to select a registered environment, optionally pinned with `environment.revision`. A CLI `--env` explicitly overrides the suite selection and uses the named environment's current revision. Alternatively, `environment.shell` points to a Bash script, relative to the suite file. These two YAML selections are mutually exclusive. It is snapshotted and sourced before each command, in the same shell. `environment.variables` supplies string-valued variables. The recorded plan and raw logs may include values supplied by the user; keep credentials out of suite files and command arguments.
|
|
158
|
+
|
|
159
|
+
The script must initialize your selected environment in a noninteractive Bash; login shell startup files are not loaded. Different suites may select different scripts. For example:
|
|
160
|
+
|
|
161
|
+
```yaml
|
|
162
|
+
schema_version: 1
|
|
163
|
+
id: cbs-environment
|
|
164
|
+
environment:
|
|
165
|
+
shell: ./cbs-env.sh
|
|
166
|
+
steps:
|
|
167
|
+
- id: python
|
|
168
|
+
argv: [python, --version]
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
Use `python` or `python3` for the interpreter selected by that script. `${python}` always refers to the interpreter running Forge itself, which can be different. Each executed step saves `activation.json` and includes its environment report in `show --step`; reports contain actual tool versions and target Python package inventories. Comparisons include these activated environments, so changing a compiler or Python environment is visible even when commands and script contents are unchanged. Missing activation records make the affected comparison not comparable. Version probes do not compile code or establish that dependencies meet a particular project's requirements.
|
|
172
|
+
|
|
173
|
+
Every run has a new ID and saves configuration, environment observations, actual commands, activation details, logs, exit status, elapsed time, and declared output files. Source code and arbitrary undeclared outputs are not archived automatically. These records support comparison; they are not a complete machine image or automatic source backup. Failed prerequisites block dependent steps; independent steps continue. Foreground execution does not promise survival after SSH disconnection.
|
|
174
|
+
|
|
175
|
+
## Development and integration
|
|
176
|
+
|
|
177
|
+
```bash
|
|
178
|
+
python3 -m pytest
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
The host integration point is `jarvis_forge.cli.main(argv, prog="Jarvis forge")`; it returns an exit code and owns the single parser. The standalone console script is operational. Jarvis-HEP forwarding is not yet integrated.
|
|
182
|
+
|
|
183
|
+
Project design and implementation scope live in [Jarvis-Books](https://github.com/Pengxuan-Zhu-Phys/Jarvis-Books/tree/main/Docs/Jarvis-Forge). CLI behavior follows the [Jarvis ecosystem CLI specification](https://github.com/Pengxuan-Zhu-Phys/Jarvis-Books/blob/main/Docs/Ecosystem/JARVIS_CLI_DESIGN.md).
|
|
184
|
+
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=77", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "Jarvis-Forge"
|
|
7
|
+
dynamic = ["version"]
|
|
8
|
+
description = "User-space environments and reproducible command acceptance runs for scientific software"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.10"
|
|
11
|
+
license = "MIT"
|
|
12
|
+
authors = [{name = "Jarvis-Forge Developers"}]
|
|
13
|
+
classifiers = [
|
|
14
|
+
"Development Status :: 5 - Production/Stable",
|
|
15
|
+
"Environment :: Console",
|
|
16
|
+
"Operating System :: POSIX",
|
|
17
|
+
"Programming Language :: Python :: 3",
|
|
18
|
+
"Topic :: Software Development :: Testing",
|
|
19
|
+
]
|
|
20
|
+
dependencies = ["typer>=0.16", "click>=8.1", "rich>=13", "PyYAML>=6", "jsonschema>=4.18", "packaging>=23"]
|
|
21
|
+
|
|
22
|
+
[project.optional-dependencies]
|
|
23
|
+
dev = ["pytest>=7", "build>=1", "twine>=6"]
|
|
24
|
+
|
|
25
|
+
[project.scripts]
|
|
26
|
+
jforge = "jarvis_forge.cli:main"
|
|
27
|
+
|
|
28
|
+
[project.urls]
|
|
29
|
+
Repository = "https://github.com/Pengxuan-Zhu-Phys/Jarvis-Forge"
|
|
30
|
+
Issues = "https://github.com/Pengxuan-Zhu-Phys/Jarvis-Forge/issues"
|
|
31
|
+
Documentation = "https://github.com/Pengxuan-Zhu-Phys/Jarvis-Books/tree/main/Docs/Jarvis-Forge"
|
|
32
|
+
|
|
33
|
+
[tool.setuptools.dynamic]
|
|
34
|
+
version = {attr = "jarvis_forge.__version__"}
|
|
35
|
+
|
|
36
|
+
[tool.setuptools.packages.find]
|
|
37
|
+
where = ["src"]
|
|
38
|
+
|
|
39
|
+
[tool.setuptools.package-data]
|
|
40
|
+
jarvis_forge = ["schemas/*.json", "examples/*.yaml", "recipes/*.yaml"]
|
|
41
|
+
|
|
42
|
+
[tool.pytest.ini_options]
|
|
43
|
+
testpaths = ["tests"]
|
|
44
|
+
pythonpath = ["src"]
|
|
45
|
+
|