From 13c7a5f2795781041cb2fb5887ec86bb022a87b9 Mon Sep 17 00:00:00 2001 From: hjoncour Date: Thu, 12 Mar 2026 23:50:38 -0400 Subject: [PATCH] feature(icons): add seti icons --- .ssmver/hooks/post-commit | 17 ++ .ssmver/hooks/prepare-commit-msg | 7 + .ssmver/scripts/bump_version.sh | 291 ++++++++++++++++++++++++++++ entrypoints/popup/main.ts | 83 +++----- package-lock.json | 11 +- package.json | 1 + scripts/copy-icons.ts | 12 +- src/icon-engine/manifest-builder.ts | 95 +++++++++ src/icon-engine/types.ts | 4 +- 9 files changed, 456 insertions(+), 65 deletions(-) create mode 100755 .ssmver/hooks/post-commit create mode 100755 .ssmver/hooks/prepare-commit-msg create mode 100755 .ssmver/scripts/bump_version.sh diff --git a/.ssmver/hooks/post-commit b/.ssmver/hooks/post-commit new file mode 100755 index 0000000..37b8b84 --- /dev/null +++ b/.ssmver/hooks/post-commit @@ -0,0 +1,17 @@ +#!/bin/sh +set -eu + +if [ "${SSMVER_AMENDING:-}" = "1" ]; then + exit 0 +fi + +if [ ! -f "ssmver.toml" ]; then + exit 0 +fi + +if git diff --quiet -- ssmver.toml; then + exit 0 +fi + +git add ssmver.toml +SSMVER_AMENDING=1 git commit --amend --no-edit >/dev/null diff --git a/.ssmver/hooks/prepare-commit-msg b/.ssmver/hooks/prepare-commit-msg new file mode 100755 index 0000000..f20e6ff --- /dev/null +++ b/.ssmver/hooks/prepare-commit-msg @@ -0,0 +1,7 @@ +#!/bin/sh +set -eu + +SCRIPT_DIR=$(CDPATH= cd -- "$(dirname "$0")/../scripts" && pwd) +. "$SCRIPT_DIR/bump_version.sh" + +ssmver_prepare_commit_msg "$1" "${2:-}" diff --git a/.ssmver/scripts/bump_version.sh b/.ssmver/scripts/bump_version.sh new file mode 100755 index 0000000..55ffe26 --- /dev/null +++ b/.ssmver/scripts/bump_version.sh @@ -0,0 +1,291 @@ +#!/bin/sh +set -eu + +SSMVER_CONFIG="ssmver.toml" + +ssmver_get_version() { + sed -n 's/^version[[:space:]]*=[[:space:]]*"\([0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\)".*/\1/p' "$SSMVER_CONFIG" | head -n 1 +} + +ssmver_version_from_content() { + printf '%s\n' "$1" | sed -n 's/^version[[:space:]]*=[[:space:]]*"\([0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\)".*/\1/p' | head -n 1 +} + +ssmver_get_table_value() { + table="$1" + key="$2" + + awk -v table="$table" -v key="$key" ' + BEGIN { in_table = 0 } + /^[[:space:]]*\[/ { + in_table = ($0 == "[" table "]") + next + } + in_table { + line = $0 + sub(/[[:space:]]*#.*/, "", line) + if (line ~ /^[[:space:]]*$/) { + next + } + + split(line, parts, "=") + current_key = parts[1] + gsub(/[[:space:]]/, "", current_key) + if (current_key != key) { + next + } + + value = substr(line, index(line, "=") + 1) + sub(/^[[:space:]]*/, "", value) + sub(/[[:space:]]*$/, "", value) + sub(/^"/, "", value) + sub(/"$/, "", value) + print value + exit + } + ' "$SSMVER_CONFIG" +} + +ssmver_get_setting() { + ssmver_get_table_value "settings" "$1" +} + +ssmver_get_prefix_level() { + ssmver_get_table_value "prefixes" "$1" +} + +ssmver_extract_prefix() { + printf '%s\n' "$1" | sed -n 's/^\([[:alnum:]_-][[:alnum:]_-]*\)\(([^)]*)\)\{0,1\}:.*/\1/p' +} + +ssmver_level_priority() { + case "$1" in + patch) printf '1\n' ;; + minor) printf '2\n' ;; + major) printf '3\n' ;; + *) printf '0\n' ;; + esac +} + +ssmver_bump_version() { + version="$1" + level="$2" + + old_ifs=$IFS + IFS=. + set -- $version + IFS=$old_ifs + + major="$1" + minor="$2" + patch="$3" + + case "$level" in + patch) + patch=$((patch + 1)) + ;; + minor) + minor=$((minor + 1)) + patch=0 + ;; + major) + major=$((major + 1)) + minor=0 + patch=0 + ;; + *) + return 1 + ;; + esac + + printf '%s.%s.%s\n' "$major" "$minor" "$patch" +} + +ssmver_write_version() { + new_version="$1" + tmp_file="${SSMVER_CONFIG}.tmp.$$" + + awk -v new_version="$new_version" ' + BEGIN { updated = 0 } + !updated && /^version[[:space:]]*=/ { + print "version = \"" new_version "\"" + updated = 1 + next + } + { print } + END { + if (!updated) { + exit 1 + } + } + ' "$SSMVER_CONFIG" > "$tmp_file" + + mv "$tmp_file" "$SSMVER_CONFIG" +} + +ssmver_find_main_ref() { + for ref in refs/heads/main refs/heads/master refs/remotes/origin/main refs/remotes/origin/master + do + if git show-ref --verify --quiet "$ref"; then + printf '%s\n' "$ref" + return 0 + fi + done + + return 1 +} + +ssmver_highest_level_from_file() { + file="$1" + highest="" + + while IFS= read -r subject + do + prefix=$(ssmver_extract_prefix "$subject" || true) + [ -n "$prefix" ] || continue + + level=$(ssmver_get_prefix_level "$prefix" || true) + [ -n "$level" ] || continue + + if [ -z "$highest" ] || [ "$(ssmver_level_priority "$level")" -gt "$(ssmver_level_priority "$highest")" ]; then + highest="$level" + fi + done < "$file" + + printf '%s\n' "$highest" +} + +ssmver_branch_version() { + new_level="$1" + current_version=$(ssmver_get_version) + main_ref=$(ssmver_find_main_ref || true) + + if [ -z "$main_ref" ]; then + ssmver_bump_version "$current_version" "$new_level" + return 0 + fi + + merge_base=$(git merge-base HEAD "$main_ref" 2>/dev/null || true) + if [ -z "$merge_base" ]; then + ssmver_bump_version "$current_version" "$new_level" + return 0 + fi + + subjects_file=$(mktemp) + git log --format=%s "$merge_base..HEAD" > "$subjects_file" 2>/dev/null || true + previous_highest=$(ssmver_highest_level_from_file "$subjects_file") + rm -f "$subjects_file" + + if [ -n "$previous_highest" ] && [ "$(ssmver_level_priority "$new_level")" -le "$(ssmver_level_priority "$previous_highest")" ]; then + return 1 + fi + + base_content=$(git show "$merge_base:$SSMVER_CONFIG" 2>/dev/null || true) + base_version=$(ssmver_version_from_content "$base_content") + if [ -z "$base_version" ]; then + base_version="$current_version" + fi + + ssmver_bump_version "$base_version" "$new_level" +} + +ssmver_needs_prompt() { + prefix="$1" + prompt_mode=$(ssmver_get_setting "prompt" || true) + + case "$prompt_mode" in + always) + return 0 + ;; + ask) + raw=$(ssmver_get_setting "prompt_prefixes" || true) + parsed=$(printf '%s\n' "$raw" | tr ',' '\n' | sed 's/\[//g; s/\]//g; s/"//g; s/^[[:space:]]*//; s/[[:space:]]*$//') + while IFS= read -r candidate + do + [ -n "$candidate" ] || continue + if [ "$candidate" = "$prefix" ]; then + return 0 + fi + done < /dev/tty + if ! IFS= read -r body < /dev/tty; then + return 0 + fi + + if [ -n "$body" ]; then + printf '\n%s\n' "$body" >> "$message_file" + fi +} + +ssmver_prepare_commit_msg() { + message_file="$1" + source="${2:-}" + + if [ "${SSMVER_AMENDING:-}" = "1" ]; then + exit 0 + fi + + case "$source" in + merge|squash|commit) + exit 0 + ;; + esac + + if [ ! -f "$SSMVER_CONFIG" ]; then + exit 0 + fi + + first_line=$(sed -n '1p' "$message_file") + prefix=$(ssmver_extract_prefix "$first_line" || true) + [ -n "$prefix" ] || exit 0 + + level=$(ssmver_get_prefix_level "$prefix" || true) + [ -n "$level" ] || exit 0 + + mode=$(ssmver_get_setting "mode" || true) + current_version=$(ssmver_get_version) + + case "$mode" in + branch) + new_version=$(ssmver_branch_version "$level") || exit 0 + ;; + *) + new_version=$(ssmver_bump_version "$current_version" "$level") + ;; + esac + + if [ "$new_version" != "$current_version" ]; then + ssmver_write_version "$new_version" + fi + + if ssmver_needs_prompt "$prefix"; then + ssmver_prompt_for_body "$message_file" "$prefix" + fi +} diff --git a/entrypoints/popup/main.ts b/entrypoints/popup/main.ts index 476f7da..89a3e28 100644 --- a/entrypoints/popup/main.ts +++ b/entrypoints/popup/main.ts @@ -9,41 +9,22 @@ if (!app) { throw new Error('Popup root element not found.'); } -const MATERIAL_PACKS: ThemePackId[] = [ - 'default', 'angular', 'nest', 'angular_ngrx', 'react', - 'react_redux', 'roblox', 'qwik', 'vue', 'vue_vuex', 'bashly', -]; - -const ALL_PACKS: { id: ThemePackId; label: string; group: string }[] = [ - ...MATERIAL_PACKS.map((id) => ({ id, label: formatPackLabel(id), group: 'Material Icon Theme' })), - { id: 'vscode-icons', label: 'VSCode Icons', group: 'VSCode Icons' }, -]; - -function formatPackLabel(pack: string): string { - return pack === 'default' - ? 'Default' - : pack - .split('_') - .map((segment) => segment.charAt(0).toUpperCase() + segment.slice(1)) - .join(' '); -} - app.innerHTML = `
-

GitHub Material Icons

-

Replace GitHub file icons with Material Design icons.

-