Skip to content

Commit 66c9068

Browse files
committed
feat: make configuration overridable
1 parent 1943181 commit 66c9068

File tree

2 files changed

+108
-56
lines changed

2 files changed

+108
-56
lines changed

APPw

Lines changed: 53 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,47 @@
11
#!/bin/bash
22

3-
# --- Configuration ---
4-
NAME="APP"
5-
APP_HOME="$HOME_DIR/.$NAME"
3+
# --- Configuration (Non-Overridable) ---
4+
APP_NAME="APP"
5+
APP_DIR=".APP"
66
RELEASE_URL="https://example.com/releases/foo-latest.tgz"
7-
# ---------------------
7+
# ---------------------------------------
88

9-
# Automatically determine the user's home directory
9+
# 1. Setup essential variables needed for config loading
1010
HOME_DIR="$HOME"
11+
APP_HOME="$HOME_DIR/$APP_DIR"
12+
13+
# 2. Define default overridable variables
14+
# The update period in days (e.g., 3 means check if the last_checked file is older than 3 days)
15+
UPDATE_PERIOD=3
16+
17+
# --- Configuration Loading ---
18+
# Function to load configuration variables from a file
19+
load_config() {
20+
local config_file="$1"
21+
if [ -f "$config_file" ]; then
22+
LOG "Loading configuration from $config_file..."
23+
# Use a temporary file to strip comments and source the clean output
24+
local temp_config
25+
temp_config=$(mktemp)
26+
# Strip lines starting with # or containing only whitespace, then source
27+
grep -v '^\s*#' "$config_file" | grep -v '^\s*$' > "$temp_config"
28+
source "$temp_config" 2>/dev/null
29+
rm "$temp_config"
30+
fi
31+
}
32+
33+
# Load user-wide configuration (if exists)
34+
load_config "$APP_HOME/bootstrap.cfg"
35+
36+
# Load local configuration (if exists)
37+
load_config "./$APP_DIR/bootstrap.cfg"
38+
39+
# -----------------------------
40+
41+
# 3. Define the remaining path variables using the (potentially overridden) APP_NAME/UPDATE_PERIOD
1142
CACHE_DIR="$APP_HOME/cache"
1243
BIN_DIR="$APP_HOME/bin"
13-
APP_EXE="$BIN_DIR/$NAME"
44+
APP_EXE="$BIN_DIR/$APP_NAME"
1445
ARCHIVE_FILE="$CACHE_DIR/release.tgz"
1546
LAST_CHECKED_FILE="$CACHE_DIR/last_checked"
1647

@@ -39,7 +70,7 @@ get_file_mtime() {
3970

4071
perform_full_install() {
4172
LOG "Application not found or update forced. Starting download and install..."
42-
73+
4374
# 1. Setup directories
4475
mkdir -p "$CACHE_DIR" || { LOG "Error: Could not create cache directory $CACHE_DIR"; exit 1; }
4576

@@ -63,7 +94,7 @@ perform_full_install() {
6394
exit 1
6495
fi
6596

66-
# Find the top-level directory inside the archive (often matches the NAME)
97+
# Find the top-level directory inside the archive (often matches the APP_NAME)
6798
# Move the contents of the single directory inside the archive to the app home
6899
# Assuming the archive unpacks to a single directory (e.g., 'foo-v1.0')
69100
UNPACKED_ROOT=$(find "$APP_HOME/temp_install" -mindepth 1 -maxdepth 1 -type d -print -quit)
@@ -80,7 +111,7 @@ perform_full_install() {
80111
mv "$APP_HOME/temp_install"/* "$APP_HOME" 2>/dev/null
81112
mv "$APP_HOME/temp_install"/.* "$APP_HOME" 2>/dev/null # Move hidden files/dirs too
82113
fi
83-
114+
84115
# Clean up the temporary directory
85116
rm -rf "$APP_HOME/temp_install"
86117

@@ -91,28 +122,28 @@ perform_full_install() {
91122

92123

93124
handle_update_check() {
94-
# 1. Check file age: older than 3 days?
125+
# 1. Check file age: older than $UPDATE_PERIOD days?
95126
# find command exits 0 and prints if a file matching criteria is found.
96-
# -mtime +3 means modification time is older than 3 full 24-hour periods.
97-
if [ ! -f "$LAST_CHECKED_FILE" ] || find "$LAST_CHECKED_FILE" -mtime +3 -print -quit 2>/dev/null; then
98-
LOG "Checking for updates (last check older than 3 days or file missing)..."
99-
127+
# -mtime +N means modification time is older than N full 24-hour periods.
128+
if [ ! -f "$LAST_CHECKED_FILE" ] || find "$LAST_CHECKED_FILE" -mtime +$UPDATE_PERIOD -print -quit 2>/dev/null; then
129+
LOG "Checking for updates (last check older than $UPDATE_PERIOD days or file missing)..."
130+
100131
# Record the modification time of the current archive before potential download
101132
local OLD_MTIME=$(get_file_mtime "$ARCHIVE_FILE")
102-
133+
103134
# 2. Conditional Download
104135
# -z "$ARCHIVE_FILE" tells curl to only download if the remote file is newer than the local one.
105136
# --remote-time (-r) ensures the new file uses the remote timestamp.
106137
LOG "Attempting conditional download..."
107-
138+
108139
# Use -w "%{http_code}" to capture the status code
109140
HTTP_CODE=$(curl -w "%{http_code}" -sSL --remote-time -z "$ARCHIVE_FILE" "$RELEASE_URL" -o "$ARCHIVE_FILE")
110-
141+
111142
# 3. Check for successful download (HTTP 200) or successful conditional skip (HTTP 304 Not Modified)
112143
if [ "$HTTP_CODE" -ge 200 ] && [ "$HTTP_CODE" -lt 300 ]; then
113144
# Download successful (200 OK)
114145
LOG "New release downloaded."
115-
146+
116147
# Record the new modification time of the archive
117148
local NEW_MTIME=$(get_file_mtime "$ARCHIVE_FILE")
118149

@@ -136,7 +167,7 @@ handle_update_check() {
136167
touch "$LAST_CHECKED_FILE"
137168
LOG "Update check complete. Timestamp updated."
138169
else
139-
LOG "Skipping update check (last check within 3 days)."
170+
LOG "Skipping update check (last check within $UPDATE_PERIOD days)."
140171
fi
141172
}
142173

@@ -164,15 +195,15 @@ if [ "$CURRENT_SCRIPT_PATH" != "$BIN_EXE_PATH" ]; then
164195
exec "$APP_EXE" "$@"
165196
fi
166197

167-
# If we are running from $BIN_DIR/$NAME, the script continues below this line.
198+
# If we are running from $BIN_DIR/$APP_NAME, the script continues below this line.
168199
# This part is the "whatever might be there" section.
169200
LOG "Running inside the application's environment ($BIN_DIR)."
170201
# Example: start the application with special debugging flags, or run cleanup tasks.
171202
# Your application's main logic or final execution step would go here if this script
172203
# *is* the final executable.
173204
# For simplicity, we just print a success message and exit.
174-
echo "--- Application $NAME is running ---"
205+
echo "--- Application $APP_NAME is running ---"
175206
echo "Arguments received: $@"
176207
echo "------------------------------------"
177208

178-
exit 0
209+
exit 0

APPw.cmd

Lines changed: 55 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,50 @@
11
@echo off
2-
setlocal
2+
setlocal enableExtensions enableDelayedExpansion
33

4-
rem --- Configuration ---
5-
set NAME=APP
6-
set "APP_HOME=%HOME_DIR%\.%NAME%"
4+
rem --- Configuration (Non-Overridable) ---
5+
set APP_NAME=APP
6+
set APP_DIR=.APP
77
set RELEASE_URL=https://example.com/releases/foo-latest.zip
8-
rem ---------------------
8+
rem ---------------------------------------
99

10-
rem --- Environment Setup ---
10+
rem 1. Setup essential variables needed for config loading
1111
set "HOME_DIR=%USERPROFILE%"
12+
set "APP_HOME=%HOME_DIR%\.%APP_DIR%"
13+
14+
rem 2. Define default overridable variables
15+
rem The update period in days (e.g., 3 means check if the last_checked file is older than 3 days)
16+
set UPDATE_PERIOD=3
17+
18+
rem --- Configuration Loading ---
19+
rem Helper subroutine to load configuration from a file
20+
:LOAD_CONFIG
21+
set "CONFIG_FILE=%~1"
22+
if exist "%CONFIG_FILE%" (
23+
call :LOG "Loading configuration from %CONFIG_FILE%..."
24+
rem /F "tokens=1,2 delims==" splits lines by '='. 'skip=0' is default. 'eol=#' handles comments.
25+
for /f "tokens=1* delims== eol=#" %%a in ('type "%CONFIG_FILE%"') do (
26+
rem %%a is the key (before '=') and %%b is the value (after '=')
27+
rem Handle specific known variable overrides here
28+
if /I "%%a" == "UPDATE_PERIOD" (
29+
set UPDATE_PERIOD=%%b
30+
)
31+
rem Add other overridable variables here if needed
32+
)
33+
)
34+
goto :eof
35+
36+
rem Load user-wide configuration (if exists)
37+
call :LOAD_CONFIG "%APP_HOME%\bootstrap.cfg"
38+
39+
rem Load local configuration (if exists)
40+
call :LOAD_CONFIG ".\%APP_DIR%\bootstrap.cfg"
41+
42+
rem -----------------------------
43+
44+
rem 3. Define the remaining path variables using the (potentially overridden) NAME/UPDATE_PERIOD
1245
set "CACHE_DIR=%APP_HOME%\cache"
1346
set "BIN_DIR=%APP_HOME%\bin"
14-
set "APP_EXE=%BIN_DIR%\%NAME%.cmd"
47+
set "APP_EXE=%BIN_DIR%\%APP_NAME%.cmd"
1548
set "ARCHIVE_FILE=%CACHE_DIR%\release.zip"
1649
set "LAST_CHECKED_FILE=%CACHE_DIR%\last_checked"
1750

@@ -59,12 +92,6 @@ rem --- Core Logic Functions ---
5992
)
6093

6194
rem Move contents from the temporary unpack location to the application home
62-
rem This requires navigating the directory structure, which is complex in Batch.
63-
rem We will assume the archive root needs to be moved into APP_HOME.
64-
65-
rem Move everything from temp_install (including the content of any single root folder)
66-
rem Note: This assumes the ZIP contains a single root folder or direct files.
67-
6895
rem Use XCOPY to move files/directories
6996
call :LOG "Moving contents to %APP_HOME%"
7097

@@ -83,35 +110,29 @@ rem --- Core Logic Functions ---
83110
:HANDLE_UPDATE_CHECK
84111
set "UPDATE_NEEDED=false"
85112

86-
rem Check file age: older than 3 days? (or doesn't exist)
113+
rem Check file age: older than %UPDATE_PERIOD% days? (or doesn't exist)
87114
rem forfiles exits with ERRORLEVEL 0 if files matching the criteria are found.
88-
rem /D -3 means files older than 3 days ago.
89-
forfiles /P "%CACHE_DIR%" /M last_checked /D -3 /C "cmd /c echo Found > nul" 2>nul
115+
rem /D -N means files older than N days ago.
116+
forfiles /P "%CACHE_DIR%" /M last_checked /D -%UPDATE_PERIOD% /C "cmd /c echo Found > nul" 2>nul
90117
if errorlevel 1 (
91-
rem ERRORLEVEL 1 means no files older than 3 days were found (either file is new, or file doesn't exist)
92-
rem We need the inverse logic: We want to update if it DOESN'T exist OR if it IS older.
118+
rem ERRORLEVEL 1 means no files older than %UPDATE_PERIOD% days were found (either file is new, or file doesn't exist)
93119
if not exist "%LAST_CHECKED_FILE%" (
94120
set "UPDATE_NEEDED=true"
95121
) else (
96-
rem Re-check: forfiles /D -N checks for files older than N days.
97-
rem If no file is found, the file is either missing or newer than N days.
98-
rem The initial check is flawed for the "newer than" case.
99-
100-
rem Simpler, more reliable check: find if any file named last_checked *exists*.
101-
rem If it exists, use forfiles to check if it's OLDER than 3 days.
102-
set "IS_OLD=true"
103-
forfiles /P "%CACHE_DIR%" /M last_checked /D -3 /C "cmd /c set IS_OLD=false" 2>nul
122+
rem Check for files older than %UPDATE_PERIOD% days
123+
set "IS_OLD=false"
124+
forfiles /P "%CACHE_DIR%" /M last_checked /D -%UPDATE_PERIOD% /C "cmd /c set IS_OLD=true" 2>nul
104125
if "%IS_OLD%"=="true" (
105-
call :LOG "Checking for updates (last check older than 3 days or file missing)..."
126+
call :LOG "Checking for updates (last check older than %UPDATE_PERIOD% days or file missing)..."
106127
set "UPDATE_NEEDED=true"
107128
) else (
108-
call :LOG "Skipping update check (last check within 3 days)."
129+
call :LOG "Skipping update check (last check within %UPDATE_PERIOD% days)."
109130
goto :eof
110131
)
111132
)
112133
) else (
113-
rem The file exists and IS older than 3 days, so ERRORLEVEL 0 was returned.
114-
call :LOG "Checking for updates (last check older than 3 days)..."
134+
rem The file exists and IS older than %UPDATE_PERIOD% days, so ERRORLEVEL 0 was returned.
135+
call :LOG "Checking for updates (last check older than %UPDATE_PERIOD% days)..."
115136
set "UPDATE_NEEDED=true"
116137
)
117138

@@ -133,8 +154,8 @@ rem --- Core Logic Functions ---
133154
set "NEW_SIZE=0"
134155
if exist "%ARCHIVE_FILE%" for %%F in ("%ARCHIVE_FILE%") do set NEW_SIZE=%%~zF
135156

136-
if not "%OLD_SIZE%"=="%NEW_SIZE%" (
137-
call :LOG "New release downloaded (size changed: Old=%OLD_SIZE%, New=%NEW_SIZE%). Unpacking update."
157+
if not "!OLD_SIZE!"=="!NEW_SIZE!" (
158+
call :LOG "New release downloaded (size changed: Old=!OLD_SIZE!, New=!NEW_SIZE!). Unpacking update."
138159
rem 4. Unpack the new release
139160
call :PERFORM_FULL_INSTALL
140161
) else (
@@ -181,9 +202,9 @@ if /I NOT "%SCRIPT_DIR_CLEAN%" EQU "%BIN_DIR%" (
181202
rem If we are running from %BIN_DIR%, the script continues below this line.
182203
call :LOG "Running inside the application's environment (%BIN_DIR%)."
183204
rem This is the "whatever might be there" section.
184-
echo --- Application %NAME% is running ---
205+
echo --- Application %APP_NAME% is running ---
185206
echo Arguments received: %*
186207
echo ------------------------------------
187208

188209
endlocal
189-
exit /b 0
210+
exit /b 0

0 commit comments

Comments
 (0)