settings: three tiers - wikitool.json (instance), .wikitool-local.json (checkout), secrets by reference incl. 1Password CLI; new command config set (#207)
Every settings field declares its tier; a value in the wrong file is an error naming
file, key and tier. A field naming a program or affecting a gate cannot be declared
instance. Secrets are references only: {"ref": "<name>"} via WIKITOOL_SECRET_<NAME> or
a user-only secrets file, {"ref": "op://..."} via op read (locked 1Password: exit 42).
The preflight records op as an optional tool. doctor gains one line per tier, docs
verify checks a committed wikitool.json for plaintext secrets, CI resolves a real
op:// value through 1password/load-secrets-action. No feature reads its settings
this way yet; without the two files every other command is unchanged.
Files changed:
- .gitea/workflows/ci.yml
- .gitignore
- AGENTS.md
- CHANGES.md
- INSTALL.md
- VERSION
- docs/explanation/README.md
- docs/explanation/configuration-tiers.md
- docs/how-to/README.md
- docs/how-to/use-1password-for-settings.md
- docs/reference/commands/README.md
- docs/reference/commands/configuration.md
- docs/reference/commands/instance-health.md
- docs/reference/commands/types-instructions-and-docs.md
- docs/reference/configuration.md
- docs/reference/exit-codes.md
- instructions/dev/doc-pull-through.md
- instructions/dev/testing-conventions.md
- instructions/preflight.md
- tools/CONTRACT.md
- tools/README.md
- tools/chemenu/cli.py
- tools/chemenu/cli_contract.py
- tools/chemenu/commands/_util.py
- tools/chemenu/commands/config_cmd.py
- tools/chemenu/commands/docs_verify.py
- tools/chemenu/commands/doctor.py
- tools/chemenu/config.py
- tools/chemenu/config_shapes.py
- tools/chemenu/prerequisites.py
- tools/chemenu/settings.py
- tools/chemenu/tests/conftest.py
- tools/chemenu/tests/test_dist_cmd.py
- tools/chemenu/tests/test_preflight.py
- tools/chemenu/tests/test_preflight_pwsh.py
- tools/chemenu/tests/test_settings.py
- tools/chemenu/toolpaths.py
- tools/preflight.ps1
- tools/preflight.sh
- tools/prerequisites.txt
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SnAJ7Z3CpVD3PRbN73QtU2
This commit is contained in:
1 parent
059a0a1840
commit
f6aaadc413
40 files changed
+2246
-31
No files matched your search
+46
-3
@@ -456,6 +456,14 @@ while IFS='|' read -r kind name minimum platforms rest; do
|
||||
fi
|
||||
done < "$MANIFEST"
|
||||
|
||||
# Recorded when found, never asked for - see the manifest's own header.
|
||||
OPTIONAL=""
|
||||
while IFS='|' read -r kind name rest; do
|
||||
[ "$kind" = optional ] || continue
|
||||
case "$name" in *[!a-z0-9]*|'') echo "preflight: bad tool name '$name' in $MANIFEST" >&2; exit 1 ;; esac
|
||||
OPTIONAL="$OPTIONAL $name"
|
||||
done < "$MANIFEST"
|
||||
|
||||
# The install command for this machine's package manager, or every known one.
|
||||
install_hint() { # <tool>
|
||||
choco=$(manifest_field tool "$1" 7)
|
||||
@@ -561,9 +569,9 @@ set_value() { # <name> -> the path given with --set, if any
|
||||
# --- --set: every named path has to work, or nothing is written -------------------
|
||||
|
||||
for entry in $(printf '%s\n' "$SETS" | sed -n 's/^\([^=]*\)=.*/\1/p'); do
|
||||
case " $TOOLS " in
|
||||
case " $TOOLS $OPTIONAL " in
|
||||
*" $entry "*) ;;
|
||||
*) echo "preflight: --set names '$entry', which is not a tool this platform needs:$TOOLS" >&2
|
||||
*) echo "preflight: --set names '$entry', which is not a tool this platform needs:$TOOLS (optional:$OPTIONAL)" >&2
|
||||
exit 1 ;;
|
||||
esac
|
||||
done
|
||||
@@ -705,6 +713,41 @@ $SELF --set $tool=<full path to $tool>"
|
||||
eval "FOUND_$tool=\$native"
|
||||
done
|
||||
|
||||
# --- optional tools: recorded when found, never a problem when not ---------------
|
||||
|
||||
for tool in $OPTIONAL; do
|
||||
label=$(manifest_field optional "$tool" 3)
|
||||
given=$(set_value "$tool")
|
||||
path=""
|
||||
if [ -n "$given" ]; then
|
||||
if usable "$given"; then
|
||||
path=$given
|
||||
else
|
||||
problem "The path given for $label does not work: $given" \
|
||||
"$(manifest_field optional "$tool" 4)" \
|
||||
"Check the path - it has to be the $tool executable itself.
|
||||
Then run: $SELF --set $tool=<full path to $tool>"
|
||||
BAD_SET=1
|
||||
continue
|
||||
fi
|
||||
else
|
||||
previous=$(recorded "$tool") || previous=""
|
||||
if [ -n "$previous" ] && usable "$previous"; then
|
||||
path=$previous
|
||||
else
|
||||
path=$(on_path "$tool" | head -n 1)
|
||||
fi
|
||||
fi
|
||||
if [ -z "$path" ]; then
|
||||
report ABSENT "$tool" - "optional, not installed"
|
||||
continue
|
||||
fi
|
||||
version=$(version_of "$("$path" --version 2>/dev/null | tr -d '\r')")
|
||||
native=$(native_path "$path")
|
||||
report OK "$tool" "${version:--}" "$native"
|
||||
eval "FOUND_$tool=\$native"
|
||||
done
|
||||
|
||||
# --- install folder length (Windows, long paths off) ------------------------------
|
||||
|
||||
if [ "$PLATFORM" = windows ] && ! longpaths_enabled; then
|
||||
@@ -730,7 +773,7 @@ write_tools_file() { # <true|false>
|
||||
{
|
||||
printf '{\n "schema": 1,\n "complete": %s,\n "tools": {' "$1"
|
||||
separator=""
|
||||
for tool in $TOOLS; do
|
||||
for tool in $TOOLS $OPTIONAL; do
|
||||
eval "value=\${FOUND_$tool:-}"
|
||||
[ -n "$value" ] || continue
|
||||
printf '%s\n "%s": "%s"' "$separator" "$tool" "$(json_string "$value")"
|
||||
|
||||
Reference in new issue
Block a user