Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QKxGW1raAWaqeU8WdHsMsp
142 lines
3.6 KiB
Bash
Executable File
142 lines
3.6 KiB
Bash
Executable File
#!/bin/bash
|
|
# omarchy:summary=Install or remove the OmarchyCN layer on an existing Omarchy
|
|
# omarchy:args=[--uninstall]
|
|
# omarchy:examples=omarchy-cn-install-overlay | omarchy-cn-install-overlay --uninstall
|
|
# Bootstraps onto a foreign OMARCHY_PATH, so it resolves its own checkout root.
|
|
|
|
set -euo pipefail
|
|
|
|
SRC=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd)
|
|
DEST="${OMARCHY_PATH:?OMARCHY_PATH must point at the target Omarchy install}"
|
|
MANIFEST="$HOME/.local/state/omarchycn/overlay-manifest"
|
|
|
|
run_in() {
|
|
local root="$1"
|
|
shift
|
|
if [[ -w $root ]]; then
|
|
"$@"
|
|
else
|
|
sudo "$@"
|
|
fi
|
|
}
|
|
|
|
valid_entry() {
|
|
[[ $1 == "cn" || $1 =~ ^bin/(omarchycn|omarchy-cn-[a-z0-9-]+)$ ]]
|
|
}
|
|
|
|
MENU_EXT="$HOME/.config/omarchy/extensions/omarchy-menu.jsonc"
|
|
MENU_MARKER="// OmarchyCN overlay menu extension"
|
|
|
|
install_menu_extension() {
|
|
if [[ -s $MENU_EXT ]] && ! grep -qF "$MENU_MARKER" "$MENU_EXT"; then
|
|
echo "跳过菜单扩展:$MENU_EXT 已有用户内容,请手动合并 default/omarchy/omarchy-menu.jsonc 的 OmarchyCN 段"
|
|
return 0
|
|
fi
|
|
mkdir -p "${MENU_EXT%/*}"
|
|
{
|
|
echo "$MENU_MARKER"
|
|
echo "{"
|
|
sed -n '/^ \/\/ OmarchyCN$/,$p' "$SRC/default/omarchy/omarchy-menu.jsonc" | sed '$d'
|
|
echo "}"
|
|
} > "$MENU_EXT"
|
|
echo "OmarchyCN 菜单扩展已写入 $MENU_EXT"
|
|
}
|
|
|
|
remove_menu_extension() {
|
|
if [[ -f $MENU_EXT ]] && grep -qF "$MENU_MARKER" "$MENU_EXT"; then
|
|
rm -f "$MENU_EXT"
|
|
fi
|
|
}
|
|
|
|
uninstall() {
|
|
if [[ ! -f $MANIFEST ]]; then
|
|
echo "No overlay manifest at $MANIFEST" >&2
|
|
exit 1
|
|
fi
|
|
|
|
local dest="" rel=""
|
|
dest=$(grep -m1 '^dest=' "$MANIFEST" | cut -d= -f2-)
|
|
if [[ -z $dest || ! -d $dest ]]; then
|
|
echo "Manifest has no valid dest= record" >&2
|
|
exit 1
|
|
fi
|
|
|
|
# Validate every entry before deleting anything
|
|
while IFS= read -r rel; do
|
|
[[ $rel == source=* || $rel == dest=* ]] && continue
|
|
if ! valid_entry "$rel"; then
|
|
echo "Refusing suspicious manifest entry: $rel (nothing deleted)" >&2
|
|
exit 1
|
|
fi
|
|
done < "$MANIFEST"
|
|
|
|
while IFS= read -r rel; do
|
|
[[ $rel == source=* || $rel == dest=* ]] && continue
|
|
if [[ $rel == "cn" ]]; then
|
|
run_in "$dest" rm -rf "$dest/cn"
|
|
else
|
|
run_in "$dest" rm -f "$dest/$rel"
|
|
fi
|
|
done < "$MANIFEST"
|
|
|
|
remove_menu_extension
|
|
rm -f "$MANIFEST"
|
|
echo "OmarchyCN overlay removed from $dest"
|
|
}
|
|
|
|
install() {
|
|
if [[ ! -f $DEST/version || ! -x $DEST/bin/omarchy ]]; then
|
|
echo "No Omarchy install found at $DEST" >&2
|
|
exit 1
|
|
fi
|
|
if [[ $SRC == "$DEST" ]]; then
|
|
echo "Source checkout and target are the same tree; nothing to overlay" >&2
|
|
exit 1
|
|
fi
|
|
|
|
# Reinstall: remove the previous overlay first so upgrades leave no residue
|
|
if [[ -f $MANIFEST ]]; then
|
|
uninstall
|
|
fi
|
|
|
|
if [[ -e $DEST/cn ]]; then
|
|
echo "Refusing to take over unmanaged $DEST/cn" >&2
|
|
exit 1
|
|
fi
|
|
|
|
local f rel entries=()
|
|
for f in "$SRC/bin/omarchycn" "$SRC"/bin/omarchy-cn-*; do
|
|
rel="bin/${f##*/}"
|
|
if [[ -e $DEST/$rel ]]; then
|
|
echo "Refusing to overwrite unmanaged $DEST/$rel" >&2
|
|
exit 1
|
|
fi
|
|
entries+=("$rel")
|
|
done
|
|
|
|
# Manifest is the intent record, published BEFORE copying: if a copy fails
|
|
# midway, a rerun sees the manifest, uninstalls the partial state, retries.
|
|
mkdir -p "${MANIFEST%/*}"
|
|
{
|
|
echo "source=$SRC"
|
|
echo "dest=$DEST"
|
|
echo "cn"
|
|
printf '%s\n' "${entries[@]}"
|
|
} > "$MANIFEST"
|
|
|
|
run_in "$DEST" cp -r "$SRC/cn" "$DEST/cn"
|
|
for rel in "${entries[@]}"; do
|
|
run_in "$DEST" cp "$SRC/$rel" "$DEST/$rel"
|
|
done
|
|
|
|
install_menu_extension
|
|
echo "OmarchyCN overlay installed into $DEST (${#entries[@]} commands)"
|
|
echo "Verify: omarchy cn version"
|
|
}
|
|
|
|
if [[ ${1:-} == "--uninstall" ]]; then
|
|
uninstall
|
|
else
|
|
install
|
|
fi
|