mirror of
https://codeberg.org/gigirassy/stack.git
synced 2026-08-30 15:27:39 +00:00
Add stack
This commit is contained in:
@@ -0,0 +1,227 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -uo pipefail
|
||||||
|
|
||||||
|
CONFIG_FILE="${STACK_CONF:-$HOME/stack.conf}"
|
||||||
|
|
||||||
|
COMPOSE_CANDIDATES=(
|
||||||
|
"compose.yml"
|
||||||
|
"compose.yaml"
|
||||||
|
"docker-compose.yml"
|
||||||
|
"docker-compose.yaml"
|
||||||
|
)
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
cat <<'EOF'
|
||||||
|
Usage:
|
||||||
|
stack start
|
||||||
|
stack add .
|
||||||
|
stack add foldername
|
||||||
|
stack add folder1 folder2 folder3
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
strip_quotes() {
|
||||||
|
local s="$1"
|
||||||
|
s="${s#\"}"
|
||||||
|
s="${s%\"}"
|
||||||
|
s="${s#\'}"
|
||||||
|
s="${s%\'}"
|
||||||
|
printf '%s' "$s"
|
||||||
|
}
|
||||||
|
|
||||||
|
resolve_path() {
|
||||||
|
local input="$1"
|
||||||
|
if command -v realpath >/dev/null 2>&1; then
|
||||||
|
realpath -m "$input"
|
||||||
|
else
|
||||||
|
python3 - "$input" <<'PY'
|
||||||
|
import os, sys
|
||||||
|
print(os.path.abspath(os.path.expanduser(sys.argv[1])))
|
||||||
|
PY
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
ensure_config_exists() {
|
||||||
|
if [[ ! -f "$CONFIG_FILE" ]]; then
|
||||||
|
mkdir -p "$(dirname "$CONFIG_FILE")"
|
||||||
|
cat > "$CONFIG_FILE" <<EOF
|
||||||
|
STACK_HOME=$HOME
|
||||||
|
# one folder per line below
|
||||||
|
EOF
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
load_config() {
|
||||||
|
STACK_HOME=""
|
||||||
|
STACK_DIRS=()
|
||||||
|
|
||||||
|
while IFS= read -r line || [[ -n "$line" ]]; do
|
||||||
|
line="${line%$'\r'}"
|
||||||
|
[[ -z "$line" ]] && continue
|
||||||
|
[[ "$line" =~ ^[[:space:]]*# ]] && continue
|
||||||
|
|
||||||
|
if [[ "$line" == STACK_HOME=* ]]; then
|
||||||
|
STACK_HOME="$(strip_quotes "${line#STACK_HOME=}")"
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
STACK_DIRS+=("$(strip_quotes "$line")")
|
||||||
|
done < "$CONFIG_FILE"
|
||||||
|
|
||||||
|
[[ -z "$STACK_HOME" ]] && STACK_HOME="$HOME"
|
||||||
|
}
|
||||||
|
|
||||||
|
compose_cmd() {
|
||||||
|
if docker compose version >/dev/null 2>&1; then
|
||||||
|
printf 'docker compose'
|
||||||
|
elif command -v docker-compose >/dev/null 2>&1; then
|
||||||
|
printf 'docker-compose'
|
||||||
|
else
|
||||||
|
echo "error: neither 'docker compose' nor 'docker-compose' is installed." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
add_folder() {
|
||||||
|
ensure_config_exists
|
||||||
|
load_config
|
||||||
|
|
||||||
|
if [[ $# -eq 0 ]]; then
|
||||||
|
echo "usage: stack add .|foldername|/path/to/folder [more folders...]" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
local added=0
|
||||||
|
local arg target
|
||||||
|
for arg in "$@"; do
|
||||||
|
if [[ "$arg" == "." ]]; then
|
||||||
|
target="$PWD"
|
||||||
|
elif [[ "$arg" == /* ]]; then
|
||||||
|
target="$arg"
|
||||||
|
else
|
||||||
|
target="$PWD/$arg"
|
||||||
|
fi
|
||||||
|
|
||||||
|
target="$(resolve_path "$target")"
|
||||||
|
|
||||||
|
if [[ ! -d "$target" ]]; then
|
||||||
|
echo "error: folder does not exist: $target" >&2
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
if grep -Fxq -- "$target" "$CONFIG_FILE"; then
|
||||||
|
echo "already in stack.conf: $target"
|
||||||
|
continue
|
||||||
|
fi || true
|
||||||
|
|
||||||
|
printf '%s\n' "$target" >> "$CONFIG_FILE"
|
||||||
|
echo "added: $target"
|
||||||
|
added=1
|
||||||
|
done
|
||||||
|
|
||||||
|
[[ "$added" -eq 0 ]] && exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
start_stacks() {
|
||||||
|
ensure_config_exists
|
||||||
|
load_config
|
||||||
|
|
||||||
|
local cc
|
||||||
|
cc="$(compose_cmd)"
|
||||||
|
|
||||||
|
local any=0 dir file found
|
||||||
|
for dir in "${STACK_DIRS[@]}"; do
|
||||||
|
[[ -z "$dir" ]] && continue
|
||||||
|
|
||||||
|
if [[ ! -d "$dir" ]]; then
|
||||||
|
echo "skipping missing folder: $dir" >&2
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
found=0
|
||||||
|
for file in "${COMPOSE_CANDIDATES[@]}"; do
|
||||||
|
if [[ -f "$dir/$file" ]]; then
|
||||||
|
found=1
|
||||||
|
any=1
|
||||||
|
echo "starting: $dir/$file"
|
||||||
|
(cd "$dir" && $cc -f "$file" up -d)
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [[ "$found" -eq 0 ]]; then
|
||||||
|
echo "no compose file found in: $dir" >&2
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [[ "$any" -eq 0 ]]; then
|
||||||
|
echo "no compose files were started."
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
update_stacks() {
|
||||||
|
ensure_config_exists
|
||||||
|
load_config
|
||||||
|
|
||||||
|
local cc
|
||||||
|
cc="$(compose_cmd)"
|
||||||
|
|
||||||
|
local any=0 dir file found
|
||||||
|
for dir in "${STACK_DIRS[@]}"; do
|
||||||
|
[[ -z "$dir" ]] && continue
|
||||||
|
|
||||||
|
if [[ ! -d "$dir" ]]; then
|
||||||
|
echo "skipping missing folder: $dir" >&2
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
found=0
|
||||||
|
for file in "${COMPOSE_CANDIDATES[@]}"; do
|
||||||
|
if [[ -f "$dir/$file" ]]; then
|
||||||
|
found=1
|
||||||
|
any=1
|
||||||
|
echo "updating: $dir/$file"
|
||||||
|
|
||||||
|
(
|
||||||
|
cd "$dir" && \
|
||||||
|
$cc -f "$file" pull && \
|
||||||
|
$cc -f "$file" up -d
|
||||||
|
)
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [[ "$found" -eq 0 ]]; then
|
||||||
|
echo "no compose file in: $dir" >&2
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [[ "$any" -eq 0 ]]; then
|
||||||
|
echo "no compose files updated."
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
main() {
|
||||||
|
local cmd="${1:-}"
|
||||||
|
shift || true
|
||||||
|
|
||||||
|
case "$cmd" in
|
||||||
|
start)
|
||||||
|
start_stacks
|
||||||
|
;;
|
||||||
|
update)
|
||||||
|
update_stacks
|
||||||
|
;;
|
||||||
|
add)
|
||||||
|
add_folder "$@"
|
||||||
|
;;
|
||||||
|
""|-h|--help|help)
|
||||||
|
usage
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "unknown command: $cmd" >&2
|
||||||
|
usage
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
main "$@"
|
||||||
Reference in New Issue
Block a user