diff options
| author | Paul Buetow <paul@buetow.org> | 2026-06-17 23:21:03 +0300 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2026-06-17 23:21:03 +0300 |
| commit | 61890e0bd98262a55b3afff495ebfead33d76b96 (patch) | |
| tree | 9422f31856e205f6e9374a14c5205027f912d458 | |
| parent | 7c94be57437ecdc9cadeb95bc4c26a25040163a9 (diff) | |
Add configurable SOURCE_URL footer link; release 0.9.00.9.0
The footer "Site generated ... with <link>" was hardcoded to the shuriken.sh
repository. Make it configurable via the SOURCE_URL config variable and the
--source-url CLI flag (defaulting to the shuriken.sh repo, so existing sites are
unchanged). The footer derives the displayed text from the URL by stripping its
scheme. Plumbed through apply_config_defaults, CLI override targets/spec,
--print-config, the verbose effective-config log, and the header template's
new render_source_url_html (config_html) render var. Documented in
shuriken.default.conf and README; added a generation test asserting a custom
SOURCE_URL replaces the default footer link, and updated the print-config and
header render-var-subset expectations.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
| -rw-r--r-- | Justfile | 2 | ||||
| -rw-r--r-- | README.md | 18 | ||||
| -rwxr-xr-x | bin/shuriken | 16 | ||||
| -rw-r--r-- | share/templates/default/header.tmpl | 2 | ||||
| -rw-r--r-- | src/lib/action.source.sh | 1 | ||||
| -rw-r--r-- | src/lib/config.print.source.sh | 1 | ||||
| -rw-r--r-- | src/lib/config.source.sh | 5 | ||||
| -rw-r--r-- | src/lib/template.source.sh | 5 | ||||
| -rw-r--r-- | src/shuriken.default.conf | 6 | ||||
| -rwxr-xr-x | src/shuriken.sh | 2 | ||||
| -rwxr-xr-x | tests/cli.sh | 52 |
11 files changed, 101 insertions, 9 deletions
@@ -1,7 +1,7 @@ set shell := ["bash", "-euo", "pipefail", "-c"] NAME := "shuriken" -VERSION := "0.8.0" +VERSION := "0.9.0" DESTDIR := env_var_or_default("DESTDIR", "") PREFIX := env_var_or_default("PREFIX", "/usr") BINDIR := env_var_or_default("BINDIR", PREFIX + "/bin") @@ -76,10 +76,10 @@ When `--config PATH` is not provided, `--generate`, `--dry-run`, If the file is missing, run `shuriken --init` first. The config file is a Bash file with assignments such as `INCOMING_DIR`, -`DIST_DIR`, `TEMPLATE_DIR`, `FAVICON`, `TITLE`, `HEIGHT`, `THUMBHEIGHT`, -`MAXPREVIEWS`, `IMAGE_JOBS`, `IMAGEMAGICK_TIMEOUT`, `RANDOM_SEED`, `SHUFFLE`, -`SPLASH_PAGE`, `STATS_PAGE`, `TARBALL_INCLUDE`, `TAR_TIMEOUT`, `SYNC_DELETE`, and -`SYNC_DESTINATIONS`. +`DIST_DIR`, `TEMPLATE_DIR`, `FAVICON`, `SOURCE_URL`, `TITLE`, `HEIGHT`, +`THUMBHEIGHT`, `MAXPREVIEWS`, `IMAGE_JOBS`, `IMAGEMAGICK_TIMEOUT`, `RANDOM_SEED`, +`SHUFFLE`, `SPLASH_PAGE`, `STATS_PAGE`, `TARBALL_INCLUDE`, `TAR_TIMEOUT`, +`SYNC_DELETE`, and `SYNC_DESTINATIONS`. Before generating, `shuriken` validates the loaded config and command-line overrides. It checks required values, positive integer settings, `yes`/`no` @@ -97,8 +97,8 @@ values that generation would use after applying command-line overrides. Its tarball filename uses `<timestamp>` as a placeholder so the output is stable. `--print-config` writes stable shell-style assignments to stdout in this order: -`CONFIG_SOURCE`, `INCOMING_DIR`, `DIST_DIR`, `TEMPLATE_DIR`, `FAVICON`, `TITLE`, -`HEIGHT`, +`CONFIG_SOURCE`, `INCOMING_DIR`, `DIST_DIR`, `TEMPLATE_DIR`, `FAVICON`, +`SOURCE_URL`, `TITLE`, `HEIGHT`, `THUMBHEIGHT`, `MAXPREVIEWS`, `IMAGE_JOBS`, `IMAGEMAGICK_TIMEOUT`, `RANDOM_SEED`, `SHUFFLE`, `SPLASH_PAGE`, `STATS_PAGE`, `TARBALL_INCLUDE`, `TARBALL_SUFFIX`, `TAR_TIMEOUT`, `TAR_OPTS`, `SYNC_DELETE`, @@ -117,6 +117,11 @@ templates link to it. By default this is the bundled shuriken favicon; set `FAVICON` in the config or pass `--favicon PATH` to publish your own favicon file instead (it is copied in as `favicon.ico`). +The page footer links to the project source ("Site generated ... with +<URL>"). This defaults to the shuriken.sh repository; set `SOURCE_URL` in +the config or pass `--source-url URL` to point it at your own album's repository +instead. The displayed link text is the URL with its scheme removed. + Normal generation preserves reusable generated artifacts from the previous `DIST_DIR` while still rerendering HTML, random splash/background choices, animation classes, timestamps, and shuffled preview order. Existing scaled @@ -146,6 +151,7 @@ The following long options override config values: | `--dist PATH` | `DIST_DIR` | | `--template PATH` | `TEMPLATE_DIR` | | `--favicon PATH` | `FAVICON` | +| `--source-url URL` | `SOURCE_URL` | | `--title TEXT` | `TITLE` | | `--height VALUE` | `HEIGHT` | | `--thumbheight VALUE` | `THUMBHEIGHT` | diff --git a/bin/shuriken b/bin/shuriken index c251336..e6ac7b2 100755 --- a/bin/shuriken +++ b/bin/shuriken @@ -10,7 +10,7 @@ if (( BASH_VERSINFO[0] < 5 \ exit 1 fi -declare -r VERSION='0.8.0' +declare -r VERSION='0.9.0' declare -r DEFAULTRC="${SHURIKEN_DEFAULT_RC:-/etc/default/shuriken}" declare -r PACKAGED_TEMPLATE_DIR='/usr/share/shuriken/templates/default' declare -r PACKAGED_ASSET_DIR='/usr/share/shuriken/assets' @@ -40,6 +40,7 @@ declare -ra CLI_CONFIG_OVERRIDE_TARGETS=( IMAGE_JOBS RANDOM_SEED SHUFFLE + SOURCE_URL SPLASH_PAGE STATS_PAGE SYNC_DELETE @@ -48,6 +49,7 @@ declare -ra CLI_CONFIG_OVERRIDE_TARGETS=( declare -Ar CLI_OPTION_SPEC=( [--config]='kind=value target=SHURIKEN_CLI_CONFIG_FILE argument=path' [--favicon]='kind=value config=FAVICON argument=path' + [--source-url]='kind=value config=SOURCE_URL argument=url' [--incoming]='kind=value config=INCOMING_DIR' [--dist]='kind=value config=DIST_DIR' [--template]='kind=value config=TEMPLATE_DIR' @@ -686,6 +688,7 @@ declare -ra TEMPLATE_RENDER_FIELD_SPECS=( 'render_preview_thumbs_html|context_raw|preview_thumbs|preview_thumbs|previewpage' 'render_redirect_page_html|context_html|redirect_page|redirect_page|redirect' 'render_show_header_bar|context_raw|show_header_bar|show_header_bar|header' + 'render_source_url_html|config_html|SOURCE_URL||header' 'render_stats_body_html|context_raw|stats_body|stats_body|stats' 'render_stats_page_html|config_html|STATS_PAGE||header' 'render_tarball_include|tarball_include|||footer' @@ -1101,6 +1104,10 @@ prepare_template_render_var__config_html() { ORIGINAL_BASEPATH) context_value="$ORIGINAL_BASEPATH" ;; + SOURCE_URL) + # Always defaulted by apply_config_defaults (footer credit link). + context_value="${SOURCE_URL:-}" + ;; STATS_PAGE) # Always defaulted by apply_config_defaults; degrade to # "no" (link hidden) if somehow unset so the header bar @@ -4702,6 +4709,11 @@ apply_config_defaults() { ORIGINAL_BASEPATH="${ORIGINAL_BASEPATH:-}" RANDOM_SEED="${RANDOM_SEED:-}" SHUFFLE="${SHUFFLE:-no}" + # SOURCE_URL is the project/source link shown in the page footer ("Site + # generated ... with <SOURCE_URL>"). Defaults to the shuriken.sh repo; + # override it per site (e.g. to the album's own repo) via config or + # --source-url. The footer derives the displayed text from the URL itself. + SOURCE_URL="${SOURCE_URL:-https://codeberg.org/snonux/shuriken.sh}" SPLASH_PAGE="${SPLASH_PAGE:-yes}" STATS_PAGE="${STATS_PAGE:-yes}" SYNC_DELETE="${SYNC_DELETE:-yes}" @@ -4747,6 +4759,7 @@ print_config() { print_shell_assignment DIST_DIR "$DIST_DIR" print_shell_assignment TEMPLATE_DIR "$TEMPLATE_DIR" print_shell_assignment FAVICON "$FAVICON" + print_shell_assignment SOURCE_URL "$SOURCE_URL" print_shell_assignment TITLE "$TITLE" print_shell_assignment HEIGHT "$HEIGHT" print_shell_assignment THUMBHEIGHT "$THUMBHEIGHT" @@ -5716,6 +5729,7 @@ log_configured_action() { log_verbose "Effective output directory: ${DIST_DIR:-}" log_verbose "Effective template directory: ${TEMPLATE_DIR:-}" log_verbose "Effective favicon: ${FAVICON:-(bundled default)}" + log_verbose "Effective source URL: $SOURCE_URL" log_verbose "Effective image jobs: $IMAGE_JOBS" log_verbose "Effective ImageMagick timeout: ${IMAGEMAGICK_TIMEOUT}s" log_verbose "Effective tar timeout: ${TAR_TIMEOUT}s" diff --git a/share/templates/default/header.tmpl b/share/templates/default/header.tmpl index 9a412fb..37c3559 100644 --- a/share/templates/default/header.tmpl +++ b/share/templates/default/header.tmpl @@ -299,7 +299,7 @@ END if [ "${render_show_header_bar}" = 'yes' ]; then cat <<END <div class="header animate-opacity"> - Site generated at ${render_current_date_text} with <a href="https://codeberg.org/snonux/shuriken.sh">codeberg.org/snonux/shuriken.sh</a> + Site generated at ${render_current_date_text} with <a href="${render_source_url_html}">${render_source_url_html#*://}</a> - © by Paul Buetow END diff --git a/src/lib/action.source.sh b/src/lib/action.source.sh index 918900f..36fef40 100644 --- a/src/lib/action.source.sh +++ b/src/lib/action.source.sh @@ -155,6 +155,7 @@ log_configured_action() { log_verbose "Effective output directory: ${DIST_DIR:-}" log_verbose "Effective template directory: ${TEMPLATE_DIR:-}" log_verbose "Effective favicon: ${FAVICON:-(bundled default)}" + log_verbose "Effective source URL: $SOURCE_URL" log_verbose "Effective image jobs: $IMAGE_JOBS" log_verbose "Effective ImageMagick timeout: ${IMAGEMAGICK_TIMEOUT}s" log_verbose "Effective tar timeout: ${TAR_TIMEOUT}s" diff --git a/src/lib/config.print.source.sh b/src/lib/config.print.source.sh index c5fe2b4..b886f8b 100644 --- a/src/lib/config.print.source.sh +++ b/src/lib/config.print.source.sh @@ -28,6 +28,7 @@ print_config() { print_shell_assignment DIST_DIR "$DIST_DIR" print_shell_assignment TEMPLATE_DIR "$TEMPLATE_DIR" print_shell_assignment FAVICON "$FAVICON" + print_shell_assignment SOURCE_URL "$SOURCE_URL" print_shell_assignment TITLE "$TITLE" print_shell_assignment HEIGHT "$HEIGHT" print_shell_assignment THUMBHEIGHT "$THUMBHEIGHT" diff --git a/src/lib/config.source.sh b/src/lib/config.source.sh index c13e807..c3c0731 100644 --- a/src/lib/config.source.sh +++ b/src/lib/config.source.sh @@ -39,6 +39,11 @@ apply_config_defaults() { ORIGINAL_BASEPATH="${ORIGINAL_BASEPATH:-}" RANDOM_SEED="${RANDOM_SEED:-}" SHUFFLE="${SHUFFLE:-no}" + # SOURCE_URL is the project/source link shown in the page footer ("Site + # generated ... with <SOURCE_URL>"). Defaults to the shuriken.sh repo; + # override it per site (e.g. to the album's own repo) via config or + # --source-url. The footer derives the displayed text from the URL itself. + SOURCE_URL="${SOURCE_URL:-https://codeberg.org/snonux/shuriken.sh}" SPLASH_PAGE="${SPLASH_PAGE:-yes}" STATS_PAGE="${STATS_PAGE:-yes}" SYNC_DELETE="${SYNC_DELETE:-yes}" diff --git a/src/lib/template.source.sh b/src/lib/template.source.sh index b5d3ad4..398e17d 100644 --- a/src/lib/template.source.sh +++ b/src/lib/template.source.sh @@ -190,6 +190,7 @@ declare -ra TEMPLATE_RENDER_FIELD_SPECS=( 'render_preview_thumbs_html|context_raw|preview_thumbs|preview_thumbs|previewpage' 'render_redirect_page_html|context_html|redirect_page|redirect_page|redirect' 'render_show_header_bar|context_raw|show_header_bar|show_header_bar|header' + 'render_source_url_html|config_html|SOURCE_URL||header' 'render_stats_body_html|context_raw|stats_body|stats_body|stats' 'render_stats_page_html|config_html|STATS_PAGE||header' 'render_tarball_include|tarball_include|||footer' @@ -605,6 +606,10 @@ prepare_template_render_var__config_html() { ORIGINAL_BASEPATH) context_value="$ORIGINAL_BASEPATH" ;; + SOURCE_URL) + # Always defaulted by apply_config_defaults (footer credit link). + context_value="${SOURCE_URL:-}" + ;; STATS_PAGE) # Always defaulted by apply_config_defaults; degrade to # "no" (link hidden) if somehow unset so the header bar diff --git a/src/shuriken.default.conf b/src/shuriken.default.conf index d71ef8e..38d070e 100644 --- a/src/shuriken.default.conf +++ b/src/shuriken.default.conf @@ -32,6 +32,12 @@ TEMPLATE_DIR=/usr/share/shuriken/templates/default # shuriken favicon. Can also be set with --favicon PATH. #FAVICON=$(pwd)/my-favicon.ico +# Source/project link shown in the page footer ("Site generated ... with <URL>"). +# Defaults to the shuriken.sh repository; point it at your own album's repo if you +# like. The displayed text is the URL without its scheme. Can also be set with +# --source-url URL. +#SOURCE_URL=https://codeberg.org/snonux/shuriken.sh + # Includes a .tar of the incoming dir in the dist, can be yes or no TARBALL_INCLUDE=yes TARBALL_SUFFIX=.tar diff --git a/src/shuriken.sh b/src/shuriken.sh index 75f79cb..de53d56 100755 --- a/src/shuriken.sh +++ b/src/shuriken.sh @@ -40,6 +40,7 @@ declare -ra CLI_CONFIG_OVERRIDE_TARGETS=( IMAGE_JOBS RANDOM_SEED SHUFFLE + SOURCE_URL SPLASH_PAGE STATS_PAGE SYNC_DELETE @@ -48,6 +49,7 @@ declare -ra CLI_CONFIG_OVERRIDE_TARGETS=( declare -Ar CLI_OPTION_SPEC=( [--config]='kind=value target=SHURIKEN_CLI_CONFIG_FILE argument=path' [--favicon]='kind=value config=FAVICON argument=path' + [--source-url]='kind=value config=SOURCE_URL argument=url' [--incoming]='kind=value config=INCOMING_DIR' [--dist]='kind=value config=DIST_DIR' [--template]='kind=value config=TEMPLATE_DIR' diff --git a/tests/cli.sh b/tests/cli.sh index 5ac6561..adbfcf5 100755 --- a/tests/cli.sh +++ b/tests/cli.sh @@ -523,6 +523,49 @@ test_generate_cli_overrides_config_values() { test::teardown } +# SOURCE_URL controls the footer "Site generated ... with <link>". The href uses +# the configured URL verbatim and the displayed text is that URL without its +# scheme, so a custom SOURCE_URL replaces the default shuriken.sh credit link. +test_generate_source_url_override_sets_footer_link() { + local config_file + local fake_bin + local page_html + + test::setup + fake_bin="$TEST_TMPDIR/bin" + config_file="$TEST_TMPDIR/shuriken.conf" + + test::install_fake_imagemagick "$fake_bin" + PATH="$fake_bin:$PATH" \ + test::generate_fixture_images "$TEST_TMPDIR/url-incoming" + + { + printf 'TITLE=%q\n' 'URL test' + printf 'THUMBHEIGHT=10\n' + printf 'HEIGHT=20\n' + printf 'MAXPREVIEWS=40\n' + printf 'INCOMING_DIR=%q/url-incoming\n' "$TEST_TMPDIR" + printf 'DIST_DIR=%q/url-dist\n' "$TEST_TMPDIR" + printf 'TEMPLATE_DIR=%q/share/templates/default\n' "$TEST_REPO_ROOT" + printf 'SOURCE_URL=https://codeberg.org/snonux/irregular.ninja\n' + printf 'TARBALL_INCLUDE=no\n' + } > "$config_file" + + ( + cd "$TEST_TMPDIR" + PATH="$fake_bin:$PATH" "$TEST_SHURIKEN" --generate --config "$config_file" + ) + + page_html=$(<"$TEST_TMPDIR/url-dist/page-1.html") + test::assert_contains \ + 'href="https://codeberg.org/snonux/irregular.ninja"' "$page_html" + test::assert_contains 'codeberg.org/snonux/irregular.ninja</a>' "$page_html" + # The default credit link must be gone once SOURCE_URL is overridden. + test::assert_not_contains 'codeberg.org/snonux/shuriken.sh' "$page_html" + + test::teardown +} + test_generate_height_bounds_photo_height_without_upscaling() { local config_file local -a create_command=() @@ -1364,6 +1407,7 @@ INCOMING_DIR=$TEST_TMPDIR/incoming DIST_DIR=$TEST_TMPDIR/dist TEMPLATE_DIR=$TEST_REPO_ROOT/share/templates/default FAVICON='' +SOURCE_URL=https://codeberg.org/snonux/shuriken.sh TITLE=A\\ simple\\ Shuriken HEIGHT=1200 THUMBHEIGHT=300 @@ -1412,6 +1456,7 @@ INCOMING_DIR=$TEST_TMPDIR/incoming DIST_DIR=$TEST_TMPDIR/dist TEMPLATE_DIR=$TEST_REPO_ROOT/share/templates/default FAVICON='' +SOURCE_URL=https://codeberg.org/snonux/shuriken.sh TITLE=Minimal\\ defaults HEIGHT='' THUMBHEIGHT=30 @@ -1553,6 +1598,7 @@ INCOMING_DIR=$TEST_TMPDIR/custom-incoming DIST_DIR=$TEST_TMPDIR/custom-dist TEMPLATE_DIR=$TEST_REPO_ROOT/share/templates/default FAVICON='' +SOURCE_URL=https://codeberg.org/snonux/shuriken.sh TITLE=Selected\\ config HEIGHT=120 THUMBHEIGHT=30 @@ -1596,6 +1642,7 @@ INCOMING_DIR=$TEST_TMPDIR/incoming DIST_DIR=$TEST_TMPDIR/dist TEMPLATE_DIR=$TEST_REPO_ROOT/share/templates/default FAVICON='' +SOURCE_URL=https://codeberg.org/snonux/shuriken.sh TITLE=Current\\ directory\\ config HEIGHT=120 THUMBHEIGHT=30 @@ -1664,6 +1711,7 @@ INCOMING_DIR=$TEST_TMPDIR/cli-incoming DIST_DIR=$dist_dir TEMPLATE_DIR=$TEST_TMPDIR/cli-template FAVICON='' +SOURCE_URL=https://codeberg.org/snonux/shuriken.sh TITLE=CLI\\ title HEIGHT=456 THUMBHEIGHT=45 @@ -4180,6 +4228,7 @@ BASH render_height_html \ render_html_dir_html \ render_show_header_bar \ + render_source_url_html \ render_stats_page_html \ render_thumbheight_html \ render_title_html | sort | paste -sd ' ' -) @@ -6311,6 +6360,9 @@ main() { '--generate CLI options override config' \ test_generate_cli_overrides_config_values test::run_case \ + '--generate SOURCE_URL override sets footer link' \ + test_generate_source_url_override_sets_footer_link + test::run_case \ '--generate HEIGHT bounds photo height without upscaling' \ test_generate_height_bounds_photo_height_without_upscaling test::run_case \ |
