mirror of
https://github.com/kuhyx/testsAndMisc.git
synced 2026-11-10 22:47:02 +01:00
Two levels of pure taxonomy carrying no information, and a 2-directory
cap leaves no room for them. Categories now sit directly under
linux_configuration/: features, fixes, utils, misc, fresh-install,
installers, diagnostics, gaming, boot_recovery, periodic_background, lib,
meta, tests. A script's own lib/ and tests/ are exempt from the cap, so
those stay put.
Depth violations 248 -> 139; roughly 40 of the remainder are inside
digital_wellbeing and hosts, deferred until the guard-lib repoint.
The moves are the easy half. What breaks is every path that counted
levels, and three classes of it had to be found by resolving paths rather
than reading diffs:
- 52 relative `source` lines for lib/common.sh and lib/android.sh. The
correct prefix differs per file: 40 were ../../ and 12 were ../../../,
so a blanket replace would have fixed one set and broken the other.
- REPO_ROOT in 7 fixes/lib/tests harnesses and setup_syncyomi_guard.sh,
each walking up four levels from a directory now two levels shallower.
This caused a real regression -- the fixes suite went red with
"log_warn: command not found" -- caught by running it and comparing
against the pre-move baseline worktree.
- conftest.py's sys.path entries, which took the pytest gate down with
14 collection errors, and the `# shellcheck source=` directives, which
took shellcheck down with SC1091.
16 symlinks in $HOME broke, including the entire i3blocks bar. All
repointed, and cpu_monitor/memory/disk/time/volume were run to confirm
they emit real output rather than merely resolving.
Verified: 1798 tests pass at 100% coverage, 8 of 9 lib/tests suites pass
(the ninth needs the coverage jail, identically at baseline), pre-commit
is clean, and the two untracked secret configs are still ignored after
their gitignore paths changed.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PJrqKERAo5QUeEHWS5Asgp
184 lines
5.9 KiB
Bash
Executable File
184 lines
5.9 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
# ============================================================================
|
|
# Stop the Flutter SDK misreading YOUR repository as itself inside git hooks.
|
|
#
|
|
# `git commit` / `git push` export GIT_DIR (and GIT_WORK_TREE,
|
|
# GIT_INDEX_FILE) to every hook they run. The flutter tool shells out to git
|
|
# to identify its own SDK, and `git -C "$FLUTTER_ROOT" rev-parse HEAD`
|
|
# (bin/internal/shared.sh) does NOT beat an inherited GIT_DIR -- `-C` only
|
|
# changes directory, while GIT_DIR overrides repository discovery outright:
|
|
#
|
|
# $ git -C /opt/flutter rev-parse HEAD
|
|
# 058e0af2c2... <- Flutter's HEAD
|
|
# $ GIT_DIR=~/some-repo/.git git -C /opt/flutter rev-parse HEAD
|
|
# 84bd550331... <- YOUR repo's HEAD
|
|
#
|
|
# So inside a hook, `flutter --version` reports your project as the SDK, pub
|
|
# resolves the SDK as "0.0.0-unknown" and every version constraint becomes
|
|
# unsatisfiable ("... is forbidden"). Worse, flutter caches that answer in
|
|
# bin/cache/flutter.version.json, so the corruption outlives the hook and
|
|
# follows the next caller into an unrelated repository -- which is why the
|
|
# same command passes when you re-run it by hand and fails again next push.
|
|
#
|
|
# Upstream already unsets these variables in bin/internal/content_aware_hash.sh
|
|
# and bin/internal/update_engine_version.sh, but not in the version path.
|
|
#
|
|
# THE FIX: a wrapper ahead of /usr/bin on PATH that strips the git-hook
|
|
# variables and hands off to the real binary. Per-call `env -u GIT_DIR ...` in
|
|
# each hook works too, but only for as long as every future hook author
|
|
# remembers; this makes the failure impossible for every caller in every repo.
|
|
#
|
|
# Deliberately NOT patching /opt/flutter/bin/internal/shared.sh: that file is
|
|
# owned by the flutter-bin package and the next update would silently restore
|
|
# the bug.
|
|
#
|
|
# Usage: fix_flutter_git_env.sh [--check | --uninstall]
|
|
# ============================================================================
|
|
|
|
set -euo pipefail
|
|
|
|
SCRIPT_NAME="$(basename "$0")"
|
|
readonly SCRIPT_NAME
|
|
readonly BIN_DIR="${HOME}/.local/bin"
|
|
readonly LIB_DIR="${HOME}/.local/share/flutter-git-env"
|
|
readonly WRAPPER="${LIB_DIR}/wrapper.sh"
|
|
# Every SDK entry point that shells out to git to identify itself.
|
|
readonly TOOLS=(flutter dart)
|
|
|
|
log() { echo "$SCRIPT_NAME: $*"; }
|
|
|
|
fail() {
|
|
echo "$SCRIPT_NAME: $*" >&2
|
|
exit 1
|
|
}
|
|
|
|
write_wrapper() {
|
|
mkdir -p "$LIB_DIR" "$BIN_DIR"
|
|
cat > "$WRAPPER" <<'WRAPPER_EOF'
|
|
#!/bin/bash
|
|
|
|
# Strip the git-hook environment, then hand off to the real SDK binary.
|
|
# Installed by linux_configuration/fixes/fix_flutter_git_env.sh
|
|
# -- see that script for why this exists. Invoked through a symlink named
|
|
# after the tool it fronts (flutter, dart).
|
|
|
|
set -euo pipefail
|
|
|
|
tool="$(basename "$0")"
|
|
real="/usr/bin/${tool}"
|
|
|
|
[[ -x $real ]] || {
|
|
echo "flutter-git-env: $real is missing or not executable" >&2
|
|
exit 127
|
|
}
|
|
|
|
# Drop our own directory so a PATH lookup inside the real tool cannot find
|
|
# this wrapper again. The Flutter entry point does exactly such a lookup.
|
|
clean_path=""
|
|
IFS=':' read -r -a path_parts <<< "$PATH"
|
|
for part in "${path_parts[@]}"; do
|
|
[[ $part == "$HOME/.local/bin" ]] && continue
|
|
clean_path="${clean_path:+$clean_path:}$part"
|
|
done
|
|
|
|
# GIT_DIR is the one that actually bites; the rest are exported by git in the
|
|
# same breath and would mislead the SDK the same way.
|
|
exec env \
|
|
-u GIT_DIR \
|
|
-u GIT_WORK_TREE \
|
|
-u GIT_INDEX_FILE \
|
|
-u GIT_COMMON_DIR \
|
|
-u GIT_OBJECT_DIRECTORY \
|
|
-u GIT_ALTERNATE_OBJECT_DIRECTORIES \
|
|
-u GIT_NAMESPACE \
|
|
-u GIT_PREFIX \
|
|
PATH="$clean_path" \
|
|
"$real" "$@"
|
|
WRAPPER_EOF
|
|
chmod +x "$WRAPPER"
|
|
}
|
|
|
|
link_tools() {
|
|
local tool link
|
|
for tool in "${TOOLS[@]}"; do
|
|
link="${BIN_DIR}/${tool}"
|
|
if [[ -e $link && ! -L $link ]]; then
|
|
fail "$link exists and is not a symlink — refusing to overwrite it"
|
|
fi
|
|
ln -sfn "$WRAPPER" "$link"
|
|
log "linked $link -> $WRAPPER"
|
|
done
|
|
}
|
|
|
|
check_path() {
|
|
case ":$PATH:" in
|
|
*":$BIN_DIR:"*) ;;
|
|
*) fail "$BIN_DIR is not on PATH — the wrapper would never be used" ;;
|
|
esac
|
|
local resolved
|
|
for tool in "${TOOLS[@]}"; do
|
|
resolved="$(command -v "$tool" || true)"
|
|
[[ $resolved == "${BIN_DIR}/${tool}" ]] ||
|
|
fail "$tool resolves to '$resolved', not the wrapper — check PATH order"
|
|
done
|
|
}
|
|
|
|
# The real test: does the SDK still know what it is with GIT_DIR poisoned?
|
|
verify() {
|
|
local probe_repo probe_version
|
|
probe_repo="$(mktemp -d)"
|
|
git -C "$probe_repo" init -q
|
|
git -C "$probe_repo" -c user.email=x@y -c user.name=x commit -q --allow-empty -m probe
|
|
|
|
probe_version="$(GIT_DIR="$probe_repo/.git" flutter --version 2>&1 | head -1 || true)"
|
|
rm -rf "$probe_repo"
|
|
|
|
if grep -q '0\.0\.0-unknown' <<< "$probe_version"; then
|
|
fail "still broken: flutter reports an unknown SDK under GIT_DIR"
|
|
fi
|
|
if ! grep -q 'flutter/flutter' <<< "$probe_version"; then
|
|
fail "still broken: flutter reports '$probe_version' under GIT_DIR"
|
|
fi
|
|
log "verified: $probe_version"
|
|
}
|
|
|
|
uninstall() {
|
|
local tool link
|
|
for tool in "${TOOLS[@]}"; do
|
|
link="${BIN_DIR}/${tool}"
|
|
if [[ -L $link && "$(readlink -f "$link")" == "$WRAPPER" ]]; then
|
|
rm -f "$link"
|
|
log "removed $link"
|
|
fi
|
|
done
|
|
rm -rf "$LIB_DIR"
|
|
log "uninstalled"
|
|
}
|
|
|
|
main() {
|
|
case "${1:-}" in
|
|
--uninstall)
|
|
uninstall
|
|
return
|
|
;;
|
|
--check)
|
|
[[ -x $WRAPPER ]] || fail "wrapper is not installed"
|
|
check_path
|
|
verify
|
|
return
|
|
;;
|
|
"") ;;
|
|
*) fail "unknown option: $1 (expected --check or --uninstall)" ;;
|
|
esac
|
|
|
|
command -v flutter >/dev/null 2>&1 || fail "flutter is not on PATH"
|
|
write_wrapper
|
|
link_tools
|
|
check_path
|
|
verify
|
|
log "done — flutter/dart now ignore an inherited GIT_DIR"
|
|
}
|
|
|
|
main "$@"
|