mirror of
https://github.com/kuhyx/WUT_Computer_Science.git
synced 2026-11-10 21:07:09 +01:00
Two workflows, one per gate, each checking out kuhyx/utils into .utils and calling the shared script -- the pattern every other repo here uses. pre-commit.yml sets UTILS_ROOT to that checkout, without which the shims fail with "shared gate not found", and both use fetch-depth 1 because the history is ~494 MB and no gate reads it. install.sh ends by verifying and exits non-zero if the gate cannot run; a warning there would just recreate the bug it exists to prevent, since this repo had no hooks at all until now. Confirmed both ways: --check exited 1 while the hooks were missing, then 0 once installed. run.sh separates `status` (probe, seconds, safe in CI) from `run <dir>` (actually executes one project). Conflating them is not hypothetical -- the first version of the probe did exactly that and it cost 120 seconds and a scare. Some course dirs already ship a run.sh from years ago, and Programming/PSD/run.sh installs packages with sudo and starts Kafka; calling it with an unknown --probe flag does not probe anything, it runs the project. It blocked on a sudo prompt rather than installing (verified against /var/log/pacman.log and the absence of a yay clone), but only by luck. So probe_one now invokes a runner ONLY if it declares --probe, wraps it in `timeout 20s` as defence in depth, and reports anything else as unprobed without touching it. All 44 directories now probe instantly. DOCS-runnability.md is generated with a per-environment column. Recording one global status would make the CI check red by construction, since `runnable` locally and `blocked` on ubuntu-latest is the normal case for the MATLAB, Unity and .NET directories rather than a drift signal. Per-directory run.sh files are the next step; all 44 currently read unprobed. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0172dj34FDpao6wsix8ZuCzE
115 lines
3.3 KiB
Bash
Executable File
115 lines
3.3 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
# ============================================================================
|
|
# Set this repository up for development.
|
|
#
|
|
# Usage:
|
|
# ./install.sh install tools and wire the git hooks
|
|
# ./install.sh --check verify only; exit 1 if anything is missing
|
|
#
|
|
# Idempotent: a second run reports what is already present and changes nothing.
|
|
#
|
|
# It ENDS by verifying, and fails loudly if the gate is not actually runnable.
|
|
# A warning here would just recreate the bug it exists to prevent: the hooks
|
|
# were absent from this repo entirely, so every "pre-commit passed" claim
|
|
# before now was vacuous.
|
|
# ============================================================================
|
|
|
|
set -euo pipefail
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
readonly SCRIPT_DIR
|
|
readonly UTILS_ROOT="${UTILS_ROOT:-$HOME/utils}"
|
|
|
|
CHECK_ONLY=0
|
|
|
|
log() { printf '==> %s\n' "$*"; }
|
|
err() { printf 'error: %s\n' "$*" >&2; }
|
|
|
|
usage() {
|
|
grep -E '^# \./install\.sh' "${BASH_SOURCE[0]}" | sed 's/^# //'
|
|
exit 0
|
|
}
|
|
|
|
# The shared gates are not vendored here on purpose -- they live in one repo so
|
|
# that every repo enforces the same rule. Without them the hooks cannot run.
|
|
check_shared_gates() {
|
|
if [[ ! -d "$UTILS_ROOT" ]]; then
|
|
err "shared gates not found at $UTILS_ROOT"
|
|
err " git clone https://github.com/kuhyx/utils \"$UTILS_ROOT\""
|
|
err " (or set UTILS_ROOT to where it lives)"
|
|
return 1
|
|
fi
|
|
log "shared gates: $UTILS_ROOT"
|
|
}
|
|
|
|
install_tools() {
|
|
local missing=()
|
|
command -v shellcheck > /dev/null 2>&1 || missing+=(shellcheck)
|
|
command -v pre-commit > /dev/null 2>&1 || missing+=(pre-commit)
|
|
|
|
if [[ ${#missing[@]} -eq 0 ]]; then
|
|
log "tools already present: shellcheck, pre-commit"
|
|
return 0
|
|
fi
|
|
|
|
if [[ $CHECK_ONLY -eq 1 ]]; then
|
|
err "missing tools: ${missing[*]}"
|
|
return 1
|
|
fi
|
|
|
|
log "installing: ${missing[*]}"
|
|
if command -v pacman > /dev/null 2>&1; then
|
|
sudo pacman -S --needed --noconfirm "${missing[@]}"
|
|
elif command -v apt-get > /dev/null 2>&1; then
|
|
sudo apt-get update -qq && sudo apt-get install -y -qq "${missing[@]}"
|
|
else
|
|
err "no supported package manager; install manually: ${missing[*]}"
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
install_hooks() {
|
|
if [[ $CHECK_ONLY -eq 1 ]]; then
|
|
[[ -f "${SCRIPT_DIR}/.git/hooks/pre-commit" ]] || {
|
|
err "git hooks are not installed"
|
|
return 1
|
|
}
|
|
log "git hooks installed"
|
|
return 0
|
|
fi
|
|
|
|
log "wiring git hooks (pre-commit and pre-push)"
|
|
( cd "$SCRIPT_DIR" \
|
|
&& pre-commit install > /dev/null \
|
|
&& pre-commit install --hook-type pre-push > /dev/null )
|
|
}
|
|
|
|
# The last word. If the gate cannot actually run, say so and exit non-zero.
|
|
verify() {
|
|
log "verifying the gate runs"
|
|
if ! ( cd "$SCRIPT_DIR" && pre-commit run --all-files > /dev/null 2>&1 ); then
|
|
err "pre-commit run --all-files failed -- the repo is not clean"
|
|
err "run it directly to see why: pre-commit run --all-files"
|
|
return 1
|
|
fi
|
|
log "OK: all hooks pass"
|
|
}
|
|
|
|
main() {
|
|
check_shared_gates
|
|
install_tools
|
|
install_hooks
|
|
verify
|
|
}
|
|
|
|
while [[ $# -gt 0 ]]; do
|
|
case $1 in
|
|
--check) CHECK_ONLY=1; shift ;;
|
|
-h | --help) usage ;;
|
|
*) err "unknown option: $1"; exit 1 ;;
|
|
esac
|
|
done
|
|
|
|
main "$@"
|