diff options
| author | Paul Buetow <paul@buetow.org> | 2026-06-13 10:04:15 +0300 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2026-06-13 10:04:15 +0300 |
| commit | e9437367b8fc7a4cb0ffed6c0a8ba89356a3b9ad (patch) | |
| tree | 70c10195c1ad8c435e0d09faaab89b96afa0fc18 | |
| parent | dfcb18a189da91885172a9323a08a0d235432c5f (diff) | |
dm0: split dry-run planning from output
| -rwxr-xr-x | bin/shuriken | 136 | ||||
| -rw-r--r-- | src/lib/album.source.sh | 134 | ||||
| -rwxr-xr-x | tests/cli.sh | 56 |
3 files changed, 243 insertions, 83 deletions
diff --git a/bin/shuriken b/bin/shuriken index 82bd24e..b37aad3 100755 --- a/bin/shuriken +++ b/bin/shuriken @@ -2406,69 +2406,121 @@ refresh_splash() { } dry_run() { - local -i image_count=0 - local -i html_index_count=1 + # shellcheck disable=SC2034 + local -A dry_run_plan=() + + collect_dry_run_plan dry_run_plan + print_dry_run_plan dry_run_plan +} + +collect_dry_run_page_plan() { + local -r plan_name="$1"; shift + # shellcheck disable=SC2178 + local -n plan_ref="$plan_name" + local -r image_count="$1"; shift local -i page_count=0 local -i redirect_count=0 - local -i details_count=0 - image_count=$(count_incoming_images) + plan_ref["html_index_count"]=1 + plan_ref["page_count"]=0 + plan_ref["redirect_count"]=0 + plan_ref["details_count"]=0 if (( image_count > 0 )); then - details_count=$image_count page_count=$(( (image_count + MAXPREVIEWS - 1) / MAXPREVIEWS )) redirect_count=$(( page_count * 4 + 2 )) + plan_ref["details_count"]="$image_count" + plan_ref["page_count"]="$page_count" + plan_ref["redirect_count"]="$redirect_count" fi +} + +collect_dry_run_plan() { + local -r plan_name="$1"; shift + # shellcheck disable=SC2178 + local -n plan_ref="$plan_name" + local -i image_count=0 + + image_count=$(count_incoming_images) + plan_ref=() + plan_ref["config_source"]="$SHURIKEN_CONFIG_SOURCE" + plan_ref["incoming_dir"]="$INCOMING_DIR" + plan_ref["dist_dir"]="$DIST_DIR" + plan_ref["template_dir"]="$TEMPLATE_DIR" + plan_ref["title"]="$TITLE" + plan_ref["height"]="$HEIGHT" + plan_ref["thumbheight"]="$THUMBHEIGHT" + plan_ref["maxpreviews"]="$MAXPREVIEWS" + plan_ref["image_jobs"]="$IMAGE_JOBS" + plan_ref["random_seed"]="$RANDOM_SEED" + plan_ref["shuffle"]="$SHUFFLE" + plan_ref["splash_page"]="$SPLASH_PAGE" + plan_ref["image_count"]="$image_count" + plan_ref["tarball_include"]="$TARBALL_INCLUDE" + plan_ref["tarball_name_plan"]='not planned' - printf 'Dry run: no files will be written.\n' - printf 'Config source: %s\n' "$SHURIKEN_CONFIG_SOURCE" - printf 'Incoming directory: %s\n' "$INCOMING_DIR" - printf 'Output directory: %s\n' "$DIST_DIR" - printf 'Template directory: %s\n' "$TEMPLATE_DIR" - printf 'Title: %s\n' "$TITLE" - printf 'Height: %s\n' "$HEIGHT" - printf 'Thumb height: %s\n' "$THUMBHEIGHT" - printf 'Max previews per page: %s\n' "$MAXPREVIEWS" - printf 'Image jobs: %s\n' "$IMAGE_JOBS" - printf 'Random seed: %s\n' "$RANDOM_SEED" - printf 'Shuffle: %s\n' "$SHUFFLE" - printf 'Splash page: %s\n' "$SPLASH_PAGE" - printf 'Image count: %s\n' "$image_count" - printf 'Tarball setting: %s\n' "$TARBALL_INCLUDE" if [ "$TARBALL_INCLUDE" = yes ]; then - printf 'Tarball name plan: %s\n' "$(tarball_name_plan)" - else - printf 'Tarball name plan: not planned\n' + plan_ref["tarball_name_plan"]=$(tarball_name_plan) fi + collect_dry_run_page_plan "$plan_name" "$image_count" +} + +print_dry_run_plan() { + local -r plan_name="$1"; shift + # shellcheck disable=SC2178 + local -n plan_ref="$plan_name" + + printf 'Dry run: no files will be written.\n' + printf 'Config source: %s\n' "${plan_ref["config_source"]}" + printf 'Incoming directory: %s\n' "${plan_ref["incoming_dir"]}" + printf 'Output directory: %s\n' "${plan_ref["dist_dir"]}" + printf 'Template directory: %s\n' "${plan_ref["template_dir"]}" + printf 'Title: %s\n' "${plan_ref["title"]}" + printf 'Height: %s\n' "${plan_ref["height"]}" + printf 'Thumb height: %s\n' "${plan_ref["thumbheight"]}" + printf 'Max previews per page: %s\n' "${plan_ref["maxpreviews"]}" + printf 'Image jobs: %s\n' "${plan_ref["image_jobs"]}" + printf 'Random seed: %s\n' "${plan_ref["random_seed"]}" + printf 'Shuffle: %s\n' "${plan_ref["shuffle"]}" + printf 'Splash page: %s\n' "${plan_ref["splash_page"]}" + printf 'Image count: %s\n' "${plan_ref["image_count"]}" + printf 'Tarball setting: %s\n' "${plan_ref["tarball_include"]}" + printf 'Tarball name plan: %s\n' "${plan_ref["tarball_name_plan"]}" + printf 'Planned directories:\n' - printf ' %s\n' "$DIST_DIR" - printf ' %s/photos\n' "$DIST_DIR" - printf ' %s/thumbs\n' "$DIST_DIR" - printf ' %s/blurs\n' "$DIST_DIR" + printf ' %s\n' "${plan_ref["dist_dir"]}" + printf ' %s/photos\n' "${plan_ref["dist_dir"]}" + printf ' %s/thumbs\n' "${plan_ref["dist_dir"]}" + printf ' %s/blurs\n' "${plan_ref["dist_dir"]}" printf 'Planned generated files:\n' - if [ "$SPLASH_PAGE" = yes ]; then + if [ "${plan_ref["splash_page"]}" = yes ]; then printf ' %s/index.html (%s splash page)\n' \ - "$DIST_DIR" "$html_index_count" + "${plan_ref["dist_dir"]}" "${plan_ref["html_index_count"]}" else printf ' %s/index.html (%s album index redirect)\n' \ - "$DIST_DIR" "$html_index_count" - fi - printf ' %s/favicon.ico\n' "$DIST_DIR" - printf ' %s/shuriken.json\n' "$DIST_DIR" - printf ' %s/photos/* (%s image files)\n' "$DIST_DIR" "$image_count" - printf ' %s/thumbs/* (%s image files)\n' "$DIST_DIR" "$image_count" - printf ' %s/blurs/* (%s image files)\n' "$DIST_DIR" "$image_count" - printf ' %s/page-*.html (%s preview pages)\n' "$DIST_DIR" "$page_count" + "${plan_ref["dist_dir"]}" "${plan_ref["html_index_count"]}" + fi + printf ' %s/favicon.ico\n' "${plan_ref["dist_dir"]}" + printf ' %s/shuriken.json\n' "${plan_ref["dist_dir"]}" + printf ' %s/photos/* (%s image files)\n' \ + "${plan_ref["dist_dir"]}" "${plan_ref["image_count"]}" + printf ' %s/thumbs/* (%s image files)\n' \ + "${plan_ref["dist_dir"]}" "${plan_ref["image_count"]}" + printf ' %s/blurs/* (%s image files)\n' \ + "${plan_ref["dist_dir"]}" "${plan_ref["image_count"]}" + printf ' %s/page-*.html (%s preview pages)\n' \ + "${plan_ref["dist_dir"]}" "${plan_ref["page_count"]}" printf ' %s/[page]-[image].html (%s view pages)\n' \ - "$DIST_DIR" "$image_count" + "${plan_ref["dist_dir"]}" "${plan_ref["image_count"]}" printf ' %s/[page]-[image]-details.html (%s details pages)\n' \ - "$DIST_DIR" "$details_count" + "${plan_ref["dist_dir"]}" "${plan_ref["details_count"]}" printf ' %s/[redirect].html (%s navigation redirects)\n' \ - "$DIST_DIR" "$redirect_count" - if [ "$TARBALL_INCLUDE" = yes ]; then - printf ' %s/%s\n' "$DIST_DIR" "$(tarball_name_plan)" + "${plan_ref["dist_dir"]}" "${plan_ref["redirect_count"]}" + if [ "${plan_ref["tarball_include"]}" = yes ]; then + printf ' %s/%s\n' \ + "${plan_ref["dist_dir"]}" "${plan_ref["tarball_name_plan"]}" fi } diff --git a/src/lib/album.source.sh b/src/lib/album.source.sh index 6043fe0..beec5fd 100644 --- a/src/lib/album.source.sh +++ b/src/lib/album.source.sh @@ -1059,68 +1059,120 @@ refresh_splash() { } dry_run() { - local -i image_count=0 - local -i html_index_count=1 + # shellcheck disable=SC2034 + local -A dry_run_plan=() + + collect_dry_run_plan dry_run_plan + print_dry_run_plan dry_run_plan +} + +collect_dry_run_page_plan() { + local -r plan_name="$1"; shift + # shellcheck disable=SC2178 + local -n plan_ref="$plan_name" + local -r image_count="$1"; shift local -i page_count=0 local -i redirect_count=0 - local -i details_count=0 - image_count=$(count_incoming_images) + plan_ref["html_index_count"]=1 + plan_ref["page_count"]=0 + plan_ref["redirect_count"]=0 + plan_ref["details_count"]=0 if (( image_count > 0 )); then - details_count=$image_count page_count=$(( (image_count + MAXPREVIEWS - 1) / MAXPREVIEWS )) redirect_count=$(( page_count * 4 + 2 )) + plan_ref["details_count"]="$image_count" + plan_ref["page_count"]="$page_count" + plan_ref["redirect_count"]="$redirect_count" fi +} + +collect_dry_run_plan() { + local -r plan_name="$1"; shift + # shellcheck disable=SC2178 + local -n plan_ref="$plan_name" + local -i image_count=0 + + image_count=$(count_incoming_images) + plan_ref=() + plan_ref["config_source"]="$SHURIKEN_CONFIG_SOURCE" + plan_ref["incoming_dir"]="$INCOMING_DIR" + plan_ref["dist_dir"]="$DIST_DIR" + plan_ref["template_dir"]="$TEMPLATE_DIR" + plan_ref["title"]="$TITLE" + plan_ref["height"]="$HEIGHT" + plan_ref["thumbheight"]="$THUMBHEIGHT" + plan_ref["maxpreviews"]="$MAXPREVIEWS" + plan_ref["image_jobs"]="$IMAGE_JOBS" + plan_ref["random_seed"]="$RANDOM_SEED" + plan_ref["shuffle"]="$SHUFFLE" + plan_ref["splash_page"]="$SPLASH_PAGE" + plan_ref["image_count"]="$image_count" + plan_ref["tarball_include"]="$TARBALL_INCLUDE" + plan_ref["tarball_name_plan"]='not planned' - printf 'Dry run: no files will be written.\n' - printf 'Config source: %s\n' "$SHURIKEN_CONFIG_SOURCE" - printf 'Incoming directory: %s\n' "$INCOMING_DIR" - printf 'Output directory: %s\n' "$DIST_DIR" - printf 'Template directory: %s\n' "$TEMPLATE_DIR" - printf 'Title: %s\n' "$TITLE" - printf 'Height: %s\n' "$HEIGHT" - printf 'Thumb height: %s\n' "$THUMBHEIGHT" - printf 'Max previews per page: %s\n' "$MAXPREVIEWS" - printf 'Image jobs: %s\n' "$IMAGE_JOBS" - printf 'Random seed: %s\n' "$RANDOM_SEED" - printf 'Shuffle: %s\n' "$SHUFFLE" - printf 'Splash page: %s\n' "$SPLASH_PAGE" - printf 'Image count: %s\n' "$image_count" - printf 'Tarball setting: %s\n' "$TARBALL_INCLUDE" if [ "$TARBALL_INCLUDE" = yes ]; then - printf 'Tarball name plan: %s\n' "$(tarball_name_plan)" - else - printf 'Tarball name plan: not planned\n' + plan_ref["tarball_name_plan"]=$(tarball_name_plan) fi + collect_dry_run_page_plan "$plan_name" "$image_count" +} + +print_dry_run_plan() { + local -r plan_name="$1"; shift + # shellcheck disable=SC2178 + local -n plan_ref="$plan_name" + + printf 'Dry run: no files will be written.\n' + printf 'Config source: %s\n' "${plan_ref["config_source"]}" + printf 'Incoming directory: %s\n' "${plan_ref["incoming_dir"]}" + printf 'Output directory: %s\n' "${plan_ref["dist_dir"]}" + printf 'Template directory: %s\n' "${plan_ref["template_dir"]}" + printf 'Title: %s\n' "${plan_ref["title"]}" + printf 'Height: %s\n' "${plan_ref["height"]}" + printf 'Thumb height: %s\n' "${plan_ref["thumbheight"]}" + printf 'Max previews per page: %s\n' "${plan_ref["maxpreviews"]}" + printf 'Image jobs: %s\n' "${plan_ref["image_jobs"]}" + printf 'Random seed: %s\n' "${plan_ref["random_seed"]}" + printf 'Shuffle: %s\n' "${plan_ref["shuffle"]}" + printf 'Splash page: %s\n' "${plan_ref["splash_page"]}" + printf 'Image count: %s\n' "${plan_ref["image_count"]}" + printf 'Tarball setting: %s\n' "${plan_ref["tarball_include"]}" + printf 'Tarball name plan: %s\n' "${plan_ref["tarball_name_plan"]}" + printf 'Planned directories:\n' - printf ' %s\n' "$DIST_DIR" - printf ' %s/photos\n' "$DIST_DIR" - printf ' %s/thumbs\n' "$DIST_DIR" - printf ' %s/blurs\n' "$DIST_DIR" + printf ' %s\n' "${plan_ref["dist_dir"]}" + printf ' %s/photos\n' "${plan_ref["dist_dir"]}" + printf ' %s/thumbs\n' "${plan_ref["dist_dir"]}" + printf ' %s/blurs\n' "${plan_ref["dist_dir"]}" printf 'Planned generated files:\n' - if [ "$SPLASH_PAGE" = yes ]; then + if [ "${plan_ref["splash_page"]}" = yes ]; then printf ' %s/index.html (%s splash page)\n' \ - "$DIST_DIR" "$html_index_count" + "${plan_ref["dist_dir"]}" "${plan_ref["html_index_count"]}" else printf ' %s/index.html (%s album index redirect)\n' \ - "$DIST_DIR" "$html_index_count" + "${plan_ref["dist_dir"]}" "${plan_ref["html_index_count"]}" fi - printf ' %s/favicon.ico\n' "$DIST_DIR" - printf ' %s/shuriken.json\n' "$DIST_DIR" - printf ' %s/photos/* (%s image files)\n' "$DIST_DIR" "$image_count" - printf ' %s/thumbs/* (%s image files)\n' "$DIST_DIR" "$image_count" - printf ' %s/blurs/* (%s image files)\n' "$DIST_DIR" "$image_count" - printf ' %s/page-*.html (%s preview pages)\n' "$DIST_DIR" "$page_count" + printf ' %s/favicon.ico\n' "${plan_ref["dist_dir"]}" + printf ' %s/shuriken.json\n' "${plan_ref["dist_dir"]}" + printf ' %s/photos/* (%s image files)\n' \ + "${plan_ref["dist_dir"]}" "${plan_ref["image_count"]}" + printf ' %s/thumbs/* (%s image files)\n' \ + "${plan_ref["dist_dir"]}" "${plan_ref["image_count"]}" + printf ' %s/blurs/* (%s image files)\n' \ + "${plan_ref["dist_dir"]}" "${plan_ref["image_count"]}" + printf ' %s/page-*.html (%s preview pages)\n' \ + "${plan_ref["dist_dir"]}" "${plan_ref["page_count"]}" printf ' %s/[page]-[image].html (%s view pages)\n' \ - "$DIST_DIR" "$image_count" + "${plan_ref["dist_dir"]}" "${plan_ref["image_count"]}" printf ' %s/[page]-[image]-details.html (%s details pages)\n' \ - "$DIST_DIR" "$details_count" + "${plan_ref["dist_dir"]}" "${plan_ref["details_count"]}" printf ' %s/[redirect].html (%s navigation redirects)\n' \ - "$DIST_DIR" "$redirect_count" - if [ "$TARBALL_INCLUDE" = yes ]; then - printf ' %s/%s\n' "$DIST_DIR" "$(tarball_name_plan)" + "${plan_ref["dist_dir"]}" "${plan_ref["redirect_count"]}" + if [ "${plan_ref["tarball_include"]}" = yes ]; then + printf ' %s/%s\n' \ + "${plan_ref["dist_dir"]}" "${plan_ref["tarball_name_plan"]}" fi } diff --git a/tests/cli.sh b/tests/cli.sh index 7aeddfd..c4e3814 100755 --- a/tests/cli.sh +++ b/tests/cli.sh @@ -1801,6 +1801,59 @@ test_dry_run_reports_cli_overrides_without_writes() { test::teardown } +test_dry_run_reports_empty_plan_without_writes() { + local config_file + local dist_dir + local fake_bin + local forbidden_log + local incoming_dir + local output + + test::setup + fake_bin="$TEST_TMPDIR/bin" + config_file="$TEST_TMPDIR/shuriken.conf" + dist_dir="$TEST_TMPDIR/dist" + forbidden_log="$TEST_TMPDIR/forbidden-tools.log" + incoming_dir="$TEST_TMPDIR/incoming" + mkdir -p "$incoming_dir" + test::install_failing_generation_tools "$fake_bin" + test::write_preflight_config \ + "$config_file" "$incoming_dir" "$dist_dir" \ + "$TEST_REPO_ROOT/share/templates/default" + + output=$( + cd "$TEST_TMPDIR" + PATH="$fake_bin:$PATH" \ + TEST_FORBIDDEN_TOOL_LOG="$forbidden_log" \ + "$TEST_SHURIKEN" --dry-run --config "$config_file" + ) + + test::assert_contains 'Dry run: no files will be written.' "$output" + test::assert_contains 'Image count: 0' "$output" + test::assert_contains 'Tarball name plan: not planned' "$output" + test::assert_contains \ + " $dist_dir/index.html (1 splash page)" \ + "$output" + test::assert_contains " $dist_dir/photos/* (0 image files)" "$output" + test::assert_contains " $dist_dir/thumbs/* (0 image files)" "$output" + test::assert_contains " $dist_dir/blurs/* (0 image files)" "$output" + test::assert_contains " $dist_dir/page-*.html (0 preview pages)" \ + "$output" + test::assert_contains \ + " $dist_dir/[page]-[image].html (0 view pages)" \ + "$output" + test::assert_contains \ + " $dist_dir/[page]-[image]-details.html (0 details pages)" \ + "$output" + test::assert_contains \ + " $dist_dir/[redirect].html (0 navigation redirects)" \ + "$output" + test::assert_path_absent "$dist_dir" + test::assert_path_absent "$forbidden_log" + test::assert_no_staging_dirs "$TEST_TMPDIR" + test::teardown +} + test_dry_run_rejects_invalid_config_and_input() { local config_file local dist_dir @@ -4766,6 +4819,9 @@ main() { '--dry-run reports CLI overrides without writes' \ test_dry_run_reports_cli_overrides_without_writes test::run_case \ + '--dry-run reports empty plan without writes' \ + test_dry_run_reports_empty_plan_without_writes + test::run_case \ '--dry-run rejects invalid config and input' \ test_dry_run_rejects_invalid_config_and_input test::run_case \ |
