#!/usr/bin/env bash # List the files that go into the installed plugin: everything git tracks, # minus the patterns in .distignore. # # Deliberately the only answer to "what ships". The release zip and the # hygiene checks both read it, so a file cannot be excluded from one and # included in the other — which is the version of this bug that ends with # internal notes readable over HTTP on a live shop. set -euo pipefail cd "$(dirname "$0")/.." [ -f .distignore ] || { echo ".distignore is missing — the zip would contain git files and internal notes." >&2; exit 1; } patterns=() while IFS= read -r line; do line="${line%%#*}" line="$(printf '%s' "$line" | sed -E 's/^[[:space:]]+|[[:space:]]+$//g')" [ -n "$line" ] && patterns+=("${line%/}") done < .distignore # -z, not plain `git ls-files`: git QUOTES any path containing a non-ASCII # byte, so "TESTMILJØ.md" comes out as the literal 14-character string # "TESTMILJ\303\230.md". That form matches no pattern in .distignore, so the # file is kept — an internal document walking straight into the release zip # with nothing said. (-z also covers paths with spaces.) Found in a sibling # plugin that has exactly such a filename; this repo has none today, which is # precisely why it would have sat here until someone added one. git ls-files -z | while IFS= read -r -d '' file; do keep=1 for p in "${patterns[@]}"; do # A bare name excludes the file or directory wherever it appears, which is # how .distignore is read everywhere else. Anchor with a leading / to mean # the repo root only. case "$p" in /*) case "$file" in "${p#/}"|"${p#/}"/*) keep=0 ;; esac ;; *) case "$file" in $p|$p/*|*/$p|*/$p/*) keep=0 ;; esac ;; esac [ "$keep" = 0 ] && break done [ "$keep" = 1 ] && printf '%s\n' "$file" done