feat!: installation only from a release, into an empty folder; upstream merge/verify and private-instance.md removed, dist adopt, shell-neutral instructions (#153)
Files changed: - .gitea/workflows/ci.yml - .gitea/workflows/release.yml - AGENTS.md - CHANGES.md - DEVELOPMENT.md - EVALS.md - INSTALL.md - README.md - VERSION - docs/ownership-and-templates.md - instructions/CONTRACT.md - instructions/bootstrap.md - instructions/dev/dev-setup.md - instructions/dev/stack-dev/SKILL.md - instructions/gates.md - instructions/ingest-large-tree.md - instructions/kb-profiles.md - instructions/mcp-read-server.md - instructions/migrations/3.0.0-authoring-conventions.md - instructions/preflight.md - instructions/private-instance.md - instructions/session-setup.md - instructions/setup-instance.md - instructions/upgrade-instance.md - tools/CONTRACT.md - tools/README.md - tools/chemenu/cli.py - tools/chemenu/cli_contract.py - tools/chemenu/commands/dist_cmd.py - tools/chemenu/commands/docs_verify.py - tools/chemenu/commands/doctor.py - tools/chemenu/commands/git_publish.py - tools/chemenu/commands/upstream_cmd.py - tools/chemenu/commands/work_cmd.py - tools/chemenu/config.py - tools/chemenu/ownership.py - tools/chemenu/tests/test_cli.py - tools/chemenu/tests/test_dist_cmd.py - tools/chemenu/tests/test_instructions_shell.py - tools/chemenu/tests/test_preflight.py - tools/chemenu/tests/test_preflight_pwsh.py - tools/chemenu/tests/test_run_budget.py - tools/chemenu/tests/test_upstream_cmd.py - tools/chemenu/toc.py - tools/preflight.ps1 - tools/preflight.sh
This commit is contained in:
1 parent
d0f08d1fba
commit
a6d07f97c4
46 files changed
+1314
-1936
No files matched your search
+47
-15
@@ -8,8 +8,10 @@
|
||||
# As the release asset `preflight.sh` - a copy with no tools/prerequisites.txt next
|
||||
# to it - the script is the first install step instead: it downloads the stack
|
||||
# release named in RELEASE_ARCHIVE_URL / RELEASE_CHECKSUM_URL, checks the sha256,
|
||||
# unpacks it into <script folder>/chemenu (or --into <path>), and runs the copy of
|
||||
# this script inside the unpacked tree, which does everything above.
|
||||
# unpacks it into the folder it lies in (or --into <path>), removes itself there, and
|
||||
# runs the copy of this script inside the unpacked tree, which does everything above.
|
||||
# That folder has to be empty apart from this script and a .git (an empty clone of the
|
||||
# instance's own repository).
|
||||
#
|
||||
# preflight.sh [--into <path>] [--archive <tarball>] [--set <tool>=<path>]...
|
||||
#
|
||||
@@ -59,8 +61,8 @@ in .wikitool-tools.json and sets up tools/.venv. Exit 0 means ready; exit 42
|
||||
means the user has to act - the output says how.
|
||||
|
||||
The second form is the release asset: it downloads the release (or takes
|
||||
--archive), checks its sha256, unpacks it into <script folder>/chemenu or --into,
|
||||
and runs the preflight inside it.
|
||||
--archive), checks its sha256, unpacks it into its own folder or --into (empty,
|
||||
or holding only .git), and runs the preflight inside it.
|
||||
EOF
|
||||
}
|
||||
|
||||
@@ -207,6 +209,23 @@ sha256_of() { # <file>
|
||||
fi
|
||||
}
|
||||
|
||||
# Whether the install folder holds anything besides this script and a .git - the
|
||||
# two things an empty folder may already carry: the script was downloaded into it, and
|
||||
# the user may have cloned the instance's own, still empty repository there.
|
||||
target_is_occupied() {
|
||||
[ -d "$TARGET" ] || return 1
|
||||
self_name=${0##*/}
|
||||
target_real=$(CDPATH='' cd -- "$TARGET" && pwd -P)
|
||||
for entry in "$TARGET"/* "$TARGET"/.[!.]* "$TARGET"/..?*; do
|
||||
[ -e "$entry" ] || [ -L "$entry" ] || continue
|
||||
name=${entry##*/}
|
||||
[ "$name" = .git ] && continue
|
||||
[ "$target_real" = "$DIR" ] && [ "$name" = "$self_name" ] && continue
|
||||
return 0
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
asset_mode() {
|
||||
# GNU tar reads `C:` as a host name; Git Bash has to hand it `/c/...`.
|
||||
if [ "$PLATFORM" = windows ] && command -v cygpath >/dev/null 2>&1; then
|
||||
@@ -216,11 +235,14 @@ asset_mode() {
|
||||
if [ -n "$INTO" ]; then
|
||||
case "$INTO" in /*) TARGET=$INTO ;; *) TARGET="$(pwd)/$INTO" ;; esac
|
||||
else
|
||||
TARGET="$DIR/chemenu"
|
||||
TARGET=$DIR
|
||||
fi
|
||||
TARGET=${TARGET%/}
|
||||
if [ -e "$TARGET" ] || [ -L "$TARGET" ]; then
|
||||
asset_fail "$(native_path "$TARGET") already exists - nothing was unpacked. Choose another folder with --into <path>, or move the existing one away."
|
||||
if { [ -e "$TARGET" ] || [ -L "$TARGET" ]; } && [ ! -d "$TARGET" ]; then
|
||||
asset_fail "$(native_path "$TARGET") exists and is not a folder - nothing was unpacked."
|
||||
fi
|
||||
if target_is_occupied; then
|
||||
asset_fail "$(native_path "$TARGET") is not empty - nothing was unpacked. The wiki installs into an empty folder (an empty git clone is fine): put this script into one and run it there, or pass --into <path>."
|
||||
fi
|
||||
|
||||
if [ -z "$ARCHIVE" ] && { [ -z "$RELEASE_ARCHIVE_URL" ] || [ -z "$RELEASE_CHECKSUM_URL" ]; }; then
|
||||
@@ -287,21 +309,31 @@ asset_mode() {
|
||||
if [ "$length" -gt "$limit" ]; then
|
||||
problem "The folder this wiki would be installed in is too long ($length characters, at most $limit): $folder" \
|
||||
"Windows on this computer only allows paths of up to 259 characters, and the wiki's own files need the rest" \
|
||||
"Run this again with a shorter folder, for example: --into C:\\\\Chemenu
|
||||
"Use a shorter folder such as C:\\Chemenu - put this script there and run it again,
|
||||
or pass --into C:\\Chemenu.
|
||||
Alternatively, someone with administrator rights can turn on long paths in Windows."
|
||||
stop
|
||||
fi
|
||||
fi
|
||||
|
||||
parent=$(dirname -- "$TARGET")
|
||||
mkdir -p "$parent" || asset_fail "could not create $parent."
|
||||
UNPACK="$parent/.chemenu-unpack.$$"
|
||||
mkdir "$UNPACK" || asset_fail "could not create a temporary folder next to the target."
|
||||
tar -xzf "$archive" -C "$UNPACK" || asset_fail "unpacking failed - the target was not created."
|
||||
[ -d "$UNPACK/$top" ] || asset_fail "unpacking produced no $top folder - the target was not created."
|
||||
mv "$UNPACK/$top" "$TARGET" || asset_fail "could not move the unpacked stack to $(native_path "$TARGET")."
|
||||
# Unpacked inside the target rather than beside it: the folder above may be a drive
|
||||
# root nobody can write to. Only then are the entries moved up, one by one.
|
||||
mkdir -p "$TARGET" || asset_fail "could not create $(native_path "$TARGET")."
|
||||
UNPACK="$TARGET/.chemenu-unpack.$$"
|
||||
mkdir "$UNPACK" || asset_fail "could not create a temporary folder in the target."
|
||||
tar -xzf "$archive" -C "$UNPACK" || asset_fail "unpacking failed - nothing was installed."
|
||||
[ -d "$UNPACK/$top" ] || asset_fail "unpacking produced no $top folder - nothing was installed."
|
||||
for entry in "$UNPACK/$top"/* "$UNPACK/$top"/.[!.]* "$UNPACK/$top"/..?*; do
|
||||
[ -e "$entry" ] || [ -L "$entry" ] || continue
|
||||
mv "$entry" "$TARGET/" || asset_fail "could not move ${entry##*/} into $(native_path "$TARGET") - the folder holds part of the stack now; empty it (keep .git) and run this again."
|
||||
done
|
||||
rm -rf "$UNPACK"
|
||||
UNPACK=""
|
||||
# The release asset is not part of the stack; left in the folder, it would end up in
|
||||
# the instance's first commit beside the tree's own tools/preflight.sh.
|
||||
if [ "$(CDPATH='' cd -- "$TARGET" && pwd -P)" = "$DIR" ]; then
|
||||
rm -f -- "$DIR/${0##*/}"
|
||||
fi
|
||||
|
||||
[ -f "$TARGET/tools/preflight.sh" ] || asset_fail "the unpacked stack has no tools/preflight.sh."
|
||||
echo "Unpacked into $(native_path "$TARGET")."
|
||||
|
||||
Reference in new issue
Block a user