summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2026-06-02 22:19:38 +0300
committerPaul Buetow <paul@buetow.org>2026-06-02 22:19:38 +0300
commiteff352ff2c1f9b0578a5884e3e0d81b1a26c6031 (patch)
tree20bb5312911b4eef544f0c5cbf19f643e87177f8
parent7557532c88f086106fb2ff52b07e73dfc68e9ee6 (diff)
Add CLI config overrides for mi0
-rw-r--r--README.md19
-rwxr-xr-xbin/photoalbum126
-rwxr-xr-xsrc/photoalbum.sh126
-rwxr-xr-xtests/cli.sh139
4 files changed, 400 insertions, 10 deletions
diff --git a/README.md b/README.md
index 5ef5880..f33e4df 100644
--- a/README.md
+++ b/README.md
@@ -18,8 +18,8 @@ modern `magick` command and falls back to `convert` when needed.
## Usage
```
- photoalbum --generate [--config PATH]
- photoalbum --clean [--config PATH]
+ photoalbum --generate [--config PATH] [OPTIONS]
+ photoalbum --clean [--config PATH] [OPTIONS]
photoalbum --version
photoalbum --init
```
@@ -30,6 +30,21 @@ modern `magick` command and falls back to `convert` when needed.
* `--version`: Prints out the version
* `--init`: Creates a `photoalbum.conf` in the current working directory
+The following long options can be used with `--generate` or `--clean` to
+override values loaded from `photoalbum.conf`:
+
+* `--incoming PATH`: Overrides `INCOMING_DIR`
+* `--dist PATH`: Overrides `DIST_DIR`
+* `--template PATH`: Overrides `TEMPLATE_DIR`
+* `--title TEXT`: Overrides `TITLE`
+* `--height VALUE`: Overrides `HEIGHT`
+* `--thumbheight VALUE`: Overrides `THUMBHEIGHT`
+* `--maxpreviews N`: Overrides `MAXPREVIEWS`
+* `--shuffle`: Sets `SHUFFLE=yes`
+* `--no-shuffle`: Sets `SHUFFLE=no`
+* `--tarball`: Sets `TARBALL_INCLUDE=yes`
+* `--no-tarball`: Sets `TARBALL_INCLUDE=no`
+
## Example usage
1. Run `photoalbum --init`, which creates a `photoalbum.conf` file in the current directory from the installed/default config template.
diff --git a/bin/photoalbum b/bin/photoalbum
index b684c7f..5ca10d2 100755
--- a/bin/photoalbum
+++ b/bin/photoalbum
@@ -10,10 +10,23 @@ declare -r DEFAULTRC="${PHOTOALBUM_DEFAULT_RC:-/etc/default/photoalbum}"
usage() {
cat - <<USAGE >&2
Usage:
- $0 --generate [--config PATH]
- $0 --clean [--config PATH]
+ $0 --generate [--config PATH] [OPTIONS]
+ $0 --clean [--config PATH] [OPTIONS]
$0 --version
$0 --init
+
+ Options:
+ --incoming PATH
+ --dist PATH
+ --template PATH
+ --title TEXT
+ --height VALUE
+ --thumbheight VALUE
+ --maxpreviews N
+ --shuffle
+ --no-shuffle
+ --tarball
+ --no-tarball
USAGE
}
@@ -521,9 +534,61 @@ apply_config_defaults() {
TAR_OPTS="${TAR_OPTS:--c}"
}
+option_value() {
+ local -r option="$1"; shift
+
+ if (( $# == 0 )) || [ -z "$1" ]; then
+ echo "Error: $option requires a value" >&2
+ usage
+ exit 1
+ fi
+
+ printf '%s\n' "$1"
+}
+
+apply_cli_overrides() {
+ if [ -n "$cli_incoming_dir" ]; then
+ INCOMING_DIR="$cli_incoming_dir"
+ fi
+ if [ -n "$cli_dist_dir" ]; then
+ DIST_DIR="$cli_dist_dir"
+ fi
+ if [ -n "$cli_template_dir" ]; then
+ TEMPLATE_DIR="$cli_template_dir"
+ fi
+ if [ -n "$cli_title" ]; then
+ TITLE="$cli_title"
+ fi
+ if [ -n "$cli_height" ]; then
+ HEIGHT="$cli_height"
+ fi
+ if [ -n "$cli_thumbheight" ]; then
+ THUMBHEIGHT="$cli_thumbheight"
+ fi
+ if [ -n "$cli_maxpreviews" ]; then
+ MAXPREVIEWS="$cli_maxpreviews"
+ fi
+ if [ -n "$cli_shuffle" ]; then
+ SHUFFLE="$cli_shuffle"
+ fi
+ if [ -n "$cli_tarball_include" ]; then
+ TARBALL_INCLUDE="$cli_tarball_include"
+ fi
+}
+
main() {
local action=''
local config_file=''
+ local has_config_overrides='no'
+ local cli_dist_dir=''
+ local cli_height=''
+ local cli_incoming_dir=''
+ local cli_maxpreviews=''
+ local cli_shuffle=''
+ local cli_tarball_include=''
+ local cli_template_dir=''
+ local cli_thumbheight=''
+ local cli_title=''
local option
local rc_file
@@ -547,6 +612,57 @@ main() {
config_file="$1"
shift
;;
+ --incoming)
+ cli_incoming_dir=$(option_value "$option" "$@")
+ has_config_overrides='yes'
+ shift
+ ;;
+ --dist)
+ cli_dist_dir=$(option_value "$option" "$@")
+ has_config_overrides='yes'
+ shift
+ ;;
+ --template)
+ cli_template_dir=$(option_value "$option" "$@")
+ has_config_overrides='yes'
+ shift
+ ;;
+ --title)
+ cli_title=$(option_value "$option" "$@")
+ has_config_overrides='yes'
+ shift
+ ;;
+ --height)
+ cli_height=$(option_value "$option" "$@")
+ has_config_overrides='yes'
+ shift
+ ;;
+ --thumbheight)
+ cli_thumbheight=$(option_value "$option" "$@")
+ has_config_overrides='yes'
+ shift
+ ;;
+ --maxpreviews)
+ cli_maxpreviews=$(option_value "$option" "$@")
+ has_config_overrides='yes'
+ shift
+ ;;
+ --shuffle)
+ cli_shuffle='yes'
+ has_config_overrides='yes'
+ ;;
+ --no-shuffle)
+ cli_shuffle='no'
+ has_config_overrides='yes'
+ ;;
+ --tarball)
+ cli_tarball_include='yes'
+ has_config_overrides='yes'
+ ;;
+ --no-tarball)
+ cli_tarball_include='no'
+ has_config_overrides='yes'
+ ;;
--version|--init|--clean|--generate)
if [ -n "$action" ]; then
usage
@@ -564,7 +680,7 @@ main() {
case "$action" in
--version)
- if [ -n "$config_file" ]; then
+ if [[ -n "$config_file" || "$has_config_overrides" = 'yes' ]]; then
usage
exit 1
fi
@@ -572,7 +688,7 @@ main() {
echo "This is Photoalbum Version $VERSION"
;;
--init)
- if [ -n "$config_file" ]; then
+ if [[ -n "$config_file" || "$has_config_overrides" = 'yes' ]]; then
usage
exit 1
fi
@@ -588,6 +704,8 @@ main() {
source "$rc_file"
apply_config_defaults
+ apply_cli_overrides
+
case "$action" in
--clean)
if [ -d "$DIST_DIR" ]; then
diff --git a/src/photoalbum.sh b/src/photoalbum.sh
index 772371b..501f6da 100755
--- a/src/photoalbum.sh
+++ b/src/photoalbum.sh
@@ -10,10 +10,23 @@ declare -r DEFAULTRC="${PHOTOALBUM_DEFAULT_RC:-/etc/default/photoalbum}"
usage() {
cat - <<USAGE >&2
Usage:
- $0 --generate [--config PATH]
- $0 --clean [--config PATH]
+ $0 --generate [--config PATH] [OPTIONS]
+ $0 --clean [--config PATH] [OPTIONS]
$0 --version
$0 --init
+
+ Options:
+ --incoming PATH
+ --dist PATH
+ --template PATH
+ --title TEXT
+ --height VALUE
+ --thumbheight VALUE
+ --maxpreviews N
+ --shuffle
+ --no-shuffle
+ --tarball
+ --no-tarball
USAGE
}
@@ -521,9 +534,61 @@ apply_config_defaults() {
TAR_OPTS="${TAR_OPTS:--c}"
}
+option_value() {
+ local -r option="$1"; shift
+
+ if (( $# == 0 )) || [ -z "$1" ]; then
+ echo "Error: $option requires a value" >&2
+ usage
+ exit 1
+ fi
+
+ printf '%s\n' "$1"
+}
+
+apply_cli_overrides() {
+ if [ -n "$cli_incoming_dir" ]; then
+ INCOMING_DIR="$cli_incoming_dir"
+ fi
+ if [ -n "$cli_dist_dir" ]; then
+ DIST_DIR="$cli_dist_dir"
+ fi
+ if [ -n "$cli_template_dir" ]; then
+ TEMPLATE_DIR="$cli_template_dir"
+ fi
+ if [ -n "$cli_title" ]; then
+ TITLE="$cli_title"
+ fi
+ if [ -n "$cli_height" ]; then
+ HEIGHT="$cli_height"
+ fi
+ if [ -n "$cli_thumbheight" ]; then
+ THUMBHEIGHT="$cli_thumbheight"
+ fi
+ if [ -n "$cli_maxpreviews" ]; then
+ MAXPREVIEWS="$cli_maxpreviews"
+ fi
+ if [ -n "$cli_shuffle" ]; then
+ SHUFFLE="$cli_shuffle"
+ fi
+ if [ -n "$cli_tarball_include" ]; then
+ TARBALL_INCLUDE="$cli_tarball_include"
+ fi
+}
+
main() {
local action=''
local config_file=''
+ local has_config_overrides='no'
+ local cli_dist_dir=''
+ local cli_height=''
+ local cli_incoming_dir=''
+ local cli_maxpreviews=''
+ local cli_shuffle=''
+ local cli_tarball_include=''
+ local cli_template_dir=''
+ local cli_thumbheight=''
+ local cli_title=''
local option
local rc_file
@@ -547,6 +612,57 @@ main() {
config_file="$1"
shift
;;
+ --incoming)
+ cli_incoming_dir=$(option_value "$option" "$@")
+ has_config_overrides='yes'
+ shift
+ ;;
+ --dist)
+ cli_dist_dir=$(option_value "$option" "$@")
+ has_config_overrides='yes'
+ shift
+ ;;
+ --template)
+ cli_template_dir=$(option_value "$option" "$@")
+ has_config_overrides='yes'
+ shift
+ ;;
+ --title)
+ cli_title=$(option_value "$option" "$@")
+ has_config_overrides='yes'
+ shift
+ ;;
+ --height)
+ cli_height=$(option_value "$option" "$@")
+ has_config_overrides='yes'
+ shift
+ ;;
+ --thumbheight)
+ cli_thumbheight=$(option_value "$option" "$@")
+ has_config_overrides='yes'
+ shift
+ ;;
+ --maxpreviews)
+ cli_maxpreviews=$(option_value "$option" "$@")
+ has_config_overrides='yes'
+ shift
+ ;;
+ --shuffle)
+ cli_shuffle='yes'
+ has_config_overrides='yes'
+ ;;
+ --no-shuffle)
+ cli_shuffle='no'
+ has_config_overrides='yes'
+ ;;
+ --tarball)
+ cli_tarball_include='yes'
+ has_config_overrides='yes'
+ ;;
+ --no-tarball)
+ cli_tarball_include='no'
+ has_config_overrides='yes'
+ ;;
--version|--init|--clean|--generate)
if [ -n "$action" ]; then
usage
@@ -564,7 +680,7 @@ main() {
case "$action" in
--version)
- if [ -n "$config_file" ]; then
+ if [[ -n "$config_file" || "$has_config_overrides" = 'yes' ]]; then
usage
exit 1
fi
@@ -572,7 +688,7 @@ main() {
echo "This is Photoalbum Version $VERSION"
;;
--init)
- if [ -n "$config_file" ]; then
+ if [[ -n "$config_file" || "$has_config_overrides" = 'yes' ]]; then
usage
exit 1
fi
@@ -588,6 +704,8 @@ main() {
source "$rc_file"
apply_config_defaults
+ apply_cli_overrides
+
case "$action" in
--clean)
if [ -d "$DIST_DIR" ]; then
diff --git a/tests/cli.sh b/tests/cli.sh
index 6608c34..3dadc7b 100755
--- a/tests/cli.sh
+++ b/tests/cli.sh
@@ -159,6 +159,23 @@ test_clean_with_config() {
teardown
}
+test_clean_cli_dist_overrides_config() {
+ local config_file
+
+ setup
+ config_file="$TEST_TMPDIR/photoalbum.conf"
+ printf 'DIST_DIR=%q/config-dist\n' "$TEST_TMPDIR" > "$config_file"
+ mkdir -p "$TEST_TMPDIR/config-dist" "$TEST_TMPDIR/cli-dist"
+
+ (
+ cd "$TEST_TMPDIR"
+ "$PHOTOALBUM" --clean --dist "$TEST_TMPDIR/cli-dist"
+ test -d "$TEST_TMPDIR/config-dist"
+ test ! -e "$TEST_TMPDIR/cli-dist"
+ )
+ teardown
+}
+
test_clean_missing_config_fails() {
local output
@@ -195,6 +212,116 @@ test_generate_with_config_missing_incoming_fails() {
teardown
}
+test_generate_cli_overrides_config_values() {
+ local config_file
+ local fake_bin
+ local page_html
+ local view_html
+
+ setup
+ fake_bin="$TEST_TMPDIR/bin"
+ config_file="$TEST_TMPDIR/photoalbum.conf"
+
+ mkdir -p "$fake_bin" "$TEST_TMPDIR/cli-incoming"
+ cat > "$fake_bin/magick" <<'MAGICK'
+#!/usr/bin/env bash
+set -euo pipefail
+
+dest="${@: -1}"
+mkdir -p "$(dirname "$dest")"
+printf 'fake image\n' > "$dest"
+MAGICK
+ chmod 0755 "$fake_bin/magick"
+ printf 'fake image\n' > "$TEST_TMPDIR/cli-incoming/01.jpg"
+ printf 'fake image\n' > "$TEST_TMPDIR/cli-incoming/02.jpg"
+
+ {
+ printf 'TITLE=%q\n' 'Config title'
+ printf 'THUMBHEIGHT=10\n'
+ printf 'HEIGHT=20\n'
+ printf 'MAXPREVIEWS=40\n'
+ printf 'SHUFFLE=yes\n'
+ printf 'INCOMING_DIR=%q/config-incoming\n' "$TEST_TMPDIR"
+ printf 'DIST_DIR=%q/config-dist\n' "$TEST_TMPDIR"
+ printf 'TEMPLATE_DIR=%q/config-template\n' "$TEST_TMPDIR"
+ printf 'TARBALL_INCLUDE=yes\n'
+ } > "$config_file"
+
+ (
+ cd "$TEST_TMPDIR"
+ PATH="$fake_bin:$PATH" "$PHOTOALBUM" \
+ --generate \
+ --incoming "$TEST_TMPDIR/cli-incoming" \
+ --dist "$TEST_TMPDIR/cli-dist" \
+ --template "$REPO_ROOT/share/templates/default" \
+ --title 'CLI title' \
+ --height 456 \
+ --thumbheight 45 \
+ --maxpreviews 1 \
+ --no-shuffle \
+ --no-tarball
+ )
+
+ page_html=$(<"$TEST_TMPDIR/cli-dist/html/page-1.html")
+ view_html=$(<"$TEST_TMPDIR/cli-dist/html/1-1.html")
+
+ test -f "$TEST_TMPDIR/cli-dist/photos/01.jpg"
+ test -f "$TEST_TMPDIR/cli-dist/photos/02.jpg"
+ test ! -e "$TEST_TMPDIR/config-dist"
+ test ! -e "$TEST_TMPDIR/cli-dist/cli-incoming-"*.tar
+ assert_contains '<title>CLI title</title>' "$page_html"
+ assert_contains 'height: 45px;' "$page_html"
+ assert_contains 'max-height: 456px;' "$view_html"
+ assert_contains 'Next 1 pictures' "$page_html"
+ assert_not_contains 'Config title' "$page_html"
+
+ teardown
+}
+
+test_generate_cli_tarball_overrides_config() {
+ local config_file
+ local fake_bin
+ local tarball_count
+
+ setup
+ fake_bin="$TEST_TMPDIR/bin"
+ config_file="$TEST_TMPDIR/photoalbum.conf"
+
+ mkdir -p "$fake_bin" "$TEST_TMPDIR/incoming"
+ cat > "$fake_bin/magick" <<'MAGICK'
+#!/usr/bin/env bash
+set -euo pipefail
+
+dest="${@: -1}"
+mkdir -p "$(dirname "$dest")"
+printf 'fake image\n' > "$dest"
+MAGICK
+ chmod 0755 "$fake_bin/magick"
+ printf 'fake image\n' > "$TEST_TMPDIR/incoming/01.jpg"
+
+ {
+ printf 'TITLE=%q\n' 'Tarball override'
+ printf 'THUMBHEIGHT=30\n'
+ printf 'HEIGHT=120\n'
+ printf 'MAXPREVIEWS=40\n'
+ printf 'INCOMING_DIR=%q/incoming\n' "$TEST_TMPDIR"
+ printf 'DIST_DIR=%q/dist\n' "$TEST_TMPDIR"
+ printf 'TEMPLATE_DIR=%q/share/templates/default\n' "$REPO_ROOT"
+ printf 'TARBALL_INCLUDE=no\n'
+ } > "$config_file"
+
+ (
+ cd "$TEST_TMPDIR"
+ PATH="$fake_bin:$PATH" "$PHOTOALBUM" --generate --tarball
+ )
+
+ tarball_count=$(find "$TEST_TMPDIR/dist" -maxdepth 1 -name '*.tar' \
+ | wc -l)
+ test "$tarball_count" -eq 1
+
+ teardown
+}
+
test_generate_missing_incoming_fails() {
setup
{
@@ -400,6 +527,11 @@ test_extra_args_fail() {
assert_failure 'extra operand is rejected' "$PHOTOALBUM" --version extra
assert_failure 'unsupported option is rejected' "$PHOTOALBUM" --unknown
assert_failure 'missing config value is rejected' "$PHOTOALBUM" --config
+ assert_failure 'missing incoming value is rejected' "$PHOTOALBUM" --incoming
+ assert_failure 'missing title value is rejected' "$PHOTOALBUM" --title
+ assert_failure \
+ '--incoming is rejected with --version' \
+ "$PHOTOALBUM" --version --incoming /tmp/incoming
assert_failure \
'--config is rejected with --init' \
"$PHOTOALBUM" --init --config custom.conf
@@ -412,11 +544,18 @@ main() {
run_test '--init succeeds' test_init
run_test '--clean succeeds' test_clean
run_test '--clean --config succeeds' test_clean_with_config
+ run_test '--clean --dist overrides config' test_clean_cli_dist_overrides_config
run_test '--clean missing config fails clearly' test_clean_missing_config_fails
run_test \
'--generate --config reads selected config' \
test_generate_with_config_missing_incoming_fails
run_test \
+ '--generate CLI options override config' \
+ test_generate_cli_overrides_config_values
+ run_test \
+ '--generate --tarball overrides config' \
+ test_generate_cli_tarball_overrides_config
+ run_test \
'--generate missing incoming fails' \
test_generate_missing_incoming_fails
run_test \