valise-sh 0.2.0 → 0.3.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 +152 -2
- package/README.md +99 -146
- package/bin/valise +57 -5376
- package/docs/architecture.md +77 -121
- package/docs/contrib-modules.md +172 -218
- package/docs/installation.md +137 -83
- package/docs/module-abi.md +125 -126
- package/docs/projects.md +249 -0
- package/docs/release-policy.md +68 -93
- package/docs/shared-modules.md +40 -39
- package/examples/README.md +12 -11
- package/examples/e2e/README.md +59 -66
- package/examples/e2e/bundles.tsv +6 -0
- package/examples/e2e/module.d/e2e_aliases.meta +1 -2
- package/examples/e2e/module.d/e2e_completions_bash.meta +0 -1
- package/examples/e2e/module.d/e2e_completions_zsh.meta +0 -1
- package/examples/e2e/module.d/e2e_env_setup.meta +2 -3
- package/examples/e2e/module.d/e2e_fish_features.meta +0 -1
- package/examples/e2e/module.d/e2e_generated_config.meta +1 -2
- package/examples/e2e/module.d/e2e_ksh_features.meta +0 -1
- package/examples/e2e/module.d/e2e_layer_probe.meta +1 -2
- package/examples/e2e/module.d/e2e_optional_network.meta +1 -2
- package/examples/e2e/module.d/e2e_platform_tools.meta +8 -0
- package/examples/e2e/module.d/e2e_platform_tools_bsd.meta +2 -3
- package/examples/e2e/module.d/e2e_platform_tools_darwin.meta +2 -3
- package/examples/e2e/module.d/e2e_platform_tools_linux.meta +2 -3
- package/examples/e2e/valise.conf +4 -0
- package/examples/e2e/variants.tsv +3 -0
- package/examples/local/module.d/hello_valise.meta +1 -2
- package/examples/profile-project/README.md +78 -108
- package/examples/profile-project/bundles.tsv +8 -0
- package/examples/profile-project/{shell/layers → layers}/demo/module.d/contrib_demo_greeting.meta +1 -2
- package/examples/profile-project/{shell/module.d → module.d}/greeting.meta +1 -2
- package/examples/profile-project/{shell/module.d → module.d}/profile_main.meta +0 -1
- package/examples/profile-project/{shell/modules → modules}/greeting.sh +1 -1
- package/examples/profile-project/valise.conf +4 -0
- package/examples/profile-project/variants.tsv +3 -0
- package/examples/shared/README.md +13 -34
- package/examples/shared/module.d/contrib_shared_paths.meta +2 -3
- package/examples/shared/module.d/contrib_shared_umask.meta +1 -2
- package/examples/shared/modules/shared/contrib_shared_paths.sh +2 -2
- package/lib/capabilities.sh +40 -13
- package/lib/cli/commands.sh +278 -0
- package/lib/cli/common.sh +326 -0
- package/lib/cli/devtools.sh +539 -0
- package/lib/cli/fish-hook.sh +986 -0
- package/lib/cli/integration.sh +337 -0
- package/lib/cli/lifecycle.sh +578 -0
- package/lib/cli/project.sh +1807 -0
- package/lib/cli/store.sh +1023 -0
- package/lib/cli/usage.sh +308 -0
- package/lib/compiler.awk +11 -4
- package/lib/fish/loader.fish +69 -9
- package/lib/fish/metadata.fish +49 -5
- package/lib/fish/profile.fish +170 -0
- package/lib/loader.sh +6 -8
- package/lib/metadata.sh +111 -5
- package/manifests/parser-support.tsv +2 -2
- package/module.d/valise_editor.meta +9 -0
- package/module.d/valise_history.meta +9 -0
- package/module.d/valise_pager.meta +9 -0
- package/module.d/valise_path.meta +9 -0
- package/module.d/{platform_bsd.meta → valise_platform_bsd.meta} +3 -4
- package/module.d/{platform_linux.meta → valise_platform_linux.meta} +3 -4
- package/module.d/{platform_macos.meta → valise_platform_macos.meta} +3 -4
- package/module.d/{platform_posix.meta → valise_platform_posix.meta} +2 -3
- package/module.d/valise_xdg.meta +9 -0
- package/modules/system/{contrib_editor.sh → valise_editor.sh} +2 -2
- package/modules/system/{contrib_history.sh → valise_history.sh} +2 -2
- package/modules/system/{contrib_pager.sh → valise_pager.sh} +2 -2
- package/modules/system/{contrib_path.sh → valise_path.sh} +3 -3
- package/modules/system/{contrib_xdg.sh → valise_xdg.sh} +2 -2
- package/package.json +91 -10
- package/docs/variants.md +0 -327
- package/entrypoints/.gitkeep +0 -0
- package/entrypoints/fish/profile.fish +0 -99
- package/examples/e2e/build-manifest.sh +0 -138
- package/examples/local/.gitkeep +0 -0
- package/examples/profile-project/shell/release/bundle-roots +0 -9
- package/examples/profile-project/shell/release/install-variants +0 -3
- package/examples/profile-project/shell/release/module-registry.tsv +0 -4
- package/examples/profile-project/shell/release/project.conf +0 -3
- package/lib/.gitkeep +0 -0
- package/manifests/.gitkeep +0 -0
- package/module.d/.gitkeep +0 -0
- package/module.d/contrib_editor.meta +0 -10
- package/module.d/contrib_history.meta +0 -10
- package/module.d/contrib_pager.meta +0 -10
- package/module.d/contrib_path.meta +0 -10
- package/module.d/contrib_xdg.meta +0 -10
- package/modules/.gitkeep +0 -0
- /package/examples/profile-project/{shell/layers → layers}/demo/modules/shared/contrib_demo_greeting.sh +0 -0
package/docs/installation.md
CHANGED
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
# Installation and releases
|
|
2
2
|
|
|
3
|
-
`bin/valise` is a `/bin/sh` CLI.
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
Python 3. `explain-bundles` reads the generated registry and the bundle
|
|
7
|
-
roots; `layer-lint` reads layer metadata directly.
|
|
3
|
+
`bin/valise` is a `/bin/sh` CLI. It needs the standard POSIX utilities and a
|
|
4
|
+
SHA-256 utility (`sha256sum`, `shasum`, or `sha256`); no command needs
|
|
5
|
+
Python, Perl, or another runtime.
|
|
8
6
|
|
|
9
7
|
## Install the CLI
|
|
10
8
|
|
|
@@ -53,30 +51,39 @@ file shadows it. It then adds the files each shell reads instead:
|
|
|
53
51
|
- `${XDG_CONFIG_HOME:-$HOME/.config}/fish/conf.d/valise.fish` when valise
|
|
54
52
|
finds a Fish executable in a trusted location.
|
|
55
53
|
|
|
56
|
-
`--no-integration` writes no startup file
|
|
54
|
+
`--no-integration` writes no startup file, no Fish hook, and no command
|
|
55
|
+
stubs. `valise apply`
|
|
57
56
|
builds, installs, and then uses the same writer.
|
|
58
57
|
|
|
59
58
|
Each POSIX file receives a managed block between `# BEGIN valise managed
|
|
60
59
|
block` and `# END valise managed block`. Existing content is preserved, and
|
|
61
|
-
a repeat install replaces the block in place.
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
60
|
+
a repeat install replaces the block in place. A new block is appended with
|
|
61
|
+
nothing added around it, so removing the block restores the file. When the
|
|
62
|
+
file's last line has no newline, install adds one before the block and a note
|
|
63
|
+
line inside it, and uninstall removes both. Rows or lines after the block
|
|
64
|
+
keep the file's own ending, newline or not, and a repeat install leaves them
|
|
65
|
+
alone. A symlinked POSIX startup file is reported and left untouched.
|
|
66
|
+
|
|
67
|
+
Install checks every startup file, the Fish hook path, and the command
|
|
68
|
+
directory before it changes the active release. The command directory is
|
|
69
|
+
checked only when the release publishes commands or a command ledger exists.
|
|
70
|
+
An unpaired marker, a startup path that is not a regular file, a directory
|
|
71
|
+
install cannot write, a command directory it cannot write, or a Fish hook
|
|
72
|
+
path that is a symlink or a directory stops the install with nothing changed. If a later step fails
|
|
73
|
+
anyway, install puts the previous active release back (or removes the active
|
|
74
|
+
link when there was none) and names the files it had already written. Those
|
|
75
|
+
files load whichever release is active, so they need no repair.
|
|
76
|
+
|
|
77
|
+
Install also warns about lines outside a managed block that load valise by
|
|
78
|
+
hand: a reference to `valise/active`, a 0.1 `installed-modules.` list, or a
|
|
79
|
+
line that sources a compiled plan. Such a line loads the profile a second
|
|
80
|
+
time; remove it. `valise doctor` reports the same lines as a failure.
|
|
81
|
+
|
|
82
|
+
The block detects the running shell class, `ksh`, `zsh`, `bash`, or `sh` for
|
|
83
|
+
any other POSIX shell, and sources `plans/<class>.sh` from the active
|
|
84
|
+
release. It sets `_valise_profile_loaded` only when the plan succeeds, so a
|
|
85
|
+
later startup file in the same session retries after a failure.
|
|
86
|
+
`VALISE_RELOAD=1` makes a later block load the profile again.
|
|
80
87
|
|
|
81
88
|
`valise install` writes `~/.profile`, which ksh reads at login. A non-login
|
|
82
89
|
interactive ksh reads the file named by `$ENV` when that variable is set.
|
|
@@ -87,16 +94,33 @@ Zsh does not read `~/.profile` on its own: zsh login shells read
|
|
|
87
94
|
`.zprofile`, not `~/.profile`. Install writes the same managed block to
|
|
88
95
|
`~/.zprofile`, so zsh needs no separate pointer.
|
|
89
96
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
`
|
|
97
|
+
When the bundle has `fish` rows, the release carries `runtime/fish/`: the
|
|
98
|
+
native Fish metadata reader and loader and `runtime/fish/profile.fish`, which
|
|
99
|
+
loads the bundle's Fish roots recorded in `valise-release.conf`. A release
|
|
100
|
+
whose bundle has no Fish rows has no `runtime/fish/`; the Fish hook then loads
|
|
101
|
+
nothing and prints nothing.
|
|
94
102
|
|
|
95
103
|
The Fish hook verifies the active release before loading it. The check
|
|
96
104
|
validates the active pointer, the release manifest, and every listed file.
|
|
97
|
-
If verification fails, the hook loads no release code
|
|
98
|
-
|
|
99
|
-
interactive shell.
|
|
105
|
+
If verification fails, the hook loads no release code and reports
|
|
106
|
+
`active release authentication failed`. Fish continues starting even if a
|
|
107
|
+
`conf.d` hook fails, so this does not abort the interactive shell.
|
|
108
|
+
|
|
109
|
+
The Fish hook is several hundred lines while the POSIX block is about twenty.
|
|
110
|
+
The difference is deliberate. The POSIX block sources a plan and trusts the
|
|
111
|
+
release on disk, as any startup file does. The Fish hook does more because
|
|
112
|
+
it must not trust release code before that code is verified, and Fish gives a
|
|
113
|
+
sourced file the caller's global functions and variables. The hook therefore
|
|
114
|
+
carries its own verification and cleanup, written before any release file
|
|
115
|
+
runs: it authenticates the release through `valise release verify`, saves the
|
|
116
|
+
caller's `SHELL_PROJECT_ROOT` and `VALISE_MODULE_ROOT` in every scope, records
|
|
117
|
+
every caller function so a release cannot silently replace one, sources
|
|
118
|
+
`runtime/fish/profile.fish` inside that transaction, and on any failure
|
|
119
|
+
removes what the release defined and restores the saved state. None of this
|
|
120
|
+
can live in the release, because a tampered release would carry tampered
|
|
121
|
+
checks. `valise apply` compares the generated hook with the installed one
|
|
122
|
+
byte for byte and reports `Fish hook current` without rewriting an identical
|
|
123
|
+
hook.
|
|
100
124
|
|
|
101
125
|
To write integration by hand, print it once and paste or save it:
|
|
102
126
|
|
|
@@ -106,8 +130,8 @@ valise init posix # POSIX managed block
|
|
|
106
130
|
valise init fish # Fish conf.d hook; save it as fish/conf.d/valise.fish
|
|
107
131
|
```
|
|
108
132
|
|
|
109
|
-
Evaluating `valise init` output
|
|
110
|
-
`eval "$(valise init)"
|
|
133
|
+
Evaluating `valise init` output at every prompt, as in
|
|
134
|
+
`eval "$(valise init)"`, re-runs CLI startup code in every shell and is
|
|
111
135
|
not the routine path; prefer `valise install` or `valise apply`, which
|
|
112
136
|
write the files once.
|
|
113
137
|
|
|
@@ -137,42 +161,55 @@ as an installed shell hook.
|
|
|
137
161
|
|
|
138
162
|
## Build a release
|
|
139
163
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
tree
|
|
164
|
+
`valise build` turns a project into a release tree (see
|
|
165
|
+
[projects.md](projects.md#valise-build)), and `valise apply` builds and
|
|
166
|
+
installs it in one step. `valise install` installs the tree in the current
|
|
167
|
+
directory, so a tree built elsewhere installs the same way:
|
|
143
168
|
|
|
144
169
|
```sh
|
|
145
|
-
|
|
146
|
-
```
|
|
147
|
-
|
|
148
|
-
By default this creates
|
|
149
|
-
`./mytree/shell/install/profile-release.manifest`. Use `--output <file>` to
|
|
150
|
-
choose another manifest path. The manifest records each regular file's size
|
|
151
|
-
and SHA-256 digest; source and destination paths are the same. The tree must
|
|
152
|
-
contain files with mode `0644` or `0755`. Symlinks, unsupported path
|
|
153
|
-
characters, and other file modes are rejected. Rebuilding an unchanged tree
|
|
154
|
-
produces the same manifest.
|
|
155
|
-
|
|
156
|
-
Install and verify from the tree root:
|
|
157
|
-
|
|
158
|
-
```sh
|
|
159
|
-
cd mytree
|
|
170
|
+
cd build/release
|
|
160
171
|
valise install
|
|
161
172
|
valise release verify
|
|
162
173
|
```
|
|
163
174
|
|
|
164
|
-
Install
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
175
|
+
Install requires `manifest.tsv`, which lists every regular file with its
|
|
176
|
+
size and SHA-256 digest, and a `valise-release.conf` declaring `format=2`;
|
|
177
|
+
a tree from an older valise must be rebuilt. It copies the tree into
|
|
178
|
+
the release store under the manifest's SHA-256, makes the copy read-only,
|
|
179
|
+
verifies it, and switches the active link. `release verify` checks the
|
|
180
|
+
installed bytes against their manifest again. Fish repeats that check at
|
|
181
|
+
every startup; the POSIX block does not, so run `release verify` when you
|
|
182
|
+
want a check before a POSIX shell sources the release.
|
|
183
|
+
|
|
184
|
+
`valise make-manifest <tree> [--output <file>]` writes the manifest for a
|
|
185
|
+
tree; `valise build` uses it. Files must have mode `0644` or `0755`;
|
|
186
|
+
symlinks, unsupported path characters, and other modes are rejected. An
|
|
187
|
+
unchanged tree always produces the same manifest.
|
|
188
|
+
|
|
189
|
+
## Published commands
|
|
190
|
+
|
|
191
|
+
A release whose modules declare `commands=` or `executables=` carries a
|
|
192
|
+
`bin/` directory (see [the module ABI](module-abi.md#published-commands)).
|
|
193
|
+
`valise install` writes a stub for each name into the command directory,
|
|
194
|
+
`${VALISE_BIN_DIR:-${XDG_BIN_HOME:-$HOME/.local/bin}}`. A stub is a short
|
|
195
|
+
`sh` script that runs the same name under the active release link, so
|
|
196
|
+
switching releases never rewrites a stub; install and `valise release use`
|
|
197
|
+
add the stubs the new release needs and remove the ones it no longer has.
|
|
198
|
+
|
|
199
|
+
valise records each stub it writes, with its SHA-256, in
|
|
200
|
+
`$XDG_STATE_HOME/valise/commands.tsv` before writing the stub, so an
|
|
201
|
+
interrupted install never leaves a stub valise does not know about. It only
|
|
202
|
+
touches files listed there, and it refuses a release whose `commands=` holds
|
|
203
|
+
a name the build would have rejected:
|
|
204
|
+
|
|
205
|
+
- A file valise did not write is never replaced. Install reports the
|
|
206
|
+
command as not published, and `valise doctor` reports the collision.
|
|
207
|
+
- A stub that was edited after valise wrote it is left in place and
|
|
208
|
+
dropped from the ledger.
|
|
209
|
+
|
|
210
|
+
`valise install --no-integration` writes no stubs and no ledger, and a later
|
|
211
|
+
`valise release use` leaves the command directory alone. Install and
|
|
212
|
+
`valise doctor` warn when the command directory is not on PATH.
|
|
176
213
|
|
|
177
214
|
## Integrity and provenance
|
|
178
215
|
|
|
@@ -194,18 +231,33 @@ controls.
|
|
|
194
231
|
| Releases | `~/.local/share/valise/releases/` | `$XDG_DATA_HOME/valise/releases/` |
|
|
195
232
|
| Active release | `~/.config/valise/active` | `$XDG_CONFIG_HOME/valise/active` |
|
|
196
233
|
| Lock and state | `~/.local/state/valise/` | `$XDG_STATE_HOME/valise/` |
|
|
234
|
+
| Command stubs | `~/.local/bin/` | `$VALISE_BIN_DIR`, then `$XDG_BIN_HOME` |
|
|
197
235
|
|
|
198
|
-
The active path is a symlink to the selected release.
|
|
236
|
+
The active path is a symlink to the selected release. The state directory
|
|
237
|
+
holds the lock, the previous-release record (`previous`), the command-stub
|
|
238
|
+
ledger (`commands.tsv`), and the list of startup files install created
|
|
239
|
+
(`startup-created`). Uninstall uses the same locations, including any XDG
|
|
240
|
+
overrides.
|
|
199
241
|
|
|
200
242
|
## Managing installed releases
|
|
201
243
|
|
|
202
244
|
`valise release list` shows the installed releases and marks the active one.
|
|
203
|
-
`valise release use <release-id>`
|
|
204
|
-
release
|
|
245
|
+
`valise release use <release-id>` verifies an installed release and points
|
|
246
|
+
the active symlink at it. Each time the active release changes, valise
|
|
247
|
+
records the one it replaced in `$XDG_STATE_HOME/valise/previous`;
|
|
248
|
+
`valise release rollback` verifies that release and makes it active again, so
|
|
249
|
+
two rollbacks in a row return to where they started. Both move the command
|
|
250
|
+
stubs to the new active release when install published them.
|
|
251
|
+
|
|
252
|
+
`valise apply --dry-run` builds the project and prints what install would
|
|
253
|
+
do: whether the release is installed or active already, and for each startup
|
|
254
|
+
file, the Fish hook, and each command stub whether it is current or would be
|
|
255
|
+
created, updated, published, skipped, or removed. It writes nothing outside
|
|
256
|
+
`build/`.
|
|
205
257
|
|
|
206
258
|
`valise release prune --keep=<n>` removes old releases. It always keeps the
|
|
207
259
|
active release and the `n` newest others, and it never removes a release that
|
|
208
|
-
fails verification against its own manifest
|
|
260
|
+
fails verification against its own manifest. A release that cannot be
|
|
209
261
|
verified is reported and kept, so a damaged tree is not silently discarded.
|
|
210
262
|
The default is `--keep=3`.
|
|
211
263
|
|
|
@@ -223,26 +275,28 @@ valise install --help
|
|
|
223
275
|
|
|
224
276
|
## Updating and removing
|
|
225
277
|
|
|
226
|
-
Update a source checkout with Git. To update
|
|
227
|
-
reinstall the tarball. `valise install` updates the active profile release;
|
|
278
|
+
Update a source checkout with Git. To update a package installation, repack
|
|
279
|
+
and reinstall the tarball. `valise install` updates the active profile release;
|
|
228
280
|
it does not update the CLI itself.
|
|
229
281
|
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
the
|
|
237
|
-
|
|
282
|
+
`valise uninstall` removes what install wrote:
|
|
283
|
+
|
|
284
|
+
- the managed block from `~/.profile`, `~/.bash_profile`, `~/.bash_login`,
|
|
285
|
+
`~/.bashrc`, `~/.zprofile`, and `~/.zshrc`, keeping every other byte and
|
|
286
|
+
the file mode; a file install created is deleted when nothing else is left
|
|
287
|
+
in it
|
|
288
|
+
- the Fish hook, when its first line is the valise header
|
|
289
|
+
- the command stubs valise owns, except a stub that was edited after valise
|
|
290
|
+
wrote it
|
|
291
|
+
- the active link, the previous-release record, and the installed releases
|
|
292
|
+
|
|
293
|
+
It checks every startup file for paired markers before it changes anything.
|
|
294
|
+
A symlinked startup file and lines that load valise outside a managed block
|
|
295
|
+
are reported for you to edit. `--keep-releases` keeps the installed releases.
|
|
296
|
+
Then remove the CLI:
|
|
238
297
|
|
|
239
298
|
```sh
|
|
240
|
-
chmod -R u+w "$HOME/.local/share/valise" 2>/dev/null || :
|
|
241
|
-
rm -rf "$HOME/.local/share/valise" "$HOME/.config/valise" "$HOME/.local/state/valise"
|
|
242
299
|
# Run only if installed from npm:
|
|
243
300
|
npm uninstall -g valise-sh
|
|
244
301
|
# For a source install, remove bin/ from PATH and delete any symlink you created.
|
|
245
302
|
```
|
|
246
|
-
|
|
247
|
-
If you use non-default XDG directories, remove the corresponding `valise/`
|
|
248
|
-
subdirectories there instead.
|