forked from Shinonome/dots-hyprland
Test the changes that have been made
This commit is contained in:
@@ -0,0 +1,66 @@
|
||||
name: Smoke Test - exp-update
|
||||
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- 'install.sh'
|
||||
- 'sdata/step/exp-update.sh'
|
||||
- 'sdata/lib/options-exp-update.sh'
|
||||
pull_request:
|
||||
paths:
|
||||
- 'install.sh'
|
||||
- 'sdata/step/exp-update.sh'
|
||||
- 'sdata/lib/options-exp-update.sh'
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
smoke-test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 1
|
||||
|
||||
- name: Make install.sh executable
|
||||
run: chmod +x install.sh
|
||||
|
||||
- name: Run smoke test
|
||||
run: |
|
||||
echo "Running: ./install.sh exp-update --non-interactive --skip-notice --dry-run -v"
|
||||
|
||||
# Capture output and exit code
|
||||
OUTPUT=$(./install.sh exp-update --non-interactive --skip-notice --dry-run -v 2>&1)
|
||||
EXIT_CODE=$?
|
||||
|
||||
echo "Exit code: $EXIT_CODE"
|
||||
echo "Output:"
|
||||
echo "$OUTPUT"
|
||||
|
||||
# Check exit code
|
||||
if [ $EXIT_CODE -ne 0 ]; then
|
||||
echo "❌ Smoke test failed: Non-zero exit code"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check for expected strings in output
|
||||
if ! echo "$OUTPUT" | grep -q "DRY-RUN MODE"; then
|
||||
echo "❌ Smoke test failed: Missing 'DRY-RUN MODE' in output"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! echo "$OUTPUT" | grep -q "Detecting Repository Structure"; then
|
||||
echo "❌ Smoke test failed: Missing 'Detecting Repository Structure' in output"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check for non-empty Structure line (should contain detected directories)
|
||||
STRUCTURE_LINE=$(echo "$OUTPUT" | grep "Structure:" | head -1)
|
||||
if [[ -z "$STRUCTURE_LINE" ]] || [[ "$STRUCTURE_LINE" == "Structure:" ]]; then
|
||||
echo "❌ Smoke test failed: Structure line is empty or malformed"
|
||||
echo "Found: $STRUCTURE_LINE"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "✅ Smoke test passed: All checks successful"
|
||||
echo "Detected structure: $STRUCTURE_LINE"
|
||||
+1
-3
@@ -1,8 +1,6 @@
|
||||
#!/usr/bin/env bash
|
||||
cd "$(dirname "$0")"
|
||||
# TODO: Use REPO_ROOT instead of base
|
||||
# Also, when scripts are sourced they do not need export to inherit vars
|
||||
export base="$(pwd)"
|
||||
# Use REPO_ROOT instead of base - when scripts are sourced they do not need export to inherit vars
|
||||
REPO_ROOT="$(pwd)"
|
||||
source ./sdata/lib/environment-variables.sh
|
||||
source ./sdata/lib/functions.sh
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
# This is NOT a script for execution, but for loading functions, so NOT need execution permission or shebang.
|
||||
# NOTE that you NOT need to `cd ..' because the `$0' is NOT this file, but the script file which will source this file.
|
||||
|
||||
# shellcheck shell=bash
|
||||
|
||||
# The script that use this file should have two lines on its top as follows:
|
||||
# cd "$(dirname "$0")"
|
||||
# export base="$(pwd)"
|
||||
@@ -9,7 +11,7 @@ function try { "$@" || sleep 0; }
|
||||
function v(){
|
||||
echo -e "####################################################"
|
||||
echo -e "${STY_BLUE}[$0]: Next command:${STY_RST}"
|
||||
echo -e "${STY_GREEN}$@${STY_RST}"
|
||||
echo -e "${STY_GREEN}$*${STY_RST}"
|
||||
local execute=true
|
||||
if $ask;then
|
||||
while true;do
|
||||
@@ -29,14 +31,14 @@ function v(){
|
||||
done
|
||||
fi
|
||||
if $execute;then x "$@";else
|
||||
echo -e "${STY_YELLOW}[$0]: Skipped \"$@\"${STY_RST}"
|
||||
echo -e "${STY_YELLOW}[$0]: Skipped \"$*\"${STY_RST}"
|
||||
fi
|
||||
}
|
||||
# When use v() for a defined function, use x() INSIDE its definition to catch errors.
|
||||
function x(){
|
||||
if "$@";then local cmdstatus=0;else local cmdstatus=1;fi # 0=normal; 1=failed; 2=failed but ignored
|
||||
while [ $cmdstatus == 1 ] ;do
|
||||
echo -e "${STY_RED}[$0]: Command \"${STY_GREEN}$@${STY_RED}\" has failed."
|
||||
echo -e "${STY_RED}[$0]: Command \"${STY_GREEN}$*${STY_RED}\" has failed."
|
||||
echo -e "You may need to resolve the problem manually BEFORE repeating this command."
|
||||
echo -e "[Tip] If a certain package is failing to install, try installing it separately in another terminal.${STY_RST}"
|
||||
echo " r = Repeat this command (DEFAULT)"
|
||||
@@ -52,9 +54,9 @@ function x(){
|
||||
esac
|
||||
done
|
||||
case $cmdstatus in
|
||||
0) echo -e "${STY_BLUE}[$0]: Command \"${STY_GREEN}$@${STY_BLUE}\" finished.${STY_RST}";;
|
||||
1) echo -e "${STY_RED}[$0]: Command \"${STY_GREEN}$@${STY_RED}\" has failed. Exiting...${STY_RST}";exit 1;;
|
||||
2) echo -e "${STY_RED}[$0]: Command \"${STY_GREEN}$@${STY_RED}\" has failed but ignored by user.${STY_RST}";;
|
||||
0) echo -e "${STY_BLUE}[$0]: Command \"${STY_GREEN}$*${STY_BLUE}\" finished.${STY_RST}";;
|
||||
1) echo -e "${STY_RED}[$0]: Command \"${STY_GREEN}$*${STY_RED}\" has failed. Exiting...${STY_RST}";exit 1;;
|
||||
2) echo -e "${STY_RED}[$0]: Command \"${STY_GREEN}$*${STY_RED}\" has failed but ignored by user.${STY_RST}";;
|
||||
esac
|
||||
}
|
||||
function showfun(){
|
||||
|
||||
@@ -1,13 +1,20 @@
|
||||
# Handle args for subcmd: exp-update
|
||||
# shellcheck shell=bash
|
||||
|
||||
showhelp(){
|
||||
echo -e "Syntax: $0 exp-update [OPTIONS]...
|
||||
echo -e "Usage: install.sh exp-update [OPTIONS]...
|
||||
|
||||
Experimental updating without full reinstall.
|
||||
Updates dotfiles by syncing configuration files to home directory.
|
||||
|
||||
Options:
|
||||
-f, --force Force check all files even if no new commits
|
||||
-p, --packages Enable package checking and building
|
||||
-n, --dry-run Show what would be done without making changes
|
||||
-v, --verbose Enable verbose output
|
||||
-h, --help Show this help message
|
||||
-s, --skip-notice Skip notice about script being untested
|
||||
--non-interactive Run without prompting for user input
|
||||
|
||||
This script updates your dotfiles by:
|
||||
1. Auto-detecting repository structure (dots/ prefix or direct)
|
||||
@@ -15,12 +22,19 @@ This script updates your dotfiles by:
|
||||
3. Optionally rebuilding packages (if -p flag is used)
|
||||
4. Syncing configuration files to home directory
|
||||
5. Updating script permissions
|
||||
|
||||
Ignore file patterns support:
|
||||
- Exact matches (e.g., 'path/to/file')
|
||||
- Directory patterns (e.g., 'path/to/dir/')
|
||||
- Wildcards (e.g., '*.log', 'path/*/file')
|
||||
- Root-relative patterns (e.g., '/.config')
|
||||
- Substring matching (prefix with '**', e.g., '**temp' matches any path containing 'temp')
|
||||
"
|
||||
}
|
||||
# `man getopt` to see more
|
||||
para=$(getopt \
|
||||
-o hfpnv \
|
||||
-l help,force,packages,dry-run,verbose,skip-notice \
|
||||
-l help,force,packages,dry-run,verbose,skip-notice,non-interactive \
|
||||
-n "$0" -- "$@")
|
||||
[ $? != 0 ] && echo "$0: Error when getopt, please recheck parameters." && exit 1
|
||||
#####################################################################################
|
||||
@@ -42,6 +56,7 @@ CHECK_PACKAGES=false
|
||||
DRY_RUN=false
|
||||
VERBOSE=false
|
||||
SKIP_NOTICE=false
|
||||
NON_INTERACTIVE=false
|
||||
|
||||
eval set -- "$para"
|
||||
while true ; do
|
||||
@@ -57,6 +72,8 @@ while true ; do
|
||||
# log_info "Verbose mode enabled"
|
||||
--skip-notice) SKIP_NOTICE=true;shift;;
|
||||
# log_warning "Skipping notice about script being untested"
|
||||
--non-interactive) NON_INTERACTIVE=true;shift;;
|
||||
# log_info "Non-interactive mode enabled"
|
||||
|
||||
## Ending
|
||||
--) break ;;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
# Handle args for subcmd: install
|
||||
# shellcheck shell=bash
|
||||
showhelp(){
|
||||
echo -e "Syntax: $0 [OPTIONS]...
|
||||
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
# This is NOT a script for execution, but for loading functions, so NOT need execution permission or shebang.
|
||||
# NOTE that you NOT need to `cd ..' because the `$0' is NOT this file, but the script file which will source this file.
|
||||
|
||||
# shellcheck shell=bash
|
||||
|
||||
# The script that use this file should have two lines on its top as follows:
|
||||
# cd "$(dirname "$0")" export base="$(pwd)"
|
||||
showhelp_global(){
|
||||
@@ -35,11 +37,12 @@ Subcommand:
|
||||
Subcommand:
|
||||
exp-update Using experimental update script.
|
||||
Options for exp-update:
|
||||
-u, --update-force Force check all files even if no new commits (update script)
|
||||
-f, --force Force check all files even if no new commits (update script)
|
||||
-p, --packages Enable package checking and building (update script)
|
||||
-n, --dry-run Show what would be done without making changes (update script)
|
||||
-v, --verbose Enable verbose output (update script)
|
||||
--skip-notice Skip warning notice (for experimental scripts)
|
||||
--non-interactive Run without prompting for user input
|
||||
"
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
# This is NOT a script for execution, but for loading functions, so NOT need execution permission or shebang.
|
||||
# NOTE that you NOT need to `cd ..' because the `$0' is NOT this file, but the script file which will source this file.
|
||||
|
||||
# shellcheck shell=bash
|
||||
|
||||
# This file is provided for any distros, mainly non-Arch(based) distros.
|
||||
|
||||
# The script that use this file should have two lines on its top as follows:
|
||||
@@ -9,8 +11,8 @@
|
||||
# export base="$(pwd)"
|
||||
|
||||
install-agsv1(){
|
||||
x mkdir -p $base/cache/agsv1
|
||||
x cd $base/cache/agsv1
|
||||
x mkdir -p $REPO_ROOT/cache/agsv1
|
||||
x cd $REPO_ROOT/cache/agsv1
|
||||
try git init -b main
|
||||
try git remote add origin https://github.com/Aylur/ags.git
|
||||
x git pull origin main && git submodule update --init --recursive
|
||||
@@ -20,12 +22,12 @@ install-agsv1(){
|
||||
x meson setup build # --reconfigure
|
||||
x meson install -C build
|
||||
x sudo mv /usr/local/bin/ags{,v1}
|
||||
x cd $base
|
||||
x cd $REPO_ROOT
|
||||
}
|
||||
|
||||
install-Rubik(){
|
||||
x mkdir -p $base/cache/Rubik
|
||||
x cd $base/cache/Rubik
|
||||
x mkdir -p $REPO_ROOT/cache/Rubik
|
||||
x cd $REPO_ROOT/cache/Rubik
|
||||
try git init -b main
|
||||
try git remote add origin https://github.com/googlefonts/rubik.git
|
||||
x git pull origin main && git submodule update --init --recursive
|
||||
@@ -35,12 +37,12 @@ install-Rubik(){
|
||||
x sudo cp OFL.txt /usr/local/share/licenses/ttf-rubik/LICENSE
|
||||
x fc-cache -fv
|
||||
x gsettings set org.gnome.desktop.interface font-name 'Rubik 11'
|
||||
x cd $base
|
||||
x cd $REPO_ROOT
|
||||
}
|
||||
|
||||
install-Gabarito(){
|
||||
x mkdir -p $base/cache/Gabarito
|
||||
x cd $base/cache/Gabarito
|
||||
x mkdir -p $REPO_ROOT/cache/Gabarito
|
||||
x cd $REPO_ROOT/cache/Gabarito
|
||||
try git init -b main
|
||||
try git remote add origin https://github.com/naipefoundry/gabarito.git
|
||||
x git pull origin main && git submodule update --init --recursive
|
||||
@@ -49,12 +51,12 @@ install-Gabarito(){
|
||||
x sudo mkdir -p /usr/local/share/licenses/ttf-gabarito/
|
||||
x sudo cp OFL.txt /usr/local/share/licenses/ttf-gabarito/LICENSE
|
||||
x fc-cache -fv
|
||||
x cd $base
|
||||
x cd $REPO_ROOT
|
||||
}
|
||||
|
||||
install-OneUI(){
|
||||
x mkdir -p $base/cache/OneUI4-Icons
|
||||
x cd $base/cache/OneUI4-Icons
|
||||
x mkdir -p $REPO_ROOT/cache/OneUI4-Icons
|
||||
x cd $REPO_ROOT/cache/OneUI4-Icons
|
||||
try git init -b main
|
||||
try git remote add origin https://github.com/end-4/OneUI4-Icons.git
|
||||
# try git remote add origin https://github.com/mjkim0727/OneUI4-Icons.git
|
||||
@@ -63,12 +65,12 @@ install-OneUI(){
|
||||
x sudo cp -r OneUI /usr/local/share/icons
|
||||
x sudo cp -r OneUI-dark /usr/local/share/icons
|
||||
x sudo cp -r OneUI-light /usr/local/share/icons
|
||||
x cd $base
|
||||
x cd $REPO_ROOT
|
||||
}
|
||||
|
||||
install-bibata(){
|
||||
x mkdir -p $base/cache/bibata-cursor
|
||||
x cd $base/cache/bibata-cursor
|
||||
x mkdir -p $REPO_ROOT/cache/bibata-cursor
|
||||
x cd $REPO_ROOT/cache/bibata-cursor
|
||||
name="Bibata-Modern-Classic"
|
||||
file="$name.tar.xz"
|
||||
# Use axel because `curl -O` always downloads a file with 0 byte size, idk why
|
||||
@@ -76,12 +78,12 @@ install-bibata(){
|
||||
tar -xf $file
|
||||
x sudo mkdir -p /usr/local/share/icons
|
||||
x sudo cp -r $name /usr/local/share/icons
|
||||
x cd $base
|
||||
x cd $REPO_ROOT
|
||||
}
|
||||
|
||||
install-MicroTeX(){
|
||||
x mkdir -p $base/cache/MicroTeX
|
||||
x cd $base/cache/MicroTeX
|
||||
x mkdir -p $REPO_ROOT/cache/MicroTeX
|
||||
x cd $REPO_ROOT/cache/MicroTeX
|
||||
try git init -b master
|
||||
try git remote add origin https://github.com/NanoMichael/MicroTeX.git
|
||||
x git pull origin master && git submodule update --init --recursive
|
||||
@@ -92,7 +94,7 @@ install-MicroTeX(){
|
||||
x sudo mkdir -p /opt/MicroTeX
|
||||
x sudo cp ./LaTeX /opt/MicroTeX/
|
||||
x sudo cp -r ./res /opt/MicroTeX/
|
||||
x cd $base
|
||||
x cd $REPO_ROOT
|
||||
}
|
||||
|
||||
install-uv(){
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
# This script is meant to be sourced.
|
||||
# It's not for directly running.
|
||||
|
||||
# shellcheck shell=bash
|
||||
|
||||
#####################################################################################
|
||||
|
||||
printf "${STY_CYAN}[$0]: Hi there! Before we start:${STY_RST}\n"
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
# This script is meant to be sourced.
|
||||
# It's not for directly running.
|
||||
|
||||
# shellcheck shell=bash
|
||||
|
||||
####################
|
||||
# Detect distro
|
||||
# Helpful link(s):
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
# This script is meant to be sourced.
|
||||
# It's not for directly running.
|
||||
|
||||
# shellcheck shell=bash
|
||||
|
||||
# TODO: https://github.com/end-4/dots-hyprland/issues/2137
|
||||
|
||||
function warning_rsync(){
|
||||
@@ -179,7 +181,7 @@ warn_files_tests+=(/usr/local/share/licenses/ttf-gabarito)
|
||||
warn_files_tests+=(/usr/local/share/icons/OneUI{,-dark,-light})
|
||||
warn_files_tests+=(/usr/local/share/icons/Bibata-Modern-Classic)
|
||||
warn_files_tests+=(/usr/local/bin/{LaTeX,res})
|
||||
for i in ${warn_files_tests[@]}; do
|
||||
for i in "${warn_files_tests[@]}"; do
|
||||
echo $i
|
||||
test -f $i && warn_files+=($i)
|
||||
test -d $i && warn_files+=($i)
|
||||
@@ -223,6 +225,6 @@ if [[ -z "${ILLOGICAL_IMPULSE_VIRTUAL_ENV}" ]]; then
|
||||
printf "\n${STY_RED}[$0]: \!! Important \!! : Please ensure environment variable ${STY_RST} \$ILLOGICAL_IMPULSE_VIRTUAL_ENV ${STY_RED} is set to proper value (by default \"~/.local/state/quickshell/.venv\"), or Quickshell config will not work. We have already provided this configuration in ~/.config/hypr/hyprland/env.conf, but you need to ensure it is included in hyprland.conf, and also a restart is needed for applying it.${STY_RST}\n"
|
||||
fi
|
||||
|
||||
if [[ ! -z "${warn_files[@]}" ]]; then
|
||||
if [[ ${#warn_files[@]} -gt 0 ]]; then
|
||||
printf "\n${STY_RED}[$0]: \!! Important \!! : Please delete ${STY_RST} ${warn_files[*]} ${STY_RED} manually as soon as possible, since we\'re now using AUR package or local PKGBUILD to install them for Arch(based) Linux distros, and they'll take precedence over our installation, or at least take up more space.${STY_RST}\n"
|
||||
fi
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
# This script is meant to be sourced.
|
||||
# It's not for directly running.
|
||||
|
||||
# shellcheck shell=bash
|
||||
|
||||
printf 'Hi there!\n'
|
||||
printf 'This script 1. will uninstall [end-4/dots-hyprland > illogical-impulse] dotfiles\n'
|
||||
printf ' 2. will try to revert *mostly everything* installed using install.sh, so it'\''s pretty destructive\n'
|
||||
@@ -40,7 +42,7 @@ starship.toml
|
||||
thorium-flags.conf
|
||||
)
|
||||
|
||||
for i in ${dirs[@]}
|
||||
for i in "${dirs[@]}"
|
||||
do v rm -rf "$XDG_CONFIG_HOME/$i"
|
||||
done
|
||||
|
||||
|
||||
+187
-192
@@ -1,15 +1,13 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# exp-update-tester.sh - Test suite for update.sh
|
||||
# exp-update-tester.sh - Test suite for update.sh (sourced subcommand)
|
||||
#
|
||||
set -euo pipefail
|
||||
|
||||
# Colors
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
CYAN='\033[0;36m'
|
||||
NC='\033[0m'
|
||||
|
||||
TESTS_PASSED=0
|
||||
@@ -32,22 +30,22 @@ log_fail() {
|
||||
((TESTS_FAILED++))
|
||||
}
|
||||
|
||||
log_info() {
|
||||
echo -e "${YELLOW}[INFO]${NC} $1"
|
||||
log_error() {
|
||||
echo -e "${RED}[ERROR]${NC} $1"
|
||||
}
|
||||
|
||||
# Setup test environment
|
||||
setup_test_env() {
|
||||
local temp_dir
|
||||
temp_dir=$(mktemp -d -t dotfiles-test.XXXXXX)
|
||||
|
||||
|
||||
cd "$temp_dir" || { echo "Failed to cd to test directory"; return 1; }
|
||||
git init -q
|
||||
git config user.email "test@example.com"
|
||||
git config user.name "Test User"
|
||||
|
||||
|
||||
git commit --allow-empty -m "Initial commit" -q
|
||||
|
||||
|
||||
echo "$temp_dir"
|
||||
}
|
||||
|
||||
@@ -63,10 +61,10 @@ cleanup_test_env() {
|
||||
run_test() {
|
||||
local test_name="$1"
|
||||
local test_func="$2"
|
||||
|
||||
|
||||
# Cleanup before test
|
||||
cleanup_test_env
|
||||
|
||||
|
||||
# Run the test
|
||||
if $test_func; then
|
||||
echo "✓ $test_name passed"
|
||||
@@ -79,18 +77,18 @@ run_test() {
|
||||
|
||||
# Test 1: Script exists and is executable
|
||||
test_script_exists() {
|
||||
log_test "Checking if update.sh exists and is executable"
|
||||
|
||||
if [[ ! -f "update.sh" ]]; then
|
||||
log_fail "update.sh not found"
|
||||
log_test "Checking if install.sh exists and is executable"
|
||||
|
||||
if [[ ! -f "install.sh" ]]; then
|
||||
log_fail "install.sh not found"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [[ ! -x "update.sh" ]]; then
|
||||
log_fail "update.sh is not executable"
|
||||
|
||||
if [[ ! -x "install.sh" ]]; then
|
||||
log_fail "install.sh is not executable"
|
||||
return 1
|
||||
fi
|
||||
|
||||
|
||||
log_pass "Script exists and is executable"
|
||||
return 0
|
||||
}
|
||||
@@ -98,8 +96,8 @@ test_script_exists() {
|
||||
# Test 2: Script has no syntax errors
|
||||
test_syntax() {
|
||||
log_test "Checking script syntax"
|
||||
|
||||
if bash -n update.sh; then
|
||||
|
||||
if bash -n install.sh; then
|
||||
log_pass "No syntax errors found"
|
||||
return 0
|
||||
else
|
||||
@@ -111,8 +109,8 @@ test_syntax() {
|
||||
# Test 3: Help option works
|
||||
test_help_option() {
|
||||
log_test "Testing --help option"
|
||||
|
||||
if ./update.sh --help 2>&1 | grep -q "Usage:"; then
|
||||
|
||||
if ./install.sh exp-update --help 2>&1 | grep -qiE "(Usage|Options|exp-update)"; then
|
||||
log_pass "Help option works"
|
||||
return 0
|
||||
else
|
||||
@@ -124,52 +122,39 @@ test_help_option() {
|
||||
# Test 4: Test repository structure detection (dots/ prefix)
|
||||
test_dots_structure() {
|
||||
log_test "Testing dots/ prefix structure detection"
|
||||
|
||||
|
||||
local test_repo
|
||||
test_repo=$(setup_test_env)
|
||||
TEST_DIR="$test_repo"
|
||||
|
||||
|
||||
cd "$test_repo" || { log_fail "Failed to cd to test directory"; return 1; }
|
||||
|
||||
|
||||
mkdir -p dots/.config/test-app
|
||||
mkdir -p dots/.local/bin
|
||||
echo "test config" > dots/.config/test-app/config.conf
|
||||
|
||||
|
||||
git add .
|
||||
git commit -m "Add dots structure" -q
|
||||
|
||||
cat > test_detection.sh << 'EOF'
|
||||
|
||||
cat > test_detection.sh << EOF
|
||||
#!/bin/bash
|
||||
# Mock logging and style functions/variables
|
||||
log_info() { :; }
|
||||
log_warning() { :; }
|
||||
log_error() { :; }
|
||||
log_success() { :; }
|
||||
log_header() { :; }
|
||||
log_die() { echo "ERROR: \$1"; exit 1; }
|
||||
STY_CYAN="" STY_RST="" STY_YELLOW=""
|
||||
|
||||
REPO_ROOT="$1"
|
||||
detect_repo_structure() {
|
||||
local found_dirs=()
|
||||
if [[ -d "${REPO_ROOT}/dots/.config" ]]; then
|
||||
found_dirs+=("dots/.config")
|
||||
[[ -d "${REPO_ROOT}/dots/.local/bin" ]] && found_dirs+=("dots/.local/bin")
|
||||
elif [[ -d "${REPO_ROOT}/.config" ]]; then
|
||||
found_dirs+=(".config")
|
||||
[[ -d "${REPO_ROOT}/.local/bin" ]] && found_dirs+=(".local/bin")
|
||||
else
|
||||
for candidate in "dots/.config" ".config" "dots/.local/bin" ".local/bin"; do
|
||||
if [[ -d "${REPO_ROOT}/${candidate}" ]]; then
|
||||
if [[ ! " ${found_dirs[*]} " =~ " ${candidate} " ]]; then
|
||||
found_dirs+=("${candidate}")
|
||||
fi
|
||||
fi
|
||||
done
|
||||
fi
|
||||
if [[ ${#found_dirs[@]} -eq 0 ]]; then
|
||||
echo "ERROR" >&2
|
||||
return 1
|
||||
fi
|
||||
echo "${found_dirs[@]}"
|
||||
}
|
||||
source "$ORIGINAL_DIR/sdata/step/exp-update.sh"
|
||||
detect_repo_structure
|
||||
EOF
|
||||
|
||||
|
||||
chmod +x test_detection.sh
|
||||
result=$(./test_detection.sh "$test_repo")
|
||||
|
||||
|
||||
if [[ "$result" == *"dots/.config"* ]]; then
|
||||
log_pass "Dots structure detected correctly"
|
||||
cd "$ORIGINAL_DIR"
|
||||
@@ -184,52 +169,39 @@ EOF
|
||||
# Test 5: Test flat structure detection
|
||||
test_flat_structure() {
|
||||
log_test "Testing flat structure detection"
|
||||
|
||||
|
||||
local test_repo
|
||||
test_repo=$(setup_test_env)
|
||||
TEST_DIR="$test_repo"
|
||||
|
||||
|
||||
cd "$test_repo" || { log_fail "Failed to cd to test directory"; return 1; }
|
||||
|
||||
|
||||
mkdir -p .config/test-app
|
||||
mkdir -p .local/bin
|
||||
echo "test config" > .config/test-app/config.conf
|
||||
|
||||
|
||||
git add .
|
||||
git commit -m "Add flat structure" -q
|
||||
|
||||
cat > test_detection.sh << 'EOF'
|
||||
|
||||
cat > test_detection.sh << EOF
|
||||
#!/bin/bash
|
||||
# Mock logging and style functions/variables
|
||||
log_info() { :; }
|
||||
log_warning() { :; }
|
||||
log_error() { :; }
|
||||
log_success() { :; }
|
||||
log_header() { :; }
|
||||
log_die() { echo "ERROR: \$1"; exit 1; }
|
||||
STY_CYAN="" STY_RST="" STY_YELLOW=""
|
||||
|
||||
REPO_ROOT="$1"
|
||||
detect_repo_structure() {
|
||||
local found_dirs=()
|
||||
if [[ -d "${REPO_ROOT}/dots/.config" ]]; then
|
||||
found_dirs+=("dots/.config")
|
||||
[[ -d "${REPO_ROOT}/dots/.local/bin" ]] && found_dirs+=("dots/.local/bin")
|
||||
elif [[ -d "${REPO_ROOT}/.config" ]]; then
|
||||
found_dirs+=(".config")
|
||||
[[ -d "${REPO_ROOT}/.local/bin" ]] && found_dirs+=(".local/bin")
|
||||
else
|
||||
for candidate in "dots/.config" ".config" "dots/.local/bin" ".local/bin"; do
|
||||
if [[ -d "${REPO_ROOT}/${candidate}" ]]; then
|
||||
if [[ ! " ${found_dirs[*]} " =~ " ${candidate} " ]]; then
|
||||
found_dirs+=("${candidate}")
|
||||
fi
|
||||
fi
|
||||
done
|
||||
fi
|
||||
if [[ ${#found_dirs[@]} -eq 0 ]]; then
|
||||
echo "ERROR" >&2
|
||||
return 1
|
||||
fi
|
||||
echo "${found_dirs[@]}"
|
||||
}
|
||||
source "$ORIGINAL_DIR/sdata/step/exp-update.sh"
|
||||
detect_repo_structure
|
||||
EOF
|
||||
|
||||
|
||||
chmod +x test_detection.sh
|
||||
result=$(./test_detection.sh "$test_repo")
|
||||
|
||||
|
||||
if [[ "$result" == *".config"* ]] && [[ "$result" != *"dots/"* ]]; then
|
||||
log_pass "Flat structure detected correctly"
|
||||
cd "$ORIGINAL_DIR"
|
||||
@@ -283,47 +255,22 @@ EOF
|
||||
mkdir -p .config
|
||||
mkdir -p secrets
|
||||
|
||||
cat > test_ignore.sh << 'EOF'
|
||||
cat > test_ignore.sh << EOF
|
||||
#!/bin/bash
|
||||
# Mock logging and style functions/variables
|
||||
log_info() { :; }
|
||||
log_warning() { :; }
|
||||
log_error() { :; }
|
||||
log_success() { :; }
|
||||
log_header() { :; }
|
||||
log_die() { echo "ERROR: \$1"; exit 1; }
|
||||
STY_CYAN="" STY_RST="" STY_YELLOW=""
|
||||
|
||||
REPO_ROOT="$1"
|
||||
UPDATE_IGNORE_FILE="${REPO_ROOT}/.updateignore"
|
||||
HOME_UPDATE_IGNORE_FILE="/dev/null"
|
||||
|
||||
should_ignore() {
|
||||
local file_path="$1"
|
||||
local relative_path="${file_path#$HOME/}"
|
||||
local repo_relative=""
|
||||
if [[ "$file_path" == "$REPO_ROOT"* ]]; then
|
||||
repo_relative="${file_path#$REPO_ROOT/}"
|
||||
fi
|
||||
|
||||
for ignore_file in "$UPDATE_IGNORE_FILE" "$HOME_UPDATE_IGNORE_FILE"; do
|
||||
if [[ -f "$ignore_file" ]]; then
|
||||
while IFS= read -r pattern || [[ -n "$pattern" ]]; do
|
||||
[[ -z "$pattern" || "$pattern" =~ ^[[:space:]]*# ]] && continue
|
||||
pattern=$(echo "$pattern" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
|
||||
[[ -z "$pattern" ]] && continue
|
||||
|
||||
if [[ "$relative_path" == "$pattern" ]] || [[ "$repo_relative" == "$pattern" ]]; then
|
||||
return 0
|
||||
fi
|
||||
if [[ "$relative_path" == $pattern ]] || [[ "$repo_relative" == $pattern ]]; then
|
||||
return 0
|
||||
fi
|
||||
if [[ "$pattern" == */ ]]; then
|
||||
local dir_pattern="${pattern%/}"
|
||||
if [[ "$relative_path" == "$dir_pattern"/* ]] || [[ "$repo_relative" == "$dir_pattern"/* ]]; then
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
if [[ "$file_path" == *"$pattern"* ]] || [[ "$relative_path" == *"$pattern"* ]]; then
|
||||
return 0
|
||||
fi
|
||||
done <"$ignore_file"
|
||||
fi
|
||||
done
|
||||
return 1
|
||||
}
|
||||
# Source the production script to use the real should_ignore function
|
||||
source "$ORIGINAL_DIR/sdata/step/exp-update.sh"
|
||||
|
||||
test_cases=(
|
||||
"$REPO_ROOT/app.log:0"
|
||||
@@ -335,7 +282,7 @@ test_cases=(
|
||||
|
||||
all_passed=true
|
||||
for test_case in "${test_cases[@]}"; do
|
||||
IFS=':' read -r file expected <<< "$test_case"
|
||||
IFS=":" read -r file expected <<< "$test_case"
|
||||
mkdir -p "$(dirname "$file")"
|
||||
touch "$file"
|
||||
|
||||
@@ -376,16 +323,22 @@ EOF
|
||||
# Test 8: Test safe_read security - COMPLETELY NON-INTERACTIVE
|
||||
test_safe_read_security() {
|
||||
log_test "Testing safe_read uses secure assignment (printf -v)"
|
||||
|
||||
# Check that safe_read uses printf -v and not eval
|
||||
if grep -A 10 "safe_read()" update.sh | grep -q "printf -v.*varname"; then
|
||||
log_pass "safe_read uses secure printf -v assignment"
|
||||
return 0
|
||||
elif grep -A 10 "safe_read()" update.sh | grep -q "eval.*varname"; then
|
||||
log_fail "safe_read uses vulnerable eval assignment"
|
||||
|
||||
local awk_script='/^safe_read() \{/,/^\}/'
|
||||
local safe_read_function
|
||||
safe_read_function=$(awk "$awk_script" "$ORIGINAL_DIR/sdata/step/exp-update.sh")
|
||||
|
||||
if [[ -z "$safe_read_function" ]]; then
|
||||
log_fail "Could not find safe_read function"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Check for secure printf -v assignment and absence of eval
|
||||
if echo "$safe_read_function" | grep -q "printf -v" && ! echo "$safe_read_function" | grep -q "eval"; then
|
||||
log_pass "safe_read uses secure printf -v assignment and no eval"
|
||||
return 0
|
||||
else
|
||||
log_fail "Cannot determine safe_read assignment method"
|
||||
log_fail "safe_read does not use secure assignment or contains eval"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
@@ -393,25 +346,25 @@ test_safe_read_security() {
|
||||
# Test 9: Test dry-run mode
|
||||
test_dry_run() {
|
||||
log_test "Testing dry-run mode"
|
||||
|
||||
|
||||
local test_repo
|
||||
test_repo=$(setup_test_env)
|
||||
TEST_DIR="$test_repo"
|
||||
|
||||
|
||||
cd "$test_repo" || { log_fail "Failed to cd to test directory"; return 1; }
|
||||
|
||||
mkdir -p dots/.config/test-app
|
||||
echo "repo config" > dots/.config/test-app/config.conf
|
||||
|
||||
|
||||
# Copy necessary files for install.sh to run
|
||||
cp "$ORIGINAL_DIR/install.sh" .
|
||||
cp -r "$ORIGINAL_DIR/sdata" .
|
||||
cp -r "$ORIGINAL_DIR/dots" .
|
||||
chmod +x install.sh
|
||||
|
||||
git add .
|
||||
git commit -m "Add test config" -q
|
||||
|
||||
cp "$ORIGINAL_DIR/update.sh" .
|
||||
chmod +x update.sh
|
||||
|
||||
# Use printf to pipe responses automatically
|
||||
printf "y\ny\n" | ./update.sh -n --skip-notice 2>&1 | tee dry_run_output.txt
|
||||
|
||||
|
||||
# Use non-interactive mode and check for DRY-RUN marker
|
||||
./install.sh exp-update -n --skip-notice --non-interactive 2>&1 | tee dry_run_output.txt
|
||||
|
||||
if grep -q "DRY-RUN" dry_run_output.txt; then
|
||||
log_pass "Dry-run mode detected in output"
|
||||
else
|
||||
@@ -419,7 +372,7 @@ test_dry_run() {
|
||||
cd "$ORIGINAL_DIR"
|
||||
return 1
|
||||
fi
|
||||
|
||||
|
||||
if [[ ! -f "${HOME}/.config/test-app/config.conf" ]]; then
|
||||
log_pass "No files created in home during dry-run"
|
||||
else
|
||||
@@ -428,7 +381,7 @@ test_dry_run() {
|
||||
cd "$ORIGINAL_DIR"
|
||||
return 1
|
||||
fi
|
||||
|
||||
|
||||
cd "$ORIGINAL_DIR"
|
||||
return 0
|
||||
}
|
||||
@@ -436,20 +389,20 @@ test_dry_run() {
|
||||
# Test 10: Test command-line flags
|
||||
test_flags() {
|
||||
log_test "Testing command-line flags"
|
||||
|
||||
|
||||
# Only test non-interactive flags
|
||||
local flags=("-h" "--help")
|
||||
local all_passed=true
|
||||
|
||||
|
||||
for flag in "${flags[@]}"; do
|
||||
if ./update.sh "$flag" 2>&1 | grep -q -E "(Usage|help)"; then
|
||||
log_info " ✓ $flag recognized"
|
||||
if ./install.sh exp-update "$flag" 2>&1 | grep -qiE "(Usage|Options|exp-update)"; then
|
||||
log_test " ✓ $flag recognized"
|
||||
else
|
||||
log_info " ✗ $flag not recognized"
|
||||
log_test " ✗ $flag not recognized"
|
||||
all_passed=false
|
||||
fi
|
||||
done
|
||||
|
||||
|
||||
if [[ "$all_passed" == true ]]; then
|
||||
log_pass "Help flags recognized correctly"
|
||||
return 0
|
||||
@@ -464,11 +417,11 @@ test_shellcheck() {
|
||||
log_test "Running shellcheck (if available)"
|
||||
|
||||
if ! command -v shellcheck &>/dev/null; then
|
||||
log_info "shellcheck not found, skipping static analysis"
|
||||
log_test "shellcheck not found, skipping static analysis"
|
||||
return 0
|
||||
fi
|
||||
|
||||
if shellcheck -e SC1090,SC1091,SC2148,SC2034,SC2155,SC2164 update.sh; then
|
||||
if shellcheck -e SC1090,SC1091,SC2148,SC2034,SC2155,SC2164 install.sh; then
|
||||
log_pass "shellcheck passed"
|
||||
return 0
|
||||
else
|
||||
@@ -477,45 +430,87 @@ test_shellcheck() {
|
||||
fi
|
||||
}
|
||||
|
||||
# Test 12: Test fresh clone scenario
|
||||
test_fresh_clone() {
|
||||
log_test "Testing fresh clone scenario"
|
||||
|
||||
# Test 13: Test ** substring ignore patterns
|
||||
test_substring_ignore_patterns() {
|
||||
log_test "Testing ** substring ignore pattern matching"
|
||||
|
||||
local test_repo
|
||||
test_repo=$(setup_test_env)
|
||||
TEST_DIR="$test_repo"
|
||||
|
||||
cd "$test_repo" || { log_fail "Failed to cd to test directory"; return 1; }
|
||||
|
||||
mkdir -p .config/test-app
|
||||
echo "config" > .config/test-app/settings.conf
|
||||
|
||||
cat > test_fresh_clone.sh << 'EOF'
|
||||
#!/bin/bash
|
||||
has_new_commits() {
|
||||
if git rev-parse --verify HEAD@{1} &>/dev/null; then
|
||||
[[ "$(git rev-parse HEAD)" != "$(git rev-parse HEAD@{1})" ]]
|
||||
else
|
||||
return 0
|
||||
fi
|
||||
}
|
||||
|
||||
if has_new_commits; then
|
||||
cd "$test_repo" || { log_fail "Failed to cd to test directory"; return 1; }
|
||||
|
||||
cat > .updateignore << 'EOF'
|
||||
**temp**
|
||||
**backup**
|
||||
**test**
|
||||
EOF
|
||||
|
||||
mkdir -p .config/test-app
|
||||
mkdir -p temp-backup-dir
|
||||
mkdir -p .local/share/test-temp
|
||||
mkdir -p .config/temp-file
|
||||
|
||||
cat > test_substring_ignore.sh << EOF
|
||||
#!/bin/bash
|
||||
# Mock logging and style functions/variables
|
||||
log_info() { :; }
|
||||
log_warning() { :; }
|
||||
log_error() { :; }
|
||||
log_success() { :; }
|
||||
log_header() { :; }
|
||||
log_die() { echo "ERROR: \$1"; exit 1; }
|
||||
STY_CYAN="" STY_RST="" STY_YELLOW=""
|
||||
|
||||
REPO_ROOT="$1"
|
||||
UPDATE_IGNORE_FILE="${REPO_ROOT}/.updateignore"
|
||||
HOME_UPDATE_IGNORE_FILE="/dev/null"
|
||||
# Source the production script to use the real should_ignore function
|
||||
source "$ORIGINAL_DIR/sdata/step/exp-update.sh"
|
||||
|
||||
test_cases=(
|
||||
"$REPO_ROOT/temp-backup-dir/file:0"
|
||||
"$REPO_ROOT/.config/test-app/temp.conf:0"
|
||||
"$REPO_ROOT/.local/share/test-temp/data:0"
|
||||
"$REPO_ROOT/.config/temp-file/config:0"
|
||||
"$REPO_ROOT/normal-config:1"
|
||||
)
|
||||
|
||||
all_passed=true
|
||||
for test_case in "${test_cases[@]}"; do
|
||||
IFS=":" read -r file expected <<< "$test_case"
|
||||
mkdir -p "$(dirname "$file")"
|
||||
touch "$file"
|
||||
|
||||
if should_ignore "$file"; then
|
||||
result=0
|
||||
else
|
||||
result=1
|
||||
fi
|
||||
|
||||
if [[ $result -ne $expected ]]; then
|
||||
echo "FAIL: $file (expected: $expected, got: $result)"
|
||||
all_passed=false
|
||||
fi
|
||||
done
|
||||
|
||||
if [[ "$all_passed" == true ]]; then
|
||||
echo "PASS"
|
||||
else
|
||||
echo "FAIL"
|
||||
fi
|
||||
EOF
|
||||
|
||||
chmod +x test_fresh_clone.sh
|
||||
result=$(./test_fresh_clone.sh)
|
||||
|
||||
|
||||
chmod +x test_substring_ignore.sh
|
||||
result=$(./test_substring_ignore.sh "$test_repo")
|
||||
|
||||
if [[ "$result" == "PASS" ]]; then
|
||||
log_pass "Fresh clone scenario handled correctly"
|
||||
log_pass "** substring ignore patterns work correctly"
|
||||
cd "$ORIGINAL_DIR"
|
||||
return 0
|
||||
else
|
||||
log_fail "Fresh clone scenario not handled properly"
|
||||
log_fail "** substring ignore patterns failed"
|
||||
echo "$result"
|
||||
cd "$ORIGINAL_DIR"
|
||||
return 1
|
||||
fi
|
||||
@@ -524,32 +519,32 @@ EOF
|
||||
# Main test runner
|
||||
main() {
|
||||
echo -e "${BLUE}================================${NC}"
|
||||
echo -e "${BLUE} Update.sh Test Suite${NC}"
|
||||
echo -e "${BLUE} Update.sh Test Suite (Sourced Subcommand)${NC}"
|
||||
echo -e "${BLUE}================================${NC}\n"
|
||||
|
||||
if [[ ! -f "update.sh" ]]; then
|
||||
log_error "Please run this test from the directory containing update.sh"
|
||||
|
||||
if [[ ! -f "install.sh" ]]; then
|
||||
log_error "Please run this test from the directory containing install.sh"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
chmod +x update.sh 2>/dev/null || true
|
||||
|
||||
|
||||
chmod +x install.sh 2>/dev/null || true
|
||||
|
||||
# Define tests
|
||||
tests=(
|
||||
"test_script_exists"
|
||||
"test_syntax"
|
||||
"test_syntax"
|
||||
"test_help_option"
|
||||
"test_dots_structure"
|
||||
"test_flat_structure"
|
||||
"test_dots_mapping"
|
||||
"test_ignore_patterns"
|
||||
"test_substring_ignore_patterns"
|
||||
"test_safe_read_security"
|
||||
"test_dry_run"
|
||||
"test_flags"
|
||||
"test_shellcheck"
|
||||
"test_fresh_clone"
|
||||
)
|
||||
|
||||
|
||||
# Run tests
|
||||
for test in "${tests[@]}"; do
|
||||
if $test; then
|
||||
@@ -559,7 +554,7 @@ main() {
|
||||
fi
|
||||
echo
|
||||
done
|
||||
|
||||
|
||||
# Summary
|
||||
echo -e "${BLUE}================================${NC}"
|
||||
echo -e "${BLUE} Test Summary${NC}"
|
||||
@@ -567,7 +562,7 @@ main() {
|
||||
echo -e "${GREEN}Passed: $TESTS_PASSED${NC}"
|
||||
echo -e "${RED}Failed: $TESTS_FAILED${NC}"
|
||||
echo -e "${BLUE}Total: ${#tests[@]}${NC}\n"
|
||||
|
||||
|
||||
if [[ $TESTS_FAILED -eq 0 ]]; then
|
||||
echo -e "${GREEN}All tests passed! 🎉${NC}\n"
|
||||
exit 0
|
||||
@@ -581,7 +576,7 @@ main() {
|
||||
cleanup() {
|
||||
echo "Cleaning up test files..."
|
||||
cleanup_test_env
|
||||
rm -f test_detection.sh test_ignore.sh test_safe_read.sh test_fresh_clone.sh dry_run_output.txt 2>/dev/null || true
|
||||
rm -f test_detection.sh test_ignore.sh test_safe_read.sh test_fresh_clone.sh test_substring_ignore.sh dry_run_output.txt 2>/dev/null || true
|
||||
rm -rf "${HOME}/.config/test-app" 2>/dev/null || true
|
||||
}
|
||||
|
||||
|
||||
Regular → Executable
+66
-35
@@ -1,6 +1,8 @@
|
||||
# This script is meant to be sourced.
|
||||
# It's not for directly running.
|
||||
|
||||
# shellcheck shell=bash
|
||||
|
||||
#####################################################################################
|
||||
#
|
||||
# update.sh - Enhanced dotfiles update script
|
||||
@@ -10,7 +12,12 @@
|
||||
# - Pull latest commits from remote
|
||||
# - Rebuild packages if PKGBUILD files changed (user choice)
|
||||
# - Handle config file conflicts with user choices
|
||||
# - Respect .updateignore file for exclusions
|
||||
# - Respect .updateignore file for exclusions with flexible pattern matching:
|
||||
# - Exact matches (e.g., "path/to/file")
|
||||
# - Directory patterns (e.g., "path/to/dir/")
|
||||
# - Wildcards (e.g., "*.log", "path/*/file")
|
||||
# - Root-relative patterns (e.g., "/.config")
|
||||
# - Substring matching (prefix with "**", e.g., "**temp" matches any path containing "temp")
|
||||
#
|
||||
set -euo pipefail
|
||||
|
||||
@@ -47,7 +54,7 @@ detect_repo_structure() {
|
||||
[[ -d "${REPO_ROOT}/.local/share" ]] && found_dirs+=(".local/share")
|
||||
else
|
||||
# Manual detection of common directories
|
||||
for candidate in "dots/.config" ".config" "config" "dots/.local/bin" ".local/bin" "dots/.local/share" ".local/share"; do
|
||||
for candidate in "dots/.config" ".config" "dots/.local/bin" ".local/bin" "dots/.local/share" ".local/share"; do
|
||||
if [[ -d "${REPO_ROOT}/${candidate}" ]]; then
|
||||
# Avoid duplicates
|
||||
if [[ ! " ${found_dirs[*]} " =~ " ${candidate} " ]]; then
|
||||
@@ -94,8 +101,6 @@ safe_read() {
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to check if a file should be ignored
|
||||
should_ignore() {
|
||||
local file_path="$1"
|
||||
local relative_path="${file_path#$HOME/}"
|
||||
@@ -161,9 +166,10 @@ should_ignore() {
|
||||
done
|
||||
fi
|
||||
|
||||
# Simple substring matching (for backward compatibility)
|
||||
if [[ ! "$should_skip" == true ]]; then
|
||||
if [[ "$file_path" == *"$pattern"* ]] || [[ "$relative_path" == *"$pattern"* ]]; then
|
||||
# Substring matching (only if pattern starts with '**')
|
||||
if [[ ! "$should_skip" == true && "$pattern" == \*\** ]]; then
|
||||
local substring_pattern="${pattern#\*\*}" # Remove the leading '**'
|
||||
if [[ -n "$substring_pattern" && ("$file_path" == *"$substring_pattern"* || "$relative_path" == *"$substring_pattern"*) ]]; then
|
||||
should_skip=true
|
||||
fi
|
||||
fi
|
||||
@@ -417,7 +423,6 @@ list_packages() {
|
||||
build_packages() {
|
||||
local build_mode="$1"
|
||||
local packages_to_build=()
|
||||
local rebuilt_packages=0
|
||||
|
||||
case "$build_mode" in
|
||||
"changed")
|
||||
@@ -474,7 +479,6 @@ build_packages() {
|
||||
log_info "Package building cancelled by user"
|
||||
return
|
||||
fi
|
||||
|
||||
for pkg_name in "${packages_to_build[@]}"; do
|
||||
pkg_dir="${ARCH_PACKAGES_DIR}/${pkg_name}"
|
||||
|
||||
@@ -490,7 +494,10 @@ build_packages() {
|
||||
continue
|
||||
fi
|
||||
|
||||
cd "$pkg_dir" || continue
|
||||
cd "$pkg_dir" || {
|
||||
log_error "Failed to change to package directory: $pkg_dir"
|
||||
continue
|
||||
}
|
||||
|
||||
if makepkg -si --noconfirm; then
|
||||
log_success "Successfully built and installed $pkg_name"
|
||||
@@ -655,9 +662,20 @@ rebuilt_packages=0
|
||||
if [[ "$CHECK_PACKAGES" == true ]]; then
|
||||
log_header "Package Management"
|
||||
|
||||
if [[ ! -d "$ARCH_PACKAGES_DIR" ]]; then
|
||||
log_warning "No packages directory found (tried: dist-arch, arch-packages, sdist/arch). Skipping package management."
|
||||
# Check if required Arch Linux tools are available
|
||||
if ! command -v pacman &>/dev/null || ! command -v makepkg &>/dev/null; then
|
||||
log_warning "Arch Linux package management tools (pacman/makepkg) not found."
|
||||
log_warning "Skipping package management as this appears to be a non-Arch Linux system."
|
||||
log_warning "Use -p/--packages flag only on Arch Linux systems."
|
||||
PKG_TOOLS_AVAILABLE=false
|
||||
else
|
||||
PKG_TOOLS_AVAILABLE=true
|
||||
fi
|
||||
|
||||
if [[ "$PKG_TOOLS_AVAILABLE" == true ]]; then
|
||||
if [[ ! -d "$ARCH_PACKAGES_DIR" ]]; then
|
||||
log_warning "No packages directory found (tried: dist-arch, arch-packages, sdist/arch). Skipping package management."
|
||||
else
|
||||
changed_pkgbuilds=()
|
||||
for pkg_dir in "$ARCH_PACKAGES_DIR"/*/; do
|
||||
if [[ -f "${pkg_dir}/PKGBUILD" ]]; then
|
||||
@@ -678,7 +696,19 @@ if [[ "$CHECK_PACKAGES" == true ]]; then
|
||||
echo "4) Skip package building"
|
||||
echo
|
||||
|
||||
if safe_read "Choose an option (1-4): " pkg_choice "1"; then
|
||||
if [[ "$NON_INTERACTIVE" == true ]]; then
|
||||
pkg_choice="1"
|
||||
log_info "Non-interactive mode: Using default package option: $pkg_choice"
|
||||
elif safe_read "Choose an option (1-4): " pkg_choice "1"; then
|
||||
if [[ "$VERBOSE" == true ]]; then
|
||||
log_info "User selected package option: $pkg_choice"
|
||||
fi
|
||||
else
|
||||
log_warning "Failed to read input. Skipping package building."
|
||||
pkg_choice=""
|
||||
fi
|
||||
|
||||
if [[ -n "$pkg_choice" ]]; then
|
||||
case $pkg_choice in
|
||||
1) build_packages "changed" ;;
|
||||
2)
|
||||
@@ -689,14 +719,23 @@ if [[ "$CHECK_PACKAGES" == true ]]; then
|
||||
3) build_packages "all" ;;
|
||||
4 | *) log_info "Skipping package building" ;;
|
||||
esac
|
||||
else
|
||||
log_warning "Failed to read input. Skipping package building."
|
||||
fi
|
||||
else
|
||||
log_info "No PKGBUILDs have changed since last update."
|
||||
echo
|
||||
if safe_read "Do you want to check and build packages anyway? (y/N): " check_anyway "N"; then
|
||||
if [[ "$check_anyway" =~ ^[Yy]$ ]]; then
|
||||
if [[ "$NON_INTERACTIVE" == true ]]; then
|
||||
check_anyway="N"
|
||||
log_info "Non-interactive mode: Using default for check packages anyway: $check_anyway"
|
||||
elif safe_read "Do you want to check and build packages anyway? (y/N): " check_anyway "N"; then
|
||||
if [[ "$VERBOSE" == true ]]; then
|
||||
log_info "User chose to check packages anyway: $check_anyway"
|
||||
fi
|
||||
else
|
||||
log_warning "Failed to read input. Skipping package management."
|
||||
check_anyway=""
|
||||
fi
|
||||
|
||||
if [[ -n "$check_anyway" && "$check_anyway" =~ ^[Yy]$ ]]; then
|
||||
if list_packages; then
|
||||
echo
|
||||
echo "Package build options:"
|
||||
@@ -717,26 +756,11 @@ if [[ "$CHECK_PACKAGES" == true ]]; then
|
||||
else
|
||||
log_info "Skipping package management"
|
||||
fi
|
||||
else
|
||||
log_info "Skipping package management"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
else
|
||||
log_header "Package Management"
|
||||
log_info "Package checking disabled. Use -p or --packages flag to enable package management."
|
||||
|
||||
if [[ -d "$ARCH_PACKAGES_DIR" ]]; then
|
||||
changed_count=0
|
||||
for pkg_dir in "$ARCH_PACKAGES_DIR"/*/; do
|
||||
if [[ -f "${pkg_dir}/PKGBUILD" ]] && check_pkgbuild_changed "$pkg_dir"; then
|
||||
((changed_count++))
|
||||
fi
|
||||
done
|
||||
|
||||
if [[ $changed_count -gt 0 ]]; then
|
||||
log_warning "Note: $changed_count package(s) have changed PKGBUILDs. Use -p flag to manage packages."
|
||||
fi
|
||||
else
|
||||
log_header "Package Management"
|
||||
log_info "Package checking disabled. Use -p or --packages flag to enable package management."
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -794,9 +818,16 @@ if [[ "$process_files" == true ]]; then
|
||||
home_file="${home_dir_path}/${rel_path}"
|
||||
|
||||
if should_ignore "$home_file"; then
|
||||
if [[ "$VERBOSE" == true ]]; then
|
||||
log_info "Ignored: $rel_path (matches ignore pattern)"
|
||||
fi
|
||||
continue
|
||||
fi
|
||||
|
||||
if [[ "$VERBOSE" == true ]]; then
|
||||
log_info "Processing: $rel_path"
|
||||
fi
|
||||
|
||||
((files_processed++))
|
||||
|
||||
if [[ "$DRY_RUN" != true ]]; then
|
||||
|
||||
Reference in New Issue
Block a user