valise-sh 0.0.0-stage → 0.2.0
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.
- package/CHANGELOG.md +177 -0
- package/LICENSE +21 -0
- package/README.md +169 -2
- package/bin/valise +5427 -0
- package/docs/architecture.md +146 -0
- package/docs/contrib-modules.md +246 -0
- package/docs/installation.md +248 -0
- package/docs/module-abi.md +404 -0
- package/docs/release-policy.md +154 -0
- package/docs/shared-modules.md +219 -0
- package/docs/variants.md +327 -0
- package/entrypoints/.gitkeep +0 -0
- package/entrypoints/fish/profile.fish +99 -0
- package/entrypoints/profile.sh +123 -0
- package/examples/README.md +44 -0
- package/examples/e2e/README.md +113 -0
- package/examples/e2e/build-manifest.sh +138 -0
- package/examples/e2e/module.d/e2e_aliases.meta +9 -0
- package/examples/e2e/module.d/e2e_completions_bash.meta +9 -0
- package/examples/e2e/module.d/e2e_completions_zsh.meta +9 -0
- package/examples/e2e/module.d/e2e_env_setup.meta +9 -0
- package/examples/e2e/module.d/e2e_fish_features.meta +9 -0
- package/examples/e2e/module.d/e2e_generated_config.meta +9 -0
- package/examples/e2e/module.d/e2e_ksh_features.meta +9 -0
- package/examples/e2e/module.d/e2e_layer_probe.meta +9 -0
- package/examples/e2e/module.d/e2e_optional_network.meta +9 -0
- package/examples/e2e/module.d/e2e_platform_tools_bsd.meta +9 -0
- package/examples/e2e/module.d/e2e_platform_tools_darwin.meta +9 -0
- package/examples/e2e/module.d/e2e_platform_tools_linux.meta +9 -0
- package/examples/e2e/modules/e2e/aliases.sh +19 -0
- package/examples/e2e/modules/e2e/completions_bash.sh +25 -0
- package/examples/e2e/modules/e2e/completions_zsh.sh +26 -0
- package/examples/e2e/modules/e2e/env_setup.sh +16 -0
- package/examples/e2e/modules/e2e/fish_features.fish +15 -0
- package/examples/e2e/modules/e2e/generated_config.sh +15 -0
- package/examples/e2e/modules/e2e/ksh_features.sh +22 -0
- package/examples/e2e/modules/e2e/layer_probe.sh +18 -0
- package/examples/e2e/modules/e2e/optional_network.sh +27 -0
- package/examples/e2e/modules/e2e/platform_tools_bsd.sh +16 -0
- package/examples/e2e/modules/e2e/platform_tools_darwin.sh +16 -0
- package/examples/e2e/modules/e2e/platform_tools_linux.sh +19 -0
- package/examples/local/.gitkeep +0 -0
- package/examples/local/module.d/hello_valise.meta +9 -0
- package/examples/local/modules/hello_valise.sh +6 -0
- package/examples/profile-project/README.md +181 -0
- package/examples/profile-project/shell/layers/demo/module.d/contrib_demo_greeting.meta +10 -0
- package/examples/profile-project/shell/layers/demo/modules/shared/contrib_demo_greeting.sh +4 -0
- package/examples/profile-project/shell/module.d/greeting.meta +10 -0
- package/examples/profile-project/shell/module.d/profile_main.meta +9 -0
- package/examples/profile-project/shell/modules/greeting.sh +5 -0
- package/examples/profile-project/shell/release/bundle-roots +9 -0
- package/examples/profile-project/shell/release/install-variants +3 -0
- package/examples/profile-project/shell/release/module-registry.tsv +4 -0
- package/examples/profile-project/shell/release/project.conf +3 -0
- package/examples/shared/README.md +49 -0
- package/examples/shared/module.d/contrib_shared_paths.meta +10 -0
- package/examples/shared/module.d/contrib_shared_umask.meta +10 -0
- package/examples/shared/modules/shared/contrib_shared_paths.sh +16 -0
- package/examples/shared/modules/shared/contrib_shared_umask.sh +14 -0
- package/lib/.gitkeep +0 -0
- package/lib/capabilities.sh +769 -0
- package/lib/compiler.awk +537 -0
- package/lib/fish/loader.fish +2308 -0
- package/lib/fish/metadata.fish +299 -0
- package/lib/loader.sh +1670 -0
- package/lib/metadata.sh +398 -0
- package/manifests/.gitkeep +0 -0
- package/manifests/parser-support.tsv +11 -0
- package/module.d/.gitkeep +0 -0
- package/module.d/contrib_editor.meta +10 -0
- package/module.d/contrib_history.meta +10 -0
- package/module.d/contrib_pager.meta +10 -0
- package/module.d/contrib_path.meta +10 -0
- package/module.d/contrib_xdg.meta +10 -0
- package/module.d/platform_bsd.meta +9 -0
- package/module.d/platform_linux.meta +9 -0
- package/module.d/platform_macos.meta +9 -0
- package/module.d/platform_posix.meta +9 -0
- package/modules/.gitkeep +0 -0
- package/modules/platform/bsd/capabilities.sh +14 -0
- package/modules/platform/linux/capabilities.sh +9 -0
- package/modules/platform/macos/capabilities.sh +10 -0
- package/modules/platform/posix.sh +13 -0
- package/modules/system/contrib_editor.sh +35 -0
- package/modules/system/contrib_history.sh +19 -0
- package/modules/system/contrib_pager.sh +28 -0
- package/modules/system/contrib_path.sh +84 -0
- package/modules/system/contrib_xdg.sh +31 -0
- package/package.json +39 -4
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
Notable user-facing changes are recorded here. Versions before 1.0 may include
|
|
4
|
+
module ABI or CLI changes; see [the release policy](docs/release-policy.md).
|
|
5
|
+
|
|
6
|
+
## [Unreleased]
|
|
7
|
+
|
|
8
|
+
## [0.2.0] - 2026-10-31
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- `valise new`, `valise module new`, `valise module list`,
|
|
13
|
+
`valise module remove`, `valise build`, `valise apply`, and
|
|
14
|
+
`valise status`. A new project can be scaffolded, given a module, built,
|
|
15
|
+
installed, and checked without hand-writing a registry or a build script.
|
|
16
|
+
`valise module new` writes the module body and its declared export, and
|
|
17
|
+
wires the module into the seed aggregator. `valise apply` builds, installs,
|
|
18
|
+
writes the shell integration, and verifies the result; it is idempotent.
|
|
19
|
+
`valise status` reports the project, the active release, the integration
|
|
20
|
+
state, and whether the active release has drifted from the build output.
|
|
21
|
+
- `valise registry`, which generates `shell/release/module-registry.tsv` from
|
|
22
|
+
the project's metadata. `valise build` regenerates and validates the
|
|
23
|
+
registry, so a committed registry is a generated artifact rather than a
|
|
24
|
+
hand-maintained catalog. The row order is fixed: the primary modules of
|
|
25
|
+
`shell/module.d/` first, then the layer modules of each
|
|
26
|
+
`shell/layers/<provider>/module.d/`, each group in C-locale name order.
|
|
27
|
+
- `valise release list`, `valise release use`, `valise release prune`, and
|
|
28
|
+
`valise release verify`. They manage installed releases; source variants
|
|
29
|
+
remain the business of `valise build` and `valise apply`.
|
|
30
|
+
- Command-specific `--help` for `build`, `compile`, `install`, `init`, `new`,
|
|
31
|
+
`module`, `release`, `doctor`, and `status`, so each prints its own
|
|
32
|
+
contract rather than the global command list.
|
|
33
|
+
- Meta modules: metadata with `requires=` and no `load` is a
|
|
34
|
+
dependency-only aggregator and loads successfully without a body. `load`
|
|
35
|
+
and `requires` may be combined.
|
|
36
|
+
- `side_effect=local-state`, a source-safe side-effect class for modules
|
|
37
|
+
that write under the XDG state directory.
|
|
38
|
+
- `VALISE_RELOAD=1`, which unsets the declared exports of the requested
|
|
39
|
+
closure before loading so a profile can be re-sourced.
|
|
40
|
+
- The `sp_cap_*` capability helpers remain available at runtime after a
|
|
41
|
+
compiled plan or a loader load finishes, so a module can call them.
|
|
42
|
+
- `examples/profile-project/`, a complete consuming project with two
|
|
43
|
+
modules, a provider layer, two variants, and a bundle, and a README that
|
|
44
|
+
walks from clone to a loaded profile.
|
|
45
|
+
- A consumer end-to-end test target that builds the reference consumer
|
|
46
|
+
profile from a temporary copy, runs the consumer's own metadata, shells,
|
|
47
|
+
release, and features suites, installs and verifies the release, and
|
|
48
|
+
proves a second build is byte-identical. The original tree and the live
|
|
49
|
+
profile are never touched.
|
|
50
|
+
|
|
51
|
+
### Changed
|
|
52
|
+
|
|
53
|
+
- `valise build` builds a complete release tree to `build/release` by
|
|
54
|
+
default, reads the variant and bundle defaults from
|
|
55
|
+
`shell/release/project.conf`, and requires an explicit output directory to
|
|
56
|
+
be empty or absent. A failed build preserves the previous build output.
|
|
57
|
+
- `valise build` produces no Fish surface: no Fish entrypoint, generated
|
|
58
|
+
plan, or native loader. A built release therefore loads nothing in Fish;
|
|
59
|
+
the Fish hook verifies the active release and stays silent. Only an engine
|
|
60
|
+
release with `entrypoints/fish/profile.fish` uses the native Fish loader.
|
|
61
|
+
- `valise install` writes shell integration by default. It always writes
|
|
62
|
+
`~/.profile`; it adds `~/.bash_profile` or `~/.bash_login` when one of
|
|
63
|
+
those exists, because bash reads that file instead of `~/.profile`; it
|
|
64
|
+
writes `~/.bashrc` when bash is the current shell or that file exists; it
|
|
65
|
+
writes `~/.zprofile` when zsh is on `PATH` or that file exists, because zsh
|
|
66
|
+
reads nothing else at login; and it writes `~/.zshrc` when zsh is the
|
|
67
|
+
current shell or that file exists. Existing files are kept current rather
|
|
68
|
+
than replaced. A symlinked startup file is reported and left untouched.
|
|
69
|
+
`--no-integration` installs without writing any startup file. Install also
|
|
70
|
+
writes the Fish `conf.d` hook when it finds Fish in a trusted location;
|
|
71
|
+
`valise apply` runs the same install path.
|
|
72
|
+
- The startup integration is a managed block between `# BEGIN valise managed
|
|
73
|
+
block` and `# END valise managed block`. Repeat installs are idempotent and
|
|
74
|
+
existing profile content is preserved. An unpaired marker is refused and
|
|
75
|
+
stops the install. Install prints each path it wrote and how to remove the
|
|
76
|
+
block.
|
|
77
|
+
- `valise init` takes `posix` or `fish`; any other argument is rejected.
|
|
78
|
+
It is a one-time snippet generator, not something to evaluate at every
|
|
79
|
+
prompt.
|
|
80
|
+
- A project's default variant is `default`. An unknown variant is an error
|
|
81
|
+
in every command that accepts one.
|
|
82
|
+
- Compiled plans and the loader now agree on required dependency closure.
|
|
83
|
+
Platform skips are recorded during discovery and reported once the full
|
|
84
|
+
required closure is known; strict mode fails when a required module is
|
|
85
|
+
blocked during ordering; permissive mode continues and returns zero. Fish
|
|
86
|
+
reports a platform-skipped optional dependency silently.
|
|
87
|
+
- Compiled plans reach parity with the loader: they gate modules by
|
|
88
|
+
`platforms=` at runtime, pre-check and post-check declared exports, report
|
|
89
|
+
each failing module by name, continue past a failure in permissive mode
|
|
90
|
+
while returning zero, stop in strict mode, and support meta modules with no
|
|
91
|
+
source line.
|
|
92
|
+
- The loader saves the logical `$PWD` and `$OLDPWD` before sourcing each
|
|
93
|
+
module and restores them afterwards, so a module that changes directory
|
|
94
|
+
during its load leaves the caller's logical directory as it was.
|
|
95
|
+
- The loader's export pre-check accepts a name that currently resolves to an
|
|
96
|
+
external command, which is how a deliberate wrapper is exported. It still
|
|
97
|
+
rejects a name already defined as a function, builtin, or alias.
|
|
98
|
+
- The loader resolves each metadata record with shell builtins instead of
|
|
99
|
+
repeated `sed`, `grep`, and `cat` processes, so the number of external
|
|
100
|
+
processes a load spawns does not grow with the number of modules.
|
|
101
|
+
- `valise compile` and `valise build` find the packaged
|
|
102
|
+
`lib/capabilities.sh` relative to the CLI, so a symlinked or relocated
|
|
103
|
+
install works. A compiled plan rejects a module that has neither a load
|
|
104
|
+
path nor dependencies, and names the module.
|
|
105
|
+
- Layer handling accepts any `shell/layers/<provider>` path rather than only
|
|
106
|
+
the `contrib` provider, and produces a deterministic manifest.
|
|
107
|
+
- `valise doctor` reports a missing active release as a failure and reads the
|
|
108
|
+
startup files the running shell actually reads. `--pre-install` skips the
|
|
109
|
+
release and integration checks; `--no-integration` checks only the
|
|
110
|
+
environment and the active release.
|
|
111
|
+
- `valise explain-bundles` and `valise layer-lint` are implemented in POSIX sh
|
|
112
|
+
and awk. `layer-lint` validates a provider layer's structure, `contrib_`
|
|
113
|
+
name prefix, version, load path, symlink freedom, file modes, and
|
|
114
|
+
dependency containment.
|
|
115
|
+
- The unused Python consumer-release helpers, wrapper lifecycle hooks, and
|
|
116
|
+
the submodule build prelude override are gone. No command requires
|
|
117
|
+
Python 3.
|
|
118
|
+
|
|
119
|
+
### Removed
|
|
120
|
+
|
|
121
|
+
- `load_hook` and the compatibility bridge in the POSIX loader, the Fish
|
|
122
|
+
loader, and compiled plans. A module declares `load`, `requires`, or both.
|
|
123
|
+
Metadata naming `load_hook` fails with
|
|
124
|
+
`metadata field load_hook is not supported; use load`.
|
|
125
|
+
- `variant list`, `variant use`, and `verify-active`; installed releases are
|
|
126
|
+
managed by `valise release list|use|prune|verify`. `variant` now refers
|
|
127
|
+
only to build variants.
|
|
128
|
+
- The per-shell `valise init` arguments `bash`, `zsh`, `ksh`, and `sh`; use
|
|
129
|
+
`valise init posix` or `valise init fish`.
|
|
130
|
+
|
|
131
|
+
### Fixed
|
|
132
|
+
|
|
133
|
+
- `valise` with no arguments: under `set -e`, a zero-argument `shift` could
|
|
134
|
+
terminate the CLI before it displayed its help text.
|
|
135
|
+
- Fish activation: functions loaded from package paths such as Homebrew are
|
|
136
|
+
authenticated and preserved through the load instead of being rejected or
|
|
137
|
+
lost.
|
|
138
|
+
- The primary-root symlink diagnostic was printed on stdout while every
|
|
139
|
+
other loader diagnostic went to stderr.
|
|
140
|
+
- `valise compile` reported that a Fish plan requires a Python compiler and
|
|
141
|
+
named a file that does not exist in this repository. Fish plans are not
|
|
142
|
+
generated; a Fish integration uses the native Fish loader.
|
|
143
|
+
- Applying to a home directory with a trailing slash could skip the zsh
|
|
144
|
+
startup file, because the target was compared against the raw `HOME`
|
|
145
|
+
string rather than a normalized path.
|
|
146
|
+
- A built release's Fish hook printed an error on every Fish start. It now
|
|
147
|
+
verifies the release quietly and returns when there is no Fish surface to
|
|
148
|
+
load.
|
|
149
|
+
- A module that makes `PWD`, `OLDPWD`, or `IFS` readonly no longer aborts the
|
|
150
|
+
loader mid-transaction. The module fails as caller-state modification, and
|
|
151
|
+
the loader's cleanup still runs.
|
|
152
|
+
- Loader temp-directory cleanup resolves `rm` from a fixed absolute path, so a
|
|
153
|
+
module that changes `PATH` cannot leave its metadata scratch directory
|
|
154
|
+
behind.
|
|
155
|
+
- Compiled plans remove a failed module's declared exports, like the loader.
|
|
156
|
+
A meta module that declares exports is rejected at compile time, and an
|
|
157
|
+
optional-only cycle inside a required graph is quarantined instead of
|
|
158
|
+
failing the whole plan.
|
|
159
|
+
- The compiler rejects an unsafe layer directory name and a reserved-word
|
|
160
|
+
export instead of emitting an unparseable or misleading plan.
|
|
161
|
+
- `release list`, `release use`, `release prune`, `doctor`, and `status`
|
|
162
|
+
identify the active release by its canonical directory name, so a trailing
|
|
163
|
+
slash or an alias symlink cannot hide it from the list or make prune delete
|
|
164
|
+
it.
|
|
165
|
+
- `module remove` keeps a body that another module still loads, and checks
|
|
166
|
+
every directory it will rewrite before changing anything. `module new`
|
|
167
|
+
checks the seed metadata before writing and rejects reserved-word exports.
|
|
168
|
+
- `make-manifest` rejects a directory or symlink as its output, and a
|
|
169
|
+
normalized in-tree output path is excluded from its own manifest.
|
|
170
|
+
- `valise install` holds its lock through the Fish and POSIX integration
|
|
171
|
+
writes, so concurrent installs cannot interleave them.
|
|
172
|
+
- The editor-defaults test is independent of host-installed editors by
|
|
173
|
+
supplying a temporary test `vi` executable.
|
|
174
|
+
|
|
175
|
+
[Unreleased]: https://github.com/joeycumines/valise-sh/compare/v0.2.0...HEAD
|
|
176
|
+
[0.2.0]: https://github.com/joeycumines/valise-sh/compare/v0.1.0...v0.2.0
|
|
177
|
+
[0.1.0]: https://github.com/joeycumines/valise-sh/releases/tag/v0.1.0
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Joseph Cumines
|
|
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.
|
package/README.md
CHANGED
|
@@ -1,3 +1,170 @@
|
|
|
1
|
-
#
|
|
1
|
+
# valise-sh
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
valise-sh is a POSIX shell-profile engine. It loads shell configuration from
|
|
4
|
+
modules described by declarative metadata files. The metadata is parsed as
|
|
5
|
+
data and never executed; the loader resolves the dependency graph and sources
|
|
6
|
+
module bodies in deterministic order. The POSIX core runs under `sh`, `dash`,
|
|
7
|
+
`ksh`, and `bash`; Fish is supported through a native loader in `lib/fish/`.
|
|
8
|
+
The repository also includes the `valise` CLI, which installs sealed
|
|
9
|
+
shell-profile releases and verifies them before use.
|
|
10
|
+
|
|
11
|
+
A consuming project can split its shell configuration into modules with
|
|
12
|
+
declared dependencies, then test and select those modules explicitly. The
|
|
13
|
+
engine is designed to be vendored by that project, for example as a Git
|
|
14
|
+
submodule; the consumer owns its profile and release contents.
|
|
15
|
+
|
|
16
|
+
## Try a sample release
|
|
17
|
+
|
|
18
|
+
This walkthrough builds and installs the included sample profile in an
|
|
19
|
+
isolated temporary home. `valise install` deploys its normal shell
|
|
20
|
+
integration there, so your real home directory and startup files are left
|
|
21
|
+
untouched.
|
|
22
|
+
|
|
23
|
+
```sh
|
|
24
|
+
git clone https://github.com/joeycumines/valise-sh.git
|
|
25
|
+
cd valise-sh
|
|
26
|
+
export PATH="$PWD/bin:$PATH"
|
|
27
|
+
|
|
28
|
+
# Isolate HOME and XDG state; the trap also removes read-only release files.
|
|
29
|
+
(
|
|
30
|
+
set -eu
|
|
31
|
+
_demo_state=$(mktemp -d)
|
|
32
|
+
cleanup_demo() {
|
|
33
|
+
chmod -R u+w "$_demo_state" 2>/dev/null || :
|
|
34
|
+
rm -rf "$_demo_state"
|
|
35
|
+
}
|
|
36
|
+
trap cleanup_demo EXIT
|
|
37
|
+
trap 'exit 130' INT
|
|
38
|
+
trap 'exit 143' TERM
|
|
39
|
+
mkdir -p "$_demo_state/home"
|
|
40
|
+
export HOME="$_demo_state/home"
|
|
41
|
+
export XDG_DATA_HOME="$_demo_state/data"
|
|
42
|
+
export XDG_CONFIG_HOME="$_demo_state/config"
|
|
43
|
+
export XDG_STATE_HOME="$_demo_state/state"
|
|
44
|
+
|
|
45
|
+
# Build, install, and apply the sample profile project.
|
|
46
|
+
(cd examples/profile-project && valise apply)
|
|
47
|
+
|
|
48
|
+
# Run the greeting function exposed by the active profile.
|
|
49
|
+
bash -l -c 'greet'
|
|
50
|
+
)
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
For the multi-shell test fixture and verification scenarios, see
|
|
54
|
+
[examples/e2e/README.md](examples/e2e/README.md). For the smallest possible
|
|
55
|
+
loader example without installation, use `examples/local/` as described in
|
|
56
|
+
[examples/README.md](examples/README.md).
|
|
57
|
+
|
|
58
|
+
## Build your own profile
|
|
59
|
+
|
|
60
|
+
The sample above loads modules from an example profile. To build your own,
|
|
61
|
+
start from the project scaffold:
|
|
62
|
+
|
|
63
|
+
```sh
|
|
64
|
+
export PATH="$PWD/bin:$PATH"
|
|
65
|
+
valise new my-profile
|
|
66
|
+
cd my-profile
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
That writes a project with a metadata directory, a module body, bundle
|
|
70
|
+
roots, variants, and `project.conf`. Add modules with `valise module new`,
|
|
71
|
+
then build and install:
|
|
72
|
+
|
|
73
|
+
```sh
|
|
74
|
+
valise build # build a release under build/release/
|
|
75
|
+
valise apply # install it and write the managed shell integration
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
`examples/profile-project/` is a worked version of this: it has two modules,
|
|
79
|
+
a provider layer, two variants, and a bundle. Its
|
|
80
|
+
[README](examples/profile-project/README.md) walks through each step and
|
|
81
|
+
explains what the generated release contains.
|
|
82
|
+
|
|
83
|
+
## Repository layout
|
|
84
|
+
|
|
85
|
+
- `entrypoints/profile.sh` — the portable entrypoint. It is sourced, not
|
|
86
|
+
executed: it resolves the engine root, sources the three libraries, and
|
|
87
|
+
calls the loader with the requested modules.
|
|
88
|
+
- `lib/metadata.sh` — parses `module.d/*.meta` files as data and validates
|
|
89
|
+
identifiers, lists, paths, shells, platforms, and side-effect classes.
|
|
90
|
+
- `lib/loader.sh` — resolves the dependency closure, selects modules by
|
|
91
|
+
shell/platform/phase, sources bodies, checks declared exports, and cleans
|
|
92
|
+
up on failure.
|
|
93
|
+
- `lib/capabilities.sh` — portable helpers (`sp_cap_*`) that modules call
|
|
94
|
+
instead of platform-specific commands.
|
|
95
|
+
- `lib/fish/` — native Fish loader and metadata reader. The Fish path never
|
|
96
|
+
sources POSIX shell bodies.
|
|
97
|
+
- `bin/valise` — the CLI: init, install, release, doctor, make-manifest,
|
|
98
|
+
registry, new, module, build, apply, status, compile, explain-variant,
|
|
99
|
+
explain-bundles, layer-lint, version.
|
|
100
|
+
`init`, `install`, `release`, `doctor`, `make-manifest`, `new`, and
|
|
101
|
+
`version` run from a bare checkout. `registry`, `module`, `build`, `apply`,
|
|
102
|
+
`status`, `compile`, `explain-variant`,
|
|
103
|
+
`explain-bundles`, and `layer-lint` require the consuming project's source
|
|
104
|
+
tree (see [docs/variants.md](docs/variants.md) and
|
|
105
|
+
[docs/contrib-modules.md](docs/contrib-modules.md)). No command requires
|
|
106
|
+
Python 3.
|
|
107
|
+
- `module.d/` and `modules/platform/` — generic platform modules
|
|
108
|
+
(`platform_posix`, `platform_macos`, `platform_linux`, `platform_bsd`).
|
|
109
|
+
- `manifests/parser-support.tsv` — declares the shell parsers used to check
|
|
110
|
+
each source-file class.
|
|
111
|
+
- `tests/` — the test suite. Every test runs in a quarantined environment:
|
|
112
|
+
fresh temporary HOME, controlled TMPDIR and PATH, cleared startup hooks.
|
|
113
|
+
- `examples/local/` — a minimal runnable module demonstrating the metadata
|
|
114
|
+
contract.
|
|
115
|
+
- `examples/profile-project/` — a complete consuming project: metadata,
|
|
116
|
+
bodies, a provider layer, bundles, variants, and project defaults. Its
|
|
117
|
+
[README](examples/profile-project/README.md) walks from clone to a loaded
|
|
118
|
+
profile.
|
|
119
|
+
|
|
120
|
+
Product-specific modules, adapters, release packaging, and installer
|
|
121
|
+
transactions belong in the consuming project, not here. See
|
|
122
|
+
[docs/architecture.md](docs/architecture.md) for the scope.
|
|
123
|
+
|
|
124
|
+
## Documentation
|
|
125
|
+
|
|
126
|
+
- [docs/installation.md](docs/installation.md) — install paths, shell
|
|
127
|
+
integration, XDG layout, publishing, and the integrity and provenance limits.
|
|
128
|
+
- [docs/module-abi.md](docs/module-abi.md) — the metadata contract: fields,
|
|
129
|
+
allowed values, multi-root search path, runtime detection, side-effect
|
|
130
|
+
phases, and the capability layer.
|
|
131
|
+
- [docs/architecture.md](docs/architecture.md) — what this repository
|
|
132
|
+
provides and what stays in the consuming project.
|
|
133
|
+
- [docs/variants.md](docs/variants.md) — build variant selection and
|
|
134
|
+
exclusion lists.
|
|
135
|
+
- [docs/contrib-modules.md](docs/contrib-modules.md) — module authoring
|
|
136
|
+
reference.
|
|
137
|
+
- [docs/shared-modules.md](docs/shared-modules.md) — governance and index
|
|
138
|
+
for shared modules: namespace ownership, review, deprecation, removal.
|
|
139
|
+
- [docs/release-policy.md](docs/release-policy.md) — compatibility surfaces,
|
|
140
|
+
current pre-1.0 status, and the release checklist.
|
|
141
|
+
- [CHANGELOG.md](CHANGELOG.md) — user-facing changes.
|
|
142
|
+
|
|
143
|
+
## Running the tests
|
|
144
|
+
|
|
145
|
+
The Makefile and the test suite live in the source repository. The npm
|
|
146
|
+
package ships the runtime, the docs, and the examples, not the Makefile.
|
|
147
|
+
|
|
148
|
+
```sh
|
|
149
|
+
make check-fast # quick contributor lane; no optional shells required
|
|
150
|
+
make check # available shell/runtime checks, CLI and end-to-end tests
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
Strict mode requires the parsers declared in
|
|
154
|
+
`manifests/parser-support.tsv`, the host shells used by the end-to-end lanes
|
|
155
|
+
(`sh`, `bash`, `zsh`, `ksh`, `dash`, and `fish`), and a BusyBox executor.
|
|
156
|
+
Missing tools skip with a visible message in an ordinary local run;
|
|
157
|
+
`CI=true` or `GITHUB_ACTIONS=true` makes them fail. Lima VM lanes are optional
|
|
158
|
+
and run only when the relevant instance is configured.
|
|
159
|
+
To require the standard runtime set locally, run:
|
|
160
|
+
|
|
161
|
+
```sh
|
|
162
|
+
make VALISE_REQUIRE_TOOLING=1 check
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
To intentionally use non-strict behavior in CI, or require tools on a local
|
|
166
|
+
machine, the GNU Make command-line override takes precedence. The Makefile
|
|
167
|
+
also includes an optional untracked `config.mk` before its defaults, so
|
|
168
|
+
machine-local preferences can be set there; use `VALISE_REQUIRE_TOOLING ?= 1`
|
|
169
|
+
for a default that a command-line assignment can still override. The release
|
|
170
|
+
checklist is in [docs/release-policy.md](docs/release-policy.md).
|