mirror of
https://github.com/nyakang/nyaterm.git
synced 2026-10-03 16:00:51 +00:00
141 lines
4.3 KiB
Bash
141 lines
4.3 KiB
Bash
#!/usr/bin/env bash
|
|
#
|
|
# Vendor the bundled icon assets described by scripts/icons.manifest.
|
|
#
|
|
# The build stays offline: this script is run by hand when the manifest or a
|
|
# pinned version changes, and its output is committed. It exists so the
|
|
# provenance of every icon is reproducible and reviewable rather than folklore.
|
|
#
|
|
# bash scripts/sync-icons.sh # sync everything
|
|
# bash scripts/sync-icons.sh --check # verify the tree matches, change nothing
|
|
#
|
|
set -euo pipefail
|
|
|
|
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
cd "$ROOT_DIR"
|
|
|
|
ASSET_DIR="crates/nyaterm-app/assets"
|
|
MANIFEST="scripts/icons.manifest"
|
|
|
|
# Pinned so a re-run reproduces the committed tree.
|
|
MD_VERSION="0.14.15" # @material-design-icons/svg Apache-2.0
|
|
SI_VERSION="16.27.1" # simple-icons CC0-1.0
|
|
FA_VERSION="7.3.1" # @fortawesome/fontawesome-free CC BY 4.0
|
|
VSC_VERSION="0.0.46-24" # @vscode/codicons CC BY 4.0
|
|
RMX_VERSION="4.9.1" # remixicon Apache-2.0
|
|
|
|
CHECK_ONLY=0
|
|
[[ "${1:-}" == "--check" ]] && CHECK_ONLY=1
|
|
|
|
SCRATCH="$(mktemp -d)"
|
|
trap 'rm -rf "$SCRATCH"' EXIT
|
|
|
|
failures=0
|
|
fail() {
|
|
printf 'sync-icons: %s\n' "$*" >&2
|
|
failures=$((failures + 1))
|
|
}
|
|
|
|
require() {
|
|
command -v "$1" >/dev/null 2>&1 || {
|
|
printf 'sync-icons: %s is required\n' "$1" >&2
|
|
exit 1
|
|
}
|
|
}
|
|
require curl
|
|
require tar
|
|
|
|
# --- upstream fetch ---------------------------------------------------------
|
|
|
|
fetch_pkg() {
|
|
# $1 npm package, $2 version, $3 scratch subdir
|
|
local pkg="$1" version="$2" dest="$SCRATCH/$3"
|
|
local tarball="${pkg##*/}-$version.tgz"
|
|
[[ -d "$dest" ]] && return 0
|
|
mkdir -p "$dest"
|
|
printf 'sync-icons: fetching %s@%s\n' "$pkg" "$version" >&2
|
|
curl -fsSL "https://registry.npmjs.org/$pkg/-/$tarball" |
|
|
tar -xz -C "$dest" --strip-components=1
|
|
}
|
|
|
|
pkg_root() {
|
|
case "$1" in
|
|
md) fetch_pkg "@material-design-icons/svg" "$MD_VERSION" md; printf '%s/md' "$SCRATCH" ;;
|
|
si) fetch_pkg "simple-icons" "$SI_VERSION" si; printf '%s/si/icons' "$SCRATCH" ;;
|
|
fa) fetch_pkg "@fortawesome/fontawesome-free" "$FA_VERSION" fa; printf '%s/fa/svgs' "$SCRATCH" ;;
|
|
vsc) fetch_pkg "@vscode/codicons" "$VSC_VERSION" vsc; printf '%s/vsc/src/icons' "$SCRATCH" ;;
|
|
rmx) fetch_pkg "remixicon" "$RMX_VERSION" rmx; printf '%s/rmx/icons' "$SCRATCH" ;;
|
|
*) return 1 ;;
|
|
esac
|
|
}
|
|
|
|
# --- transforms -------------------------------------------------------------
|
|
|
|
# Upstream icon-set files are already optimized and correctly sized; copying them
|
|
# byte-for-byte keeps the vendored tree diffable against upstream.
|
|
copy_verbatim() {
|
|
cp "$1" "$2"
|
|
}
|
|
|
|
# --- driver -----------------------------------------------------------------
|
|
|
|
emit() {
|
|
local dest_rel="$1" spec="$2"
|
|
local dest="$ASSET_DIR/$dest_rel"
|
|
local staged="$SCRATCH/staged/$dest_rel"
|
|
mkdir -p "$(dirname "$staged")"
|
|
|
|
case "$spec" in
|
|
keep)
|
|
[[ -f "$dest" ]] || fail "$dest_rel is marked 'keep' but does not exist"
|
|
return 0
|
|
;;
|
|
*:*)
|
|
local kind="${spec%%:*}" rel="${spec#*:}" root
|
|
root="$(pkg_root "$kind")" || { fail "unknown source kind '$kind' for $dest_rel"; return 0; }
|
|
[[ -f "$root/$rel" ]] || { fail "missing upstream $kind:$rel for $dest_rel"; return 0; }
|
|
copy_verbatim "$root/$rel" "$staged"
|
|
;;
|
|
*)
|
|
fail "unparseable source spec '$spec' for $dest_rel"
|
|
return 0
|
|
;;
|
|
esac
|
|
|
|
if (( CHECK_ONLY )); then
|
|
if ! cmp -s "$staged" "$dest"; then
|
|
fail "$dest_rel is out of date; run bash scripts/sync-icons.sh"
|
|
fi
|
|
else
|
|
mkdir -p "$(dirname "$dest")"
|
|
cp "$staged" "$dest"
|
|
fi
|
|
}
|
|
|
|
count=0
|
|
while IFS=$'\t' read -r dest_rel spec; do
|
|
# Tolerate a CRLF checkout; a stray \r would otherwise turn every source spec
|
|
# into an unknown one.
|
|
dest_rel="${dest_rel%$'\r'}"
|
|
spec="${spec%$'\r'}"
|
|
[[ -z "${dest_rel// }" ]] && continue
|
|
[[ "$dest_rel" == \#* ]] && continue
|
|
if [[ -z "${spec:-}" ]]; then
|
|
fail "manifest line for '$dest_rel' has no tab-separated source spec"
|
|
continue
|
|
fi
|
|
emit "$dest_rel" "$spec"
|
|
count=$((count + 1))
|
|
done < "$MANIFEST"
|
|
|
|
if (( failures )); then
|
|
printf 'sync-icons: %d problem(s) across %d manifest entries\n' "$failures" "$count" >&2
|
|
exit 1
|
|
fi
|
|
|
|
if (( CHECK_ONLY )); then
|
|
printf 'sync-icons: %d assets match the manifest\n' "$count"
|
|
else
|
|
printf 'sync-icons: synced %d assets\n' "$count"
|
|
fi
|