summaryrefslogtreecommitdiff
path: root/Justfile
AgeCommit message (Collapse)Author
2026-07-18release 0.13.0HEAD0.13.0masterPaul Buetow
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-06-28release 0.12.40.12.4Paul Buetow
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-28release 0.12.30.12.3Paul Buetow
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-28release 0.12.20.12.2Paul Buetow
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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-28Extract destructive --clean path guard into config.clean-guard.source.shPaul Buetow
Move the safety-critical rm -rf guard (resolve_dist_dir_path and validate_clean_dist_dir, including the dangerous-path blocklist) out of config.validate.source.sh into a dedicated module so the policy that gates an unconditional rm -rf lives in one isolated place with its own test surface. This is a pure move refactor: the guard logic, the forbidden list, and the error messages are byte-identical. Register the new module in both LIB_SOURCES lists (Justfile and the src/shuriken.sh marker block) at the same position, right before config.validate.source.sh, keeping the anti-drift invariant green and regenerating bin/shuriken. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-25release 0.12.10.12.1Paul Buetow
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-25release 0.12.00.12.0Paul Buetow
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-25Add runtime GNU-tool guard; document Linux-only platform supportPaul Buetow
shuriken shells out to GNU-only features of the standard Unix tools (find -printf, stat -c, cp -a, sort -R). Add require_gnu_tools in a new src/lib/compat.source.sh, sourced early and invoked from main() before any action runs. On invocation it feature-probes each tool in a throwaway temp dir; if any probe fails it prints a clear error naming the offending tool and exits 1, so non-GNU (macOS/BSD) environments fail fast instead of producing broken output. README gains a Platform compatibility section and the requirements line now mentions GNU coreutils/findutils. Tests cover the find and stat rejection paths; the shared test helper that builds a coreutils-without-imagemagick PATH now includes cp and stat (which the guard probes).
2026-06-24release 0.11.40.11.4Paul Buetow
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-24Extract shared list_photos/pick_random_photo helper (br0)Paul Buetow
Collapse the duplicated "find photos, error on empty, random_index by ctx, return one" pattern into a single photo-list.source.sh exposing list_photos <dir> and pick_random_photo <dir> <ctx>. Consumers in album-photo-select, album-render, image-pipeline and stats-render now call the shared helpers; _stats_load_background_photos keeps its caching via a cached list_photos call rather than re-listing per filter page. Per-call-site random_index ctx strings are preserved, so selection semantics are unchanged. Sourced before its consumers in LIB_SOURCES (Justfile + src/shuriken.sh); bin/shuriken regenerated. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-24Split album-render.source.sh along its four seams (ar0)Paul Buetow
album-render.source.sh bundled four concerns that change for unrelated reasons. Extract three focused siblings, leaving album-render as the page orchestrator: - album-tile-layout.source.sh tile_layout_for, build_tile_block, build_subdivided_tile - album-thumbnail-html.source.sh build_preview_thumbnail, append_preview_grid - album-photo-select.source.sh album_photo_files, album_page_records, splash_photo_files, random_splash_photo, randomphoto album-render.source.sh keeps page assembly, the per-photo view/details pages, navigation redirects, index/splash, and the job_pool_* plumbing. Every function moved whole with no body/signature change. The album_view_page_for_photo accessor and its private ALBUM_VIEW_PAGE_BY_PHOTO map stay in album-render so the stats mini-album boundary is unchanged. LIB_SOURCES (Justfile + src/shuriken.sh) sources the three new modules before album-render. Regenerated bin/shuriken. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-24Split album-metadata.source.sh into focused modules (6r0)Paul Buetow
album-metadata.source.sh aggregated six unrelated concerns. Move each along its existing seam (pure mechanical move, no logic changes): - EXIF presentation (photo_exif_details_html, tooltip helpers, the _photo_exif_values_to wrapper) stays in album-metadata.source.sh, which is now EXIF-presentation only. - File counting (count_files, count_incoming_images, count_tree_files) -> image.source.sh, which already owns incoming_image_files; count_incoming_images is a direct wrapper of it. - Tarball naming (tarball_name_plan, generated_tarball_name) -> archive.source.sh, which already owns tarball()/resolve_tar_opts. - Generation metadata + JSON (_collect_generation_metadata, _generation_metadata_json, write_generation_metadata) -> new generation-metadata.source.sh. - Dry-run (dry_run, collect_dry_run_*, print_dry_run_plan) -> new dry-run.source.sh. - clear_exif_cache -> metadata-cache.source.sh, next to the cache primitive cached_photo_identify_output. LIB_SOURCES (Justfile + src/shuriken.sh): insert generation-metadata and dry-run right after album-metadata, before album-render/album. They depend on image, archive, template and metadata-cache (all earlier or runtime-only calls), and are consumed by the album coordinator and the dry-run CLI action, which come later. bin/shuriken regenerated via just build. File-header comments updated to reflect the new homes. 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-24release 0.11.30.11.3Paul Buetow
Mobile-friendly generated album: viewport meta tag, responsive 2-column phone grid, touch-friendly menu buttons, and a missing-alt fix on stats filter view pages. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22release 0.11.20.11.2Paul Buetow
Thumbnail grid fills the full window width (no large left/right margins) and the spacing above the header / below the footer matches the inter- element gaps. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22release 0.11.10.11.1Paul Buetow
Cap the big 2x2 feature tiles at two per page (main preview pages and stats mini-album galleries). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22release 0.11.00.11.0Paul Buetow
Dynamic thumbnail tiles: subdivided tiles, 2x2 feature tiles, a CSS-grid overview, and the same effects in the stats mini-album galleries. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21Fix W3C HTML validation errors in generated pages; release 0.10.10.10.1Paul Buetow
Every shuriken-generated page failed W3C validation. Fixed across the templates and the bash thumbnail builders so all page categories (splash, gallery, photo view, details, stats overview, stats filter mini-albums and redirect stubs) validate cleanly: - Add <!DOCTYPE html>, <html lang="en"> and <meta charset="utf-8"> to the header, splash and redirect templates. - Drop the obsolete type="text/css" on <style> and border='0' on <img>. - Fix invalid CSS "margin: 2 auto" -> "margin: 2px auto". - Add required alt attributes to every <img> (splash, thumbnails, views). - Replace the obsolete name attribute on <a> thumbnail anchors with id (in album-render.source.sh and stats-filter-album.source.sh, where the markup is actually built, plus preview.tmpl for consistency). - Give redirect stubs a <title>; drop trailing slashes on void elements. Updated the affected cli.sh assertions and rebuilt bin/shuriken. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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-17pn0 decouple stats from album internalsPaul Buetow
Stats reached directly into album-module internals: the private global ALBUM_VIEW_PAGE_BY_PHOTO and the EXIF cache reader cached_photo_identify_output. Introduce a clean boundary, behaviour and generated HTML byte-identical. - Promote the EXIF identify cache primitive (cached_photo_identify_output plus its private helpers photo_cache_signature and print_cached_photo_identify_output) out of album-metadata.source.sh into a new shared src/lib/metadata-cache.source.sh, sourced before both album and stats (right after metadata-label in LIB_SOURCES). It is a low-level metadata primitive used by both consumers, so it no longer belongs to album internals. Signature/behaviour unchanged. - Add album_view_page_for_photo accessor in album-render.source.sh as the documented public API; keep ALBUM_VIEW_PAGE_BY_PHOTO as the album's private backing store. stats-filter-album.source.sh now calls the accessor instead of indexing the global, so a change to album page naming/caching stays contained in the album module. - Add test_album_stats_decoupling_boundary asserting the accessor returns the backing-store value and that the assembled bin/shuriken keeps the cache primitive in the shared module and no longer indexes the global from the stats filter section. Existing stats/album tests unchanged. Verified: 3-image fixture (STATS_PAGE=yes, fixed seed) diff -r of stashed original vs new build is byte-identical across all 47 dist files (only the inherent generated_at timestamp normalized). 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-17mn0 share camera Make+Model dedup helperPaul Buetow
The rule that joins a camera's EXIF Make + Model into one label while avoiding a duplicated manufacturer prefix (e.g. "Canon Canon EOS 5D" -> "Canon EOS 5D") was implemented independently in the album tooltip builder and the stats leaderboard tally. Extract it into a single shared helper camera_label_from_make_model in the new src/lib/metadata-label.source.sh, sourced before both callers. Both prior implementations were behavior-identical (empty model -> make, empty make -> model, exact/prefix dedup, case-sensitive), so this is a pure DRY refactor with no observable output change. Added a focused unit test covering dedup, plain concatenation and the empty-field edge cases. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-16jn0 split bootstrap.source.sh into logging/paths/startup modulesPaul Buetow
Separate the mixed concerns in bootstrap.source.sh per [SRP]: - logging.source.sh: output_is_quiet, output_is_verbose, log_info, log_verbose, log_warning (the output/logging concern). - paths.source.sh: resolve_default_rc_file, resolve_source_root, resolve_default_template_dir, resolve_default_asset_dir, template_dir_uses_default, apply_template_dir_default, init_config (install/source-root/default-dir + rc-file/template-dir resolution). - bootstrap.source.sh keeps the CLI usage text and the shared resolve_config_array parser used by the config modules. Pure code move, verified byte-identical function bodies. LIB_SOURCES now lists logging.source.sh first, then bootstrap, then paths; matching source directives added to src/shuriken.sh so --check-sourced sees the new modules. just test/shellcheck/check-generated and git diff --check all pass. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-16cn0 split stats.source.sh into aggregate/render/filter-album modulesPaul Buetow
Pure code move: split the ~1248-line stats.source.sh (SRP+SoC) into three cohesive modules, all functions and STATS_* constants/globals moved verbatim: - stats-aggregate.source.sh: EXIF parsing, bucketing, _stats_tally, reset/collect_photo_exif_stats and the STATS_* maps. - stats-render.source.sh: stats overview page (sections, bars, leaderboard, render_stats_page, _stats_build_body, _stats_filter_link, background pickers). - stats-filter-album.source.sh: per-filter mini-albums (render_filter_pages, gallery/view/thumbnail builders, _stats_enqueue_filter_album). Updated LIB_SOURCES accordingly. No logic change (verified: all 55 functions and top-level globals preserved; full suite, shellcheck, check-generated, diff all pass). The SoC point (HTML built in bash rather than templates) is left for a follow-up (nn0/qn0). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-16in0 split album.source.sh into cohesive modulesPaul Buetow
Refactor the ~1442-line album.source.sh ([SRP] violation) into three cohesive modules, leaving album.source.sh a thin coordinator. Pure code move, no behavior change -- whole functions and their doc comments moved verbatim; the assembled bin/shuriken contains the same function set. - image-pipeline.source.sh: ImageMagick derivative generation (create_photo_derivatives, create_all_photo_derivatives) and photo asset prep (prepare_generation_photo_assets). - album-metadata.source.sh: EXIF identify caching, exif tooltip/details helpers, file counts, shuriken.json metadata, EXIF cache clearing and the dry-run plan. - album-render.source.sh: preview/view/details/splash/redirect page rendering, the parallel render-job orchestration and the ALBUM_VIEW_PAGE_BY_PHOTO global. - album.source.sh: thin coordinator (generate, refresh_splash, generate_stats_pages, site-asset/archive/html-clean helpers). Add the three modules to LIB_SOURCES (Justfile) and to the SHURIKEN_LIB_SOURCES markers in src/shuriken.sh, ordered after random and before album.source.sh / stats.source.sh. just build, 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-15Release 0.8.00.8.0Paul Buetow
EXIF stats site (overview + a clickable filter mini-album per bucket under stats/, rendered in parallel), an EXIF mouse-over tooltip on the normal image view, a persistent ./cache EXIF directory, web-readable dist permissions, and a configurable favicon (FAVICON / --favicon). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-14om0 add stats aggregation modulePaul Buetow
Add src/lib/stats.source.sh implementing the aggregation layer for the stats site feature. collect_photo_exif_stats() iterates the album's incoming photos, reads each one's cached identify -verbose output via album.source.sh's cache helper, and fills global STATS_* associative arrays for the camera leaderboard, per-camera photo lists, temporal, exposure, dimension, format and enum stats. Builds exactly the v1 stat set recommended by docs/stats-exif-audit.md (rendering is left to the sibling tasks pm0/rm0/um0). Wire stats.source.sh into the Justfile LIB_SOURCES list (after album, before config) and regenerate bin/shuriken. Add unit tests exercising synthetic identify fixtures, rational/bucket boundaries, DateTimeOriginal substring parsing, missing-field tolerance, and the cached-output path. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-13Refactor helper modules for im0Paul Buetow
2026-06-13hm0 deduplicate Justfile rendererPaul Buetow
2026-06-11Split config module concerns for task 9m0Paul Buetow
2026-06-11Rename photoalbum to shurikenPaul Buetow
2026-06-11Add shuriken logo and generated faviconPaul Buetow
2026-06-11Split photoalbum source into lib modulesPaul Buetow
2026-06-05Bump version to 0.7.00.7.0Paul Buetow
2026-06-04Refine Bash practices for oi0Paul Buetow
2026-06-04Enforce photoalbum generated script drift check (5j0)Paul Buetow
2026-06-04qi0 add just install workflowPaul Buetow