Upload files to "/"
This commit is contained in:
186
update_zshrc.sh
Normal file
186
update_zshrc.sh
Normal file
@@ -0,0 +1,186 @@
|
||||
#!/bin/bash
|
||||
# =============================================================================
|
||||
# 🔧 StianNOR-ZSHkit — .zshrc Merge Script
|
||||
# Merges managed sections from ZSHkit/.zshrc into the live ~/.zshrc
|
||||
# without overwriting personal aliases or custom configuration.
|
||||
#
|
||||
# How it works:
|
||||
# - Managed sections in ~/.zshrc are wrapped with markers:
|
||||
# # --- ZSHKIT:section_name ---
|
||||
# ... content ...
|
||||
# # --- /ZSHKIT:section_name ---
|
||||
# - On first run, markers are injected into your existing ~/.zshrc
|
||||
# - On subsequent runs, content between markers is updated from ZSHkit
|
||||
# - Everything outside the markers is never touched
|
||||
#
|
||||
# Usage:
|
||||
# ./update_zshrc.sh — merge and apply
|
||||
# ./update_zshrc.sh --dry-run — show what would change, no writes
|
||||
# ./update_zshrc.sh --status — show which sections are present
|
||||
# =============================================================================
|
||||
set -euo pipefail
|
||||
|
||||
GREEN='\033[0;32m'; YELLOW='\033[1;33m'; CYAN='\033[0;36m'
|
||||
RED='\033[0;31m'; BOLD='\033[1m'; RESET='\033[0m'
|
||||
LINE="────────────────────────────────────────────────────────────────────────────"
|
||||
|
||||
info() { echo -e "${CYAN}ℹ $*${RESET}"; }
|
||||
success() { echo -e "${GREEN}✅ $*${RESET}"; }
|
||||
warn() { echo -e "${YELLOW}⚠ $*${RESET}"; }
|
||||
error() { echo -e "${RED}❌ $*${RESET}"; }
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
SOURCE="$SCRIPT_DIR/.zshrc"
|
||||
TARGET="$HOME/.zshrc"
|
||||
BACKUP="$HOME/.zshrc.bak.$(date +%Y%m%d-%H%M%S)"
|
||||
DRY_RUN=false
|
||||
STATUS_ONLY=false
|
||||
|
||||
case "${1:-}" in
|
||||
--dry-run) DRY_RUN=true ;;
|
||||
--status) STATUS_ONLY=true ;;
|
||||
esac
|
||||
|
||||
if [[ ! -f "$SOURCE" ]]; then
|
||||
error "Source not found: $SOURCE"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ ! -f "$TARGET" ]]; then
|
||||
warn "No ~/.zshrc found — copying source directly"
|
||||
cp "$SOURCE" "$TARGET"
|
||||
success "Created $TARGET from ZSHkit source"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
declare -A SECTION_START=(
|
||||
[autosuggestions]="# ─── Autosuggestions"
|
||||
[aliases]="# ─── User Aliases and Functions"
|
||||
)
|
||||
declare -A SECTION_END=(
|
||||
[autosuggestions]="source \$ZSH/oh-my-zsh.sh"
|
||||
[aliases]="alias rsy="
|
||||
)
|
||||
|
||||
# =============================================================================
|
||||
# STATUS MODE
|
||||
# =============================================================================
|
||||
if [[ "$STATUS_ONLY" = true ]]; then
|
||||
echo -e "\n${BOLD}${CYAN}🔧 .zshrc Managed Sections Status${RESET}"
|
||||
echo -e "${LINE}"
|
||||
for section in "${!SECTION_START[@]}"; do
|
||||
marker="# --- ZSHKIT:${section} ---"
|
||||
if grep -qF "$marker" "$TARGET" 2>/dev/null; then
|
||||
success "Section present: $section"
|
||||
else
|
||||
warn "Section missing (will be injected on next run): $section"
|
||||
fi
|
||||
done
|
||||
echo -e "${LINE}\n"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# =============================================================================
|
||||
# BACKUP
|
||||
# =============================================================================
|
||||
cp "$TARGET" "$BACKUP"
|
||||
info "Backup saved: $BACKUP"
|
||||
|
||||
echo -e "\n${BOLD}${CYAN}🔧 Merging .zshrc sections${RESET}"
|
||||
echo -e "${LINE}"
|
||||
|
||||
CHANGED=0
|
||||
|
||||
merge_section() {
|
||||
local name="$1"
|
||||
local start_pat="$2"
|
||||
local end_pat="$3"
|
||||
|
||||
local begin_marker="# --- ZSHKIT:${name} ---"
|
||||
local end_marker="# --- /ZSHKIT:${name} ---"
|
||||
|
||||
local new_content
|
||||
new_content=$(awk "/$start_pat/{found=1} found{print} /$end_pat/{if(found) {found=0}}" "$SOURCE")
|
||||
|
||||
if [[ -z "$new_content" ]]; then
|
||||
warn "Could not extract section '$name' from source — skipping"
|
||||
return
|
||||
fi
|
||||
|
||||
local block
|
||||
block="$begin_marker
|
||||
$new_content
|
||||
$end_marker"
|
||||
|
||||
if grep -qF "$begin_marker" "$TARGET"; then
|
||||
local existing
|
||||
existing=$(awk "/$begin_marker/{found=1; next} /$end_marker/{found=0; next} found{print}" "$TARGET")
|
||||
if [[ "$existing" == "$new_content" ]]; then
|
||||
success "Up to date: $name"
|
||||
return
|
||||
fi
|
||||
if [[ "$DRY_RUN" = true ]]; then
|
||||
warn "[DRY RUN] Would update section: $name"
|
||||
diff <(echo "$existing") <(echo "$new_content") || true
|
||||
else
|
||||
python3 - "$TARGET" "$begin_marker" "$end_marker" "$new_content" <<'PYEOF'
|
||||
import sys, re
|
||||
target = sys.argv[1]
|
||||
begin = sys.argv[2]
|
||||
end = sys.argv[3]
|
||||
new_body = sys.argv[4]
|
||||
with open(target, 'r') as f:
|
||||
content = f.read()
|
||||
pattern = re.escape(begin) + r'.*?' + re.escape(end)
|
||||
replacement = begin + '\n' + new_body + '\n' + end
|
||||
new_content = re.sub(pattern, replacement, content, flags=re.DOTALL)
|
||||
with open(target, 'w') as f:
|
||||
f.write(new_content)
|
||||
PYEOF
|
||||
success "Updated section: $name"
|
||||
(( CHANGED++ )) || true
|
||||
fi
|
||||
else
|
||||
if [[ "$DRY_RUN" = true ]]; then
|
||||
warn "[DRY RUN] Would inject new section: $name"
|
||||
else
|
||||
if grep -q "# End of .zshrc" "$TARGET"; then
|
||||
python3 - "$TARGET" "# End of .zshrc" "$block" <<'PYEOF'
|
||||
import sys
|
||||
target = sys.argv[1]
|
||||
marker = sys.argv[2]
|
||||
new_block = sys.argv[3]
|
||||
with open(target, 'r') as f:
|
||||
content = f.read()
|
||||
content = content.replace(marker, new_block + '\n\n' + marker)
|
||||
with open(target, 'w') as f:
|
||||
f.write(content)
|
||||
PYEOF
|
||||
else
|
||||
echo "" >> "$TARGET"
|
||||
echo "$block" >> "$TARGET"
|
||||
fi
|
||||
success "Injected new section: $name"
|
||||
(( CHANGED++ )) || true
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
merge_section "autosuggestions" \
|
||||
"# ─── Autosuggestions" \
|
||||
"source \\\$ZSH/oh-my-zsh.sh"
|
||||
|
||||
merge_section "aliases" \
|
||||
"# ─── User Aliases and Functions" \
|
||||
"alias rsy="
|
||||
|
||||
echo -e "${LINE}"
|
||||
if [[ "$DRY_RUN" = true ]]; then
|
||||
warn "Dry run complete — no files were modified"
|
||||
elif [[ $CHANGED -eq 0 ]]; then
|
||||
success "Everything already up to date — no changes needed"
|
||||
else
|
||||
success "$CHANGED section(s) updated in $TARGET"
|
||||
echo -e "\n ${YELLOW}Run ${CYAN}fresh${RESET}${YELLOW} or open a new terminal to apply changes.${RESET}"
|
||||
fi
|
||||
echo -e "${LINE}\n"
|
||||
Reference in New Issue
Block a user