summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xbin/shuriken32
-rw-r--r--src/lib/album-metadata.source.sh9
-rw-r--r--src/lib/metadata-cache.source.sh5
-rw-r--r--src/lib/stats-filter-album.source.sh5
-rw-r--r--src/lib/stats-render.source.sh7
-rw-r--r--src/lib/template.source.sh6
-rwxr-xr-xsrc/shuriken.sh10
-rwxr-xr-xtests/cli.sh56
8 files changed, 122 insertions, 8 deletions
diff --git a/bin/shuriken b/bin/shuriken
index b5d8839..cc8cac2 100755
--- a/bin/shuriken
+++ b/bin/shuriken
@@ -1290,7 +1290,11 @@ prepare_template_render_var__config_html() {
context_value="${THUMBHEIGHT:-}"
;;
TITLE)
- context_value="$TITLE"
+ # Always defaulted by apply_config_defaults; degrade to empty if
+ # somehow unset, matching the other config cases above. The :-
+ # default also silences SC2153 (a lowercase "title" local in another
+ # --check-sourced module makes shellcheck suspect a misspelling).
+ context_value="${TITLE:-}"
;;
*)
config_error "unknown template render config $source_name"
@@ -2190,7 +2194,10 @@ photo_exif_values_to() {
# shellcheck disable=SC2034
output_ref["${BASH_REMATCH[1]}"]="${BASH_REMATCH[2]}"
elif [[ "$line" =~ ^[[:space:]]*Geometry:[[:space:]]*(.*)$ ]]; then
- # shellcheck disable=SC2034
+ # __geometry is a literal array key, not a variable; --check-sourced
+ # nameref aliasing across modules misreads it (SC2154). SC2034 covers
+ # the caller-owned array write.
+ # shellcheck disable=SC2034,SC2154
output_ref[__geometry]="${BASH_REMATCH[1]}"
fi
done
@@ -2336,15 +2343,22 @@ photo_exif_details_html() {
printf '</table>\n'
}
+# output_ref is a string nameref here. Other modules (e.g.
+# metadata-cache.source.sh) reuse the name "output_ref" as an associative array,
+# so --check-sourced cross-file nameref aliasing misreports each string write as
+# an array assignment (SC2178). Both writes below are correct string nameref
+# assignments, so SC2178 is suppressed at each one.
_first_exif_value_to() {
+ # shellcheck disable=SC2178
local -n output_ref="$1"; shift
local -n exif_ref="$1"; shift
local key
+ # shellcheck disable=SC2178
output_ref=''
for key in "$@"; do
if [ -n "${exif_ref[$key]:-}" ]; then
- # shellcheck disable=SC2034
+ # shellcheck disable=SC2034,SC2178
output_ref="${exif_ref[$key]}"
return
fi
@@ -4725,7 +4739,7 @@ _stats_max_count() {
local -i max=0
for key in "${!counts_ref[@]}"; do
- if (( counts_ref[$key] > max )); then
+ if (( counts_ref[key] > max )); then
max=${counts_ref[$key]}
fi
done
@@ -5034,10 +5048,15 @@ _stats_random_background() {
# namespace is unchanged so selection is identical to the former inline code.
_stats_pick_background() {
local -r context="$1"; shift
+ # photos is a newline-joined string of photo paths, not an array. Other
+ # modules reuse the name "photos" as an array, so --check-sourced nameref
+ # aliasing misreports SC2178/SC2128; both are false positives here.
+ # shellcheck disable=SC2178
local -r photos="$1"; shift
local -a list=()
local photo
+ # shellcheck disable=SC2128
while IFS= read -r photo; do
[ -n "$photo" ] && list+=("$photo")
done <<< "$photos"
@@ -5126,11 +5145,16 @@ declare -gr STATS_FILTER_BACKHREF='../..'
# <div class="thumbs-grid"> container the main pages use.
_stats_build_filter_thumbs() {
local -r backhref_html="$1"; shift
+ # photos is a newline-joined string of photo paths, not an array. Other
+ # modules reuse the name "photos" as an array, so --check-sourced nameref
+ # aliasing misreports SC2178/SC2128; both are false positives here.
+ # shellcheck disable=SC2178
local -r photos="$1"; shift
local -a photo_list=()
local photo
local thumbs=''
+ # shellcheck disable=SC2128
while IFS= read -r photo; do
[ -n "$photo" ] && photo_list+=("$photo")
done <<< "$photos"
diff --git a/src/lib/album-metadata.source.sh b/src/lib/album-metadata.source.sh
index b1bed7a..cb3f2ee 100644
--- a/src/lib/album-metadata.source.sh
+++ b/src/lib/album-metadata.source.sh
@@ -60,15 +60,22 @@ photo_exif_details_html() {
printf '</table>\n'
}
+# output_ref is a string nameref here. Other modules (e.g.
+# metadata-cache.source.sh) reuse the name "output_ref" as an associative array,
+# so --check-sourced cross-file nameref aliasing misreports each string write as
+# an array assignment (SC2178). Both writes below are correct string nameref
+# assignments, so SC2178 is suppressed at each one.
_first_exif_value_to() {
+ # shellcheck disable=SC2178
local -n output_ref="$1"; shift
local -n exif_ref="$1"; shift
local key
+ # shellcheck disable=SC2178
output_ref=''
for key in "$@"; do
if [ -n "${exif_ref[$key]:-}" ]; then
- # shellcheck disable=SC2034
+ # shellcheck disable=SC2034,SC2178
output_ref="${exif_ref[$key]}"
return
fi
diff --git a/src/lib/metadata-cache.source.sh b/src/lib/metadata-cache.source.sh
index 7c6d2e3..aa580b6 100644
--- a/src/lib/metadata-cache.source.sh
+++ b/src/lib/metadata-cache.source.sh
@@ -135,7 +135,10 @@ photo_exif_values_to() {
# shellcheck disable=SC2034
output_ref["${BASH_REMATCH[1]}"]="${BASH_REMATCH[2]}"
elif [[ "$line" =~ ^[[:space:]]*Geometry:[[:space:]]*(.*)$ ]]; then
- # shellcheck disable=SC2034
+ # __geometry is a literal array key, not a variable; --check-sourced
+ # nameref aliasing across modules misreads it (SC2154). SC2034 covers
+ # the caller-owned array write.
+ # shellcheck disable=SC2034,SC2154
output_ref[__geometry]="${BASH_REMATCH[1]}"
fi
done
diff --git a/src/lib/stats-filter-album.source.sh b/src/lib/stats-filter-album.source.sh
index cc4cf2e..562a72e 100644
--- a/src/lib/stats-filter-album.source.sh
+++ b/src/lib/stats-filter-album.source.sh
@@ -52,11 +52,16 @@ declare -gr STATS_FILTER_BACKHREF='../..'
# <div class="thumbs-grid"> container the main pages use.
_stats_build_filter_thumbs() {
local -r backhref_html="$1"; shift
+ # photos is a newline-joined string of photo paths, not an array. Other
+ # modules reuse the name "photos" as an array, so --check-sourced nameref
+ # aliasing misreports SC2178/SC2128; both are false positives here.
+ # shellcheck disable=SC2178
local -r photos="$1"; shift
local -a photo_list=()
local photo
local thumbs=''
+ # shellcheck disable=SC2128
while IFS= read -r photo; do
[ -n "$photo" ] && photo_list+=("$photo")
done <<< "$photos"
diff --git a/src/lib/stats-render.source.sh b/src/lib/stats-render.source.sh
index b9bc067..1050ef2 100644
--- a/src/lib/stats-render.source.sh
+++ b/src/lib/stats-render.source.sh
@@ -27,7 +27,7 @@ _stats_max_count() {
local -i max=0
for key in "${!counts_ref[@]}"; do
- if (( counts_ref[$key] > max )); then
+ if (( counts_ref[key] > max )); then
max=${counts_ref[$key]}
fi
done
@@ -336,10 +336,15 @@ _stats_random_background() {
# namespace is unchanged so selection is identical to the former inline code.
_stats_pick_background() {
local -r context="$1"; shift
+ # photos is a newline-joined string of photo paths, not an array. Other
+ # modules reuse the name "photos" as an array, so --check-sourced nameref
+ # aliasing misreports SC2178/SC2128; both are false positives here.
+ # shellcheck disable=SC2178
local -r photos="$1"; shift
local -a list=()
local photo
+ # shellcheck disable=SC2128
while IFS= read -r photo; do
[ -n "$photo" ] && list+=("$photo")
done <<< "$photos"
diff --git a/src/lib/template.source.sh b/src/lib/template.source.sh
index 6201647..cd38b3d 100644
--- a/src/lib/template.source.sh
+++ b/src/lib/template.source.sh
@@ -688,7 +688,11 @@ prepare_template_render_var__config_html() {
context_value="${THUMBHEIGHT:-}"
;;
TITLE)
- context_value="$TITLE"
+ # Always defaulted by apply_config_defaults; degrade to empty if
+ # somehow unset, matching the other config cases above. The :-
+ # default also silences SC2153 (a lowercase "title" local in another
+ # --check-sourced module makes shellcheck suspect a misspelling).
+ context_value="${TITLE:-}"
;;
*)
config_error "unknown template render config $source_name"
diff --git a/src/shuriken.sh b/src/shuriken.sh
index d9f7d1b..2b8cf9b 100755
--- a/src/shuriken.sh
+++ b/src/shuriken.sh
@@ -115,6 +115,10 @@ source "$SHURIKEN_SOURCE_DIR/lib/image.source.sh"
source "$SHURIKEN_SOURCE_DIR/lib/random.source.sh"
# shellcheck source=src/lib/photo-list.source.sh
source "$SHURIKEN_SOURCE_DIR/lib/photo-list.source.sh"
+# shellcheck source=src/lib/metadata-label.source.sh
+source "$SHURIKEN_SOURCE_DIR/lib/metadata-label.source.sh"
+# shellcheck source=src/lib/metadata-cache.source.sh
+source "$SHURIKEN_SOURCE_DIR/lib/metadata-cache.source.sh"
# shellcheck source=src/lib/image-pipeline.source.sh
source "$SHURIKEN_SOURCE_DIR/lib/image-pipeline.source.sh"
# shellcheck source=src/lib/album-metadata.source.sh
@@ -133,6 +137,12 @@ source "$SHURIKEN_SOURCE_DIR/lib/album-photo-select.source.sh"
source "$SHURIKEN_SOURCE_DIR/lib/album-render.source.sh"
# shellcheck source=src/lib/album.source.sh
source "$SHURIKEN_SOURCE_DIR/lib/album.source.sh"
+# shellcheck source=src/lib/stats-aggregate.source.sh
+source "$SHURIKEN_SOURCE_DIR/lib/stats-aggregate.source.sh"
+# shellcheck source=src/lib/stats-render.source.sh
+source "$SHURIKEN_SOURCE_DIR/lib/stats-render.source.sh"
+# shellcheck source=src/lib/stats-filter-album.source.sh
+source "$SHURIKEN_SOURCE_DIR/lib/stats-filter-album.source.sh"
# shellcheck source=src/lib/config.source.sh
source "$SHURIKEN_SOURCE_DIR/lib/config.source.sh"
# shellcheck source=src/lib/config.print.source.sh
diff --git a/tests/cli.sh b/tests/cli.sh
index 3ce8939..28aacbb 100755
--- a/tests/cli.sh
+++ b/tests/cli.sh
@@ -6701,6 +6701,59 @@ test_camera_label_from_make_model() {
_assert_camera_label 'canon Canon EOS 5D' 'canon' 'Canon EOS 5D'
}
+# Guards against drift between the hand-maintained 'source ...' lines inside the
+# SHURIKEN_LIB_SOURCES_BEGIN/END marker block of src/shuriken.sh and the
+# authoritative Justfile LIB_SOURCES list. 'just build' regenerates bin/shuriken
+# by replacing that marker block with LIB_SOURCES, so the installed bin/ never
+# reveals divergence; only direct execution of src/shuriken.sh sources the
+# hand-maintained list. This test asserts both lists carry the same module names
+# in the same order, so a missing or misordered source line fails CI.
+test_lib_sources_match_justfile_lib_sources() {
+ local src_modules justfile_modules
+
+ # Module basenames from the marker block in src/shuriken.sh, in file order.
+ src_modules=$(
+ awk '
+ /# SHURIKEN_LIB_SOURCES_BEGIN/ { inside = 1; next }
+ /# SHURIKEN_LIB_SOURCES_END/ { inside = 0 }
+ inside && /^source / {
+ line = $0
+ sub(/.*\/lib\//, "", line)
+ sub(/".*/, "", line)
+ print line
+ }
+ ' "$TEST_REPO_ROOT/src/shuriken.sh"
+ )
+
+ # Module basenames from the Justfile LIB_SOURCES assignment, in list order.
+ justfile_modules=$(
+ awk '
+ /^LIB_SOURCES :=/ {
+ n = split($0, parts, /"/)
+ list = parts[2]
+ m = split(list, words, /[ \t]+/)
+ for (i = 1; i <= m; i++) {
+ word = words[i]
+ if (word == "") continue
+ sub(/.*\/lib\//, "", word)
+ print word
+ }
+ exit
+ }
+ ' "$TEST_REPO_ROOT/Justfile"
+ )
+
+ if [ "$src_modules" != "$justfile_modules" ]; then
+ echo 'FAIL: src/shuriken.sh lib source list diverged from Justfile LIB_SOURCES' >&2
+ echo '--- src/shuriken.sh marker block ---' >&2
+ echo "$src_modules" >&2
+ echo '--- Justfile LIB_SOURCES ---' >&2
+ echo "$justfile_modules" >&2
+ diff <(echo "$src_modules") <(echo "$justfile_modules") >&2 || true
+ exit 1
+ fi
+}
+
main() {
trap test::teardown EXIT
@@ -7119,6 +7172,9 @@ main() {
test::run_case \
'GNU-tool guard rejects non-GNU stat' \
test_gnu_tool_guard_rejects_non_gnu_stat
+ test::run_case \
+ 'src/shuriken.sh lib source list matches Justfile LIB_SOURCES' \
+ test_lib_sources_match_justfile_lib_sources
}
main "$@"