| Age | Commit message (Collapse) | Author |
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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.
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
|
|
|
|
|