mirror of
https://github.com/kuhyx/testsAndMisc.git
synced 2026-11-10 20:07:04 +01:00
fresh-install: split main.sh 308 -> 200 + 121
The five package-installation functions move to lib/packages.sh; main.sh keeps the top-level flow and sources the library after `set -e`. The first attempt sliced by line range and was thrown away. This file interleaves top-level commands - sudo -v, git config, the cp of makepkg.conf and pacman.conf - between its function definitions, so a range slice swept them into the library, where they would have run at source time and in the wrong order. Sourcing that version blocked on a sudo password prompt, which is how it was caught. The rebuild extracts function blocks by brace counting and leaves every other line exactly where it was. Verified with the new shfmt harness (all 5 functions verbatim), by a structural comparison of the top-level flow showing exactly one line added and none missing, and by sourcing the library to confirm it defines all five functions with no side effects. The script itself was NOT run: it does `sudo pacman -Sy`, overwrites /etc/makepkg.conf and /etc/pacman.conf, and installs AUR packages. Over-cap files 32 -> 31. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011w2Pj4Ek3ZNMQVYcFHgXDY
This commit is contained in:
parent
23baf9d63f
commit
9b30329ca3
@ -0,0 +1,58 @@
|
||||
{
|
||||
"intent": "Split fresh-install/main.sh (308 lines) into an entry script and a sourced package-helpers library, both under the 250-line cap, without changing the order of any top-level step.",
|
||||
"scope": [
|
||||
"linux_configuration/scripts/single_use/fresh-install/main.sh 308 -> 200",
|
||||
"New: .../fresh-install/lib/packages.sh 121 (the five installation functions)",
|
||||
"Non-goal: any behaviour change; this script installs packages and was not executed"
|
||||
],
|
||||
"changes": [
|
||||
"Extracted the five top-level functions - play_error_sound, install_from_aur, try_aur_install, process_packages, all_subpackages_installed - into lib/packages.sh, each with the comment directly above it.",
|
||||
"main.sh sources the library immediately after `set -e`, using the SCRIPT_DIR idiom with a `# shellcheck source=` directive relative to the script's own directory, per the repo convention for new sourced libs.",
|
||||
"The first attempt sliced by line range and was discarded: this file interleaves top-level commands (sudo -v, git config, cp of makepkg.conf and pacman.conf) between the function definitions, so a range slice swept them into the library where they would have run at source time, out of order. The rebuild extracts function blocks by brace counting and leaves every other line where it was."
|
||||
],
|
||||
"verification": [
|
||||
{
|
||||
"command": "bash meta/scripts/verify_shell_split.sh HEAD .../main.sh .../lib/packages.sh .../main.sh",
|
||||
"result": "pass",
|
||||
"evidence": "IDENTICAL: all 5 top-level functions moved verbatim, via the shfmt-normalised per-function hash."
|
||||
},
|
||||
{
|
||||
"command": "Structural comparison of the top-level flow before and after",
|
||||
"result": "pass",
|
||||
"evidence": "Exactly one line added to main.sh (the source line), zero lines missing, and the surviving order is preserved. Function blocks were removed structurally rather than by grep, so function bodies could not be mistaken for top-level code."
|
||||
},
|
||||
{
|
||||
"command": "bash -c '. lib/packages.sh; declare -F <each of the five>'",
|
||||
"result": "pass",
|
||||
"evidence": "All five functions defined, and the source completes with no side effects. This is the check that caught the bad first attempt: sourcing that version hit `sudo -v` and blocked on a password prompt."
|
||||
},
|
||||
{
|
||||
"command": "bash -n on both files",
|
||||
"result": "pass",
|
||||
"evidence": "Both parse. The script itself was deliberately NOT executed: it runs `sudo pacman -Sy`, copies over /etc/makepkg.conf and /etc/pacman.conf, and installs AUR packages."
|
||||
},
|
||||
{
|
||||
"command": "grep triage for a deployed copy of main.sh",
|
||||
"result": "pass",
|
||||
"evidence": "No other script copies or installs it, so the entry+lib shape is safe here - unlike the phone_focus_mode scripts, whose deploy.sh copies a hardcoded per-file list and never deploys lib/."
|
||||
},
|
||||
{
|
||||
"command": "pre-commit run --files <both files>",
|
||||
"result": "pass",
|
||||
"evidence": "All hooks pass, including shfmt and shellcheck."
|
||||
},
|
||||
{
|
||||
"command": "bash ~/utils/scripts/check_file_length.sh --all",
|
||||
"result": "pass",
|
||||
"evidence": "31 files over cap, down from 32. The two files are 200 and 121 lines."
|
||||
}
|
||||
],
|
||||
"risks": [
|
||||
"main.sh at 200 lines has 50 lines of headroom. Its remaining bulk is the top-level package loop, which would need a different seam (a function extracted from inline code) to shrink further - that is a behaviour-preserving refactor rather than a move, so it was not attempted here.",
|
||||
"This script is only ever run by hand on a fresh machine, so there is no test and no CI coverage for it. The verbatim proof and the source-time check are the whole of the evidence; a genuine end-to-end verification would mean reinstalling a machine."
|
||||
],
|
||||
"rollback": [
|
||||
"git revert the commit; main.sh returns to its 308-line form and lib/packages.sh disappears.",
|
||||
"After rollback, confirm bash -n main.sh still passes and that the file contains all five function definitions again."
|
||||
]
|
||||
}
|
||||
121
linux_configuration/scripts/single_use/fresh-install/lib/packages.sh
Executable file
121
linux_configuration/scripts/single_use/fresh-install/lib/packages.sh
Executable file
@ -0,0 +1,121 @@
|
||||
#!/usr/bin/env bash
|
||||
# Package-installation helpers for the fresh-install run.
|
||||
#
|
||||
# Sourced by main.sh, which owns the ordering of the top-level steps; this
|
||||
# file defines functions only, so sourcing it has no side effects.
|
||||
|
||||
# Function to play a sound on error
|
||||
play_error_sound() {
|
||||
#pactl set-sink-volume @DEFAULT_SINK@ +50%
|
||||
for _ in 1 2 3; do
|
||||
paplay /usr/share/sounds/freedesktop/stereo/dialog-error.oga
|
||||
done
|
||||
#pactl set-sink-volume @DEFAULT_SINK@ -50%
|
||||
}
|
||||
|
||||
install_from_aur() {
|
||||
local repo_url pkg_name repo_dir
|
||||
repo_url="$1"
|
||||
pkg_name="$2"
|
||||
|
||||
mkdir -p "$HOME/aur"
|
||||
cd "$HOME/aur" || return 1
|
||||
repo_dir="$(basename "$repo_url" .git)"
|
||||
|
||||
if [ ! -d "$repo_dir" ]; then
|
||||
git clone "$repo_url"
|
||||
else
|
||||
echo "Repository $repo_dir already cloned; updating"
|
||||
(cd "$repo_dir" && git fetch --all -q && git reset --hard origin/HEAD -q || git pull --ff-only || true)
|
||||
fi
|
||||
cd "$repo_dir" || return 1
|
||||
|
||||
if pacman -Qi "$pkg_name" > /dev/null 2>&1; then
|
||||
echo "$pkg_name is already installed"
|
||||
return 0
|
||||
fi
|
||||
|
||||
echo "Cleaning old package artifacts to avoid duplicate -U targets"
|
||||
find . -maxdepth 1 -type f -name '*.pkg.tar.*' -delete 2> /dev/null || true
|
||||
|
||||
echo "Building $pkg_name (clean build)"
|
||||
# -c (clean up work dirs after) -C (clean build - remove src/ and pkg/ first)
|
||||
if ! yes | makepkg -s -c -C --noconfirm --nocheck --skipchecksums --skipinteg --skippgpcheck --needed; then
|
||||
echo "Build failed for $pkg_name" >&2
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Collect only the freshly built packages (should now be only current version)
|
||||
mapfile -t built_pkgs < <(find . -maxdepth 1 -type f -name '*.pkg.tar.zst' -printf './%f\n')
|
||||
if [ ${#built_pkgs[@]} -eq 0 ]; then
|
||||
echo "No package files produced for $pkg_name" >&2
|
||||
return 1
|
||||
fi
|
||||
|
||||
echo "Installing built package(s): ${built_pkgs[*]}"
|
||||
if ! yes | sudo pacman -U --noconfirm "${built_pkgs[@]}"; then
|
||||
echo "Installation failed for $pkg_name" >&2
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Helper: try to install from AUR and log result to done.txt/failed.txt
|
||||
try_aur_install() {
|
||||
local repo_url="$1"
|
||||
local pkg_name="$2"
|
||||
if install_from_aur "$repo_url" "$pkg_name"; then
|
||||
echo "$pkg_name" >> done.txt
|
||||
else
|
||||
echo "$pkg_name" >> failed.txt
|
||||
fi
|
||||
}
|
||||
|
||||
process_packages() {
|
||||
local file_path
|
||||
file_path="$1"
|
||||
: > failed.txt
|
||||
: > done.txt
|
||||
|
||||
while IFS= read -r pkg_name; do
|
||||
if [ -z "$pkg_name" ]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
local repo_url repo_dir
|
||||
repo_url="https://aur.archlinux.org/${pkg_name}-git.git"
|
||||
repo_dir="${pkg_name}-git"
|
||||
|
||||
git clone "$repo_url"
|
||||
if [ -d "$repo_dir" ] && [ -z "$(ls -A "$repo_dir")" ]; then
|
||||
echo "Repository $repo_dir is empty, trying without -git suffix"
|
||||
repo_url="https://aur.archlinux.org/${pkg_name}.git"
|
||||
repo_dir="${pkg_name}"
|
||||
|
||||
git clone "$repo_url"
|
||||
if [ -d "$repo_dir" ] && [ -z "$(ls -A "$repo_dir")" ]; then
|
||||
echo "Repository $repo_dir is empty, trying to install with pacman"
|
||||
if sudo pacman -Sy --noconfirm "$pkg_name"; then
|
||||
echo "$pkg_name" >> done.txt
|
||||
else
|
||||
echo "$pkg_name" >> failed.txt
|
||||
fi
|
||||
else
|
||||
try_aur_install "$repo_url" "$pkg_name"
|
||||
fi
|
||||
else
|
||||
try_aur_install "$repo_url" "$pkg_name"
|
||||
fi
|
||||
done < "$file_path"
|
||||
}
|
||||
|
||||
# Helper: Check if all subpackages are installed
|
||||
# Returns 0 if ALL subpackages are installed, 1 otherwise
|
||||
all_subpackages_installed() {
|
||||
local -n sub_pkgs_ref=$1
|
||||
for subpkg in "${sub_pkgs_ref[@]}"; do
|
||||
if ! pacman -Qi "$subpkg" &> /dev/null; then
|
||||
return 1
|
||||
fi
|
||||
done
|
||||
return 0
|
||||
}
|
||||
@ -3,14 +3,9 @@
|
||||
# shellcheck source=./detect_gpu_and_install.sh
|
||||
set -e
|
||||
|
||||
# Function to play a sound on error
|
||||
play_error_sound() {
|
||||
#pactl set-sink-volume @DEFAULT_SINK@ +50%
|
||||
for _ in 1 2 3; do
|
||||
paplay /usr/share/sounds/freedesktop/stereo/dialog-error.oga
|
||||
done
|
||||
#pactl set-sink-volume @DEFAULT_SINK@ -50%
|
||||
}
|
||||
# shellcheck source=lib/packages.sh
|
||||
. "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/lib/packages.sh"
|
||||
|
||||
|
||||
# Trap errors and call the play_error_sound function
|
||||
trap 'play_error_sound' ERR
|
||||
@ -29,100 +24,8 @@ else
|
||||
echo "GPU detection scripts not found; continuing without GPU specific installation."
|
||||
fi
|
||||
|
||||
install_from_aur() {
|
||||
local repo_url pkg_name repo_dir
|
||||
repo_url="$1"
|
||||
pkg_name="$2"
|
||||
|
||||
mkdir -p "$HOME/aur"
|
||||
cd "$HOME/aur" || return 1
|
||||
repo_dir="$(basename "$repo_url" .git)"
|
||||
|
||||
if [ ! -d "$repo_dir" ]; then
|
||||
git clone "$repo_url"
|
||||
else
|
||||
echo "Repository $repo_dir already cloned; updating"
|
||||
(cd "$repo_dir" && git fetch --all -q && git reset --hard origin/HEAD -q || git pull --ff-only || true)
|
||||
fi
|
||||
cd "$repo_dir" || return 1
|
||||
|
||||
if pacman -Qi "$pkg_name" > /dev/null 2>&1; then
|
||||
echo "$pkg_name is already installed"
|
||||
return 0
|
||||
fi
|
||||
|
||||
echo "Cleaning old package artifacts to avoid duplicate -U targets"
|
||||
find . -maxdepth 1 -type f -name '*.pkg.tar.*' -delete 2> /dev/null || true
|
||||
|
||||
echo "Building $pkg_name (clean build)"
|
||||
# -c (clean up work dirs after) -C (clean build - remove src/ and pkg/ first)
|
||||
if ! yes | makepkg -s -c -C --noconfirm --nocheck --skipchecksums --skipinteg --skippgpcheck --needed; then
|
||||
echo "Build failed for $pkg_name" >&2
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Collect only the freshly built packages (should now be only current version)
|
||||
mapfile -t built_pkgs < <(find . -maxdepth 1 -type f -name '*.pkg.tar.zst' -printf './%f\n')
|
||||
if [ ${#built_pkgs[@]} -eq 0 ]; then
|
||||
echo "No package files produced for $pkg_name" >&2
|
||||
return 1
|
||||
fi
|
||||
|
||||
echo "Installing built package(s): ${built_pkgs[*]}"
|
||||
if ! yes | sudo pacman -U --noconfirm "${built_pkgs[@]}"; then
|
||||
echo "Installation failed for $pkg_name" >&2
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Helper: try to install from AUR and log result to done.txt/failed.txt
|
||||
try_aur_install() {
|
||||
local repo_url="$1"
|
||||
local pkg_name="$2"
|
||||
if install_from_aur "$repo_url" "$pkg_name"; then
|
||||
echo "$pkg_name" >> done.txt
|
||||
else
|
||||
echo "$pkg_name" >> failed.txt
|
||||
fi
|
||||
}
|
||||
|
||||
process_packages() {
|
||||
local file_path
|
||||
file_path="$1"
|
||||
: > failed.txt
|
||||
: > done.txt
|
||||
|
||||
while IFS= read -r pkg_name; do
|
||||
if [ -z "$pkg_name" ]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
local repo_url repo_dir
|
||||
repo_url="https://aur.archlinux.org/${pkg_name}-git.git"
|
||||
repo_dir="${pkg_name}-git"
|
||||
|
||||
git clone "$repo_url"
|
||||
if [ -d "$repo_dir" ] && [ -z "$(ls -A "$repo_dir")" ]; then
|
||||
echo "Repository $repo_dir is empty, trying without -git suffix"
|
||||
repo_url="https://aur.archlinux.org/${pkg_name}.git"
|
||||
repo_dir="${pkg_name}"
|
||||
|
||||
git clone "$repo_url"
|
||||
if [ -d "$repo_dir" ] && [ -z "$(ls -A "$repo_dir")" ]; then
|
||||
echo "Repository $repo_dir is empty, trying to install with pacman"
|
||||
if sudo pacman -Sy --noconfirm "$pkg_name"; then
|
||||
echo "$pkg_name" >> done.txt
|
||||
else
|
||||
echo "$pkg_name" >> failed.txt
|
||||
fi
|
||||
else
|
||||
try_aur_install "$repo_url" "$pkg_name"
|
||||
fi
|
||||
else
|
||||
try_aur_install "$repo_url" "$pkg_name"
|
||||
fi
|
||||
done < "$file_path"
|
||||
}
|
||||
|
||||
sudo cp /etc/makepkg.conf /etc/makepkg.conf.bak
|
||||
sudo cp ./makepkg.conf /etc/makepkg.conf
|
||||
@ -177,17 +80,6 @@ while IFS= read -r line; do
|
||||
fi
|
||||
done < "aur_packages.txt"
|
||||
|
||||
# Helper: Check if all subpackages are installed
|
||||
# Returns 0 if ALL subpackages are installed, 1 otherwise
|
||||
all_subpackages_installed() {
|
||||
local -n sub_pkgs_ref=$1
|
||||
for subpkg in "${sub_pkgs_ref[@]}"; do
|
||||
if ! pacman -Qi "$subpkg" &> /dev/null; then
|
||||
return 1
|
||||
fi
|
||||
done
|
||||
return 0
|
||||
}
|
||||
|
||||
# Read pacman packages from file
|
||||
declare -a pacman_packages
|
||||
|
||||
Loading…
Reference in New Issue
Block a user