| Age | Commit message (Collapse) | Author |
|
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
|
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
|
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
|
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
|
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>
|
|
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>
|
|
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
|
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
|
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).
|
|
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|