summaryrefslogtreecommitdiff
path: root/src/lib/config.source.sh
AgeCommit message (Collapse)Author
2026-06-28mr0: add CONFIG_SPECS registry; derive defaults, CLI targets, print, validationPaul Buetow
Introduce src/lib/config.spec.source.sh: CONFIG_SPECS, a single '|'-delimited config-field registry (name|default|has_default|cli_overridable|validation| print_kind), using the same spec idiom as ACTION_SPECS / TEMPLATE_RENDER_FIELD_SPECS. This replaces the parallel, hand-maintained config-knowledge lists that caused the TARBALL_INCLUDE default-drift bug (fixed in 7r0). Derived consumers (behaviour byte-identical): - apply_config_defaults: loops the registry applying VAR="${VAR:-default}" for has_default=yes scalars; arrays keep their declare -p guards. - CLI_CONFIG_OVERRIDE_TARGETS: built from cli_overridable=yes (verified to match CLI_OPTION_SPEC's config= targets exactly). - print_config: emits in registry order dispatching on print_kind. - validate_common_config: required set + per-field rule come from the registry via config_spec_validation + validate_config_field_required/_kind; two-phase order and historical reporting order preserved. log_configured_action and the dry-run plan are not yet converted (bespoke prose / intermixed computed values). shellcheck: TARBALL_SUFFIX lost its visible literal assignment, annotated at the archive use site. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-28Centralize DIST_DIR-derived paths via working_dir/exif_cache_dir helpersPaul Buetow
The EXIF cache dir ($(dirname "$DIST_DIR")/cache/exif) was recomputed inline, byte for byte, in both cached_photo_identify_output (read/write) and clear_exif_cache (--force/--clean removal). The plain parent of DIST_DIR (dirname "$DIST_DIR") was likewise recomputed in metadata-cache and in action.source.sh's staging-artifact cleanup. Extract two helpers computed once from DIST_DIR: - working_dir() in config.source.sh (next to existing_parent_dir, the other DIST_DIR-parent resolver): plain `dirname "$DIST_DIR"`. - exif_cache_dir() in metadata-cache.source.sh (owns the EXIF cache): `working_dir()/cache/exif`. Route cached_photo_identify_output, clear_exif_cache, and clean_generation_staging_artifacts through them so the cache reader and the cleaner can never drift to different directories. Paths are byte-identical to the prior inline code (dirname semantics, cache/exif suffix, trailing-slash and relative/absolute handling all preserved). Stale "recompute the cache dir" comments removed; helpers document the path once. Add a unit test asserting the helpers agree and resolve beside dist for several DIST_DIR shapes. Broader DIST_DIR parameterization of leaf pipeline helpers was intentionally left out of scope (only the duplicated path computation is centralized here). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-27qr0: timeout + per-destination isolation for rsync sync_distPaul Buetow
Wrap each rsync in sync_dist in run_with_timeout (new SYNC_TIMEOUT config, default 300s) so a hung or unreachable mirror cannot block the whole sync, matching every other external call. Make destinations isolated: under set -euo pipefail a single failing destination used to abort the loop and silently skip the rest. Now each destination runs under a localized set +e (the project's refresh_splash idiom), results are collected per destination, a clear pass/fail summary is logged, and sync returns non-zero if any destination failed while still attempting all of them. SYNC_TIMEOUT is plumbed like TAR_TIMEOUT: shuriken.default.conf, apply_config_defaults, print_config, verbose config log, and positive-integer validation in both validate_config (generate path) and validate_sync_config (sync path). No CLI flag, matching TAR_TIMEOUT. Tests: a sync where one destination fails still attempts the others and exits non-zero with the summary; SYNC_TIMEOUT=0 is rejected as a positive integer. Adds install_rsync_spy_failing_one helper and updates the print_config expected blocks. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-24Fix TARBALL_INCLUDE config default drift (7r0, scoped down)Paul Buetow
apply_config_defaults fell back to TARBALL_INCLUDE=no while the user-facing src/shuriken.default.conf documents (and --init writes) TARBALL_INCLUDE=yes. The two disagreed, so an album generated from a config that omitted the key silently dropped the tarball despite the documented default saying otherwise. 'yes' is the authoritative default: the original definition was `declare -r TARBALL_INCLUDE=yes` (tarball inclusion was on from the start); the ':-no' fallback was introduced later during a refactor and drifted from the documented intent. Align apply_config_defaults to ':-yes' and add a comment explaining the invariant and the history. Tests: add test_tarball_include_default_matches_init_config asserting the effective default agrees between a fresh --init config and apply_config_defaults (and is 'yes'); update the omitted-runtime-defaults --print-config expectation to the corrected 'yes'. bin/shuriken regenerated via just build. This is the scoped-down drift fix only. The full CONFIG_SPECS registry plus cfg_get/SHURIKEN_CFG access-layer rewrite proposed in 7r0 remains DEFERRED. just test, just shellcheck, just check-generated and git diff --check all pass. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22Add large 2x2 feature tiles and a CSS-grid overviewPaul Buetow
Allow a single photo to be blown up into a large "feature" tile that spans a 2x2 block of the album overview, controlled by a new THUMB_FEATURE_PERCENT (0-100, default 10; 0 disables). Each tile rolls for a feature first, then for a subdivision, otherwise stays a normal square. To pack mixed-size tiles (normal 1x1, subdivided 1x1, feature 2x2) without gaps, the overview is now a real CSS grid with grid-auto-flow: dense, so smaller tiles backfill the holes a 2x2 feature would leave. Tile spacing moved from per-image padding to the grid gap. Feature tiles reuse the img.thumb class and its dramatic hover. THUMB_FEATURE_PERCENT is wired through the same layers as THUMB_SUBDIVIDE_PERCENT: config defaults, 0..100 validation, --print-config, the --feature CLI flag, the usage text, and the shuriken.json / --dry-run metadata, with docs and tests updated. Generated HTML and CSS pass the W3C Nu HTML checker and CSS validator. Setting both percentages to 0 reproduces the previous all-1x1 grid. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22Add dynamic subdivided thumbnail tilesPaul Buetow
Make the album preview grid livelier: with a configurable probability (THUMB_SUBDIVIDE_PERCENT, default 30%) a square thumbnail tile is subdivided into several smaller thumbnails packed into the same square footprint, chosen at random from: - quad: 2x2 squares (4 photos) - two-wide: two stacked full-width strips (2 photos) - squares+wide: two squares plus one full-width strip, strip on the top or the bottom (3 photos) Each sub-thumbnail stays its own clickable photo with its own view page; subdivision only groups consecutive photos visually, so preview numbering and the view/details/redirect pages are unchanged. No new images are generated (CSS object-fit crops the existing aspect-correct thumbs into squares or wide strips). Sub-thumbnails get the same random entry animation and the same dramatic hover (flip/scale/rotate/filter) as full thumbs. The layout choice reuses the seeded random_index, so builds stay reproducible under RANDOM_SEED. THUMB_SUBDIVIDE_PERCENT=0 reproduces the previous output byte-for-byte. The new option is wired through the config defaults, validation (0..100), --print-config, the --subdivide CLI flag, the usage text, and the shuriken.json / --dry-run metadata, with docs and tests updated. Generated HTML and CSS pass the W3C Nu HTML checker and CSS validator. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19docs: split README into quick-start + reference pages under docs/Paul Buetow
Trim README.md to a quick-start guide (install, init, generate, sync, clean) with a main-flags table and feature-toggle summary, and move the detailed reference material into focused pages under docs/: installation, usage, configuration, generation, publishing, templates. Correctness fixes carried over during the split: - The 'Site generated ... with <URL>' source link lives in the page header bar (header.tmpl), not the footer (footer.tmpl only renders the tarball download). Fixed in docs and the SOURCE_URL code comment. - --sync is a config-backed action and accepts --config PATH / reads ./shuriken.conf; the --config action list now includes it. - --refresh-splash also re-copies the site favicon; documented. - State the Bash 5.1 requirement (enforced by the script) in the docs. - docs/stats-exif-audit.md: the EXIF cache moved to metadata-cache.source.sh and the native-field parser extension was implemented; add a status note and fix the stale module path. bin/shuriken regenerated from the config.source.sh comment change.
2026-06-18Default stats generation to off; release 0.10.00.10.0Paul Buetow
The EXIF stats site (stats/ overview plus per-camera and filter mini-albums) was generated by default. Flip the STATS_PAGE default to "no" so a plain album stays lean; enable it explicitly with STATS_PAGE=yes or --stats. Updated the bundled default config, the README ("off by default"), and the tests that relied on the old default (the stats-rendering and dry-run-override tests now pass --stats / set STATS_PAGE=yes; the print-config expectations now show STATS_PAGE=no). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-17Add configurable SOURCE_URL footer link; release 0.9.00.9.0Paul Buetow
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>
2026-06-15Make the favicon configurable via FAVICON config / --favicon flagPaul Buetow
The generated pages link a favicon.ico that was always the bundled shuriken favicon (copy_site_favicon hard-copied share/shuriken/assets/favicon.ico). Add a FAVICON config variable and a --favicon PATH CLI flag: when set, that file is published as favicon.ico instead of the bundled default; when empty, the bundled favicon is used as before. Plumbed through apply_config_defaults, CLI_OPTION_SPEC + override allowlist, usage, print_config, the action config list and effective-setting log, and validated (a non-empty FAVICON must be a readable file) before generation. shuriken.default.conf and the README document it; a test covers a custom favicon, its appearance in --print-config, and rejection of a missing file. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-14rm0 wire stats feature into generate with STATS_PAGE togglePaul Buetow
Final integration of the stats-site feature: - Add STATS_PAGE config (default yes) mirroring SPLASH_PAGE through every layer: shuriken.default.conf, apply_config_defaults, CLI_OPTION_SPEC (--stats/--no-stats), the CLI_CONFIG_OVERRIDE_TARGETS allowlist (without which the flag was silently ignored), usage text, yes/no validation, print_config, the action config list + effective-setting log, the generation metadata, and the dry-run plan. - generate() now calls a gated generate_stats_pages helper after the album pages (and before archiving, so the stats/camera pages are tarballed): collect_photo_exif_stats + render_stats_page . . + render_camera_pages . . - Emit "stats_page" in shuriken.json next to "splash_page". - Gate the header Stats nav link behind STATS_PAGE via a new render_stats_page_html config_html field, so it is hidden (no 404) when stats are disabled. - Document STATS_PAGE and --stats/--no-stats in the README. - Tests: full --generate produces stats.html + camera-<slug>.html + the nav link and stats_page=true; --no-stats suppresses all three and sets stats_page=false; print-config and metadata expectations updated. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-11Split config module concerns for task 9m0Paul Buetow
2026-06-11Rename photoalbum to shurikenPaul Buetow
2026-06-11Split photoalbum source into lib modulesPaul Buetow