fix: Make the install script clone the repo instead of linking it and reflected changes into the updater
This commit is contained in:
parent
c51330c1c2
commit
38d2572e84
2 changed files with 102 additions and 79 deletions
|
|
@ -115,11 +115,18 @@ header() {
|
||||||
clear
|
clear
|
||||||
printf "${BOLD}${BLUE}"
|
printf "${BOLD}${BLUE}"
|
||||||
cat << 'EOF'
|
cat << 'EOF'
|
||||||
╔══════════════════════════════════════════════════════════╗
|
╔══════════════════════════════════════════════════════════════════╗
|
||||||
║ Some ASCII Art ║
|
║ _ _ _____ _ _ ║
|
||||||
╠══════════════════════════════════════════════════════════╣
|
║ /\ | | | | | __ \ | | | | ║
|
||||||
║ Installer · Arch Linux ║
|
║ / \ | |_| | __ _ ___ | | | | ___ ___| | _| |_ ___ _ __ ║
|
||||||
╚══════════════════════════════════════════════════════════╝
|
║ / /\ \| __| |/ _` / __| | | | |/ _ \/ __| |/ / __/ _ \| '_ \ ║
|
||||||
|
║ / ____ \ |_| | (_| \__ \ | |__| | __/\__ \ <| || (_) | |_) | ║
|
||||||
|
║ /_/ \_\__|_|\__,_|___/ |_____/ \___||___/_|\_\\__\___/| .__/ ║
|
||||||
|
║ | | ║
|
||||||
|
║ |_| ║
|
||||||
|
╠══════════════════════════════════════════════════════════════════╣
|
||||||
|
║ Installer · Arch Linux ║
|
||||||
|
╚══════════════════════════════════════════════════════════════════╝
|
||||||
EOF
|
EOF
|
||||||
printf "${RESET}\n"
|
printf "${RESET}\n"
|
||||||
}
|
}
|
||||||
|
|
@ -537,25 +544,63 @@ install_packages() {
|
||||||
}
|
}
|
||||||
|
|
||||||
# ─────────────────────────────────────────────────────────────────────────────
|
# ─────────────────────────────────────────────────────────────────────────────
|
||||||
# STEP 9 — Stow dotfiles
|
# STEP 9 — Clone into ~/.atlas-dotfiles and stow
|
||||||
# ─────────────────────────────────────────────────────────────────────────────
|
# ─────────────────────────────────────────────────────────────────────────────
|
||||||
stow_dotfiles() {
|
stow_dotfiles() {
|
||||||
phase "Stowing dotfiles"
|
phase "Copying and stowing dotfiles"
|
||||||
|
|
||||||
step "Linking ${CONFIG_DIR} → ${HOME}"
|
# ~/.atlas-dotfiles is the permanent home of the repo. They can delete the original
|
||||||
|
# clone after installation without breaking anything.
|
||||||
|
local remote_url
|
||||||
|
remote_url=$(git -C "$REPO_DIR" remote get-url origin 2>/dev/null || true)
|
||||||
|
|
||||||
# The config/ dir IS the stow package (its contents mirror $HOME)
|
if [[ -z $remote_url ]]; then
|
||||||
# We treat config/ as a single stow package named "config"
|
die "Could not determine remote URL from $REPO_DIR (is origin set?)"
|
||||||
# stow will create symlinks in $HOME for everything inside config/
|
fi
|
||||||
|
|
||||||
# Backup any existing files that would conflict
|
step "Setting up ~/.atlas-dotfiles as the permanent repo"
|
||||||
|
info "Remote: $remote_url"
|
||||||
|
|
||||||
|
if [[ -d $DOTFILES_DIR/.git ]]; then
|
||||||
|
# Already a git repo — verify it points to the same remote
|
||||||
|
local existing_remote
|
||||||
|
existing_remote=$(git -C "$DOTFILES_DIR" remote get-url origin 2>/dev/null || true)
|
||||||
|
if [[ $existing_remote == $remote_url ]]; then
|
||||||
|
ok "~/.atlas-dotfiles already cloned from correct remote"
|
||||||
|
run_quiet "Pulling latest" git -C "$DOTFILES_DIR" pull --ff-only origin main
|
||||||
|
else
|
||||||
|
warn "~/.atlas-dotfiles exists but points to a different remote:"
|
||||||
|
warn " existing: $existing_remote"
|
||||||
|
warn " expected: $remote_url"
|
||||||
|
if confirm "Replace it with the correct repo?" y; then
|
||||||
|
rm -rf "$DOTFILES_DIR"
|
||||||
|
run_quiet "Cloning dotfiles" git clone "$remote_url" "$DOTFILES_DIR"
|
||||||
|
else
|
||||||
|
die "Aborted — ~/.atlas-dotfiles remote mismatch"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
elif [[ -e $DOTFILES_DIR ]]; then
|
||||||
|
warn "~/.atlas-dotfiles exists but is not a git repo — moving to ~/.atlas-dotfiles.bak"
|
||||||
|
mv "$DOTFILES_DIR" "${DOTFILES_DIR}.bak"
|
||||||
|
run_quiet "Cloning dotfiles" git clone "$remote_url" "$DOTFILES_DIR"
|
||||||
|
else
|
||||||
|
run_quiet "Cloning dotfiles" git clone "$remote_url" "$DOTFILES_DIR"
|
||||||
|
fi
|
||||||
|
|
||||||
|
#TODO Checkout ?
|
||||||
|
|
||||||
|
ok "~/.atlas-dotfiles → $remote_url"
|
||||||
|
|
||||||
|
# Backup any real files that would conflict with stow links
|
||||||
|
local stow_config_dir="$DOTFILES_DIR/config"
|
||||||
local conflicts=()
|
local conflicts=()
|
||||||
while IFS= read -r link; do
|
while IFS= read -r link; do
|
||||||
local target="$HOME/${link#$CONFIG_DIR/}"
|
local rel="${link#$stow_config_dir/}"
|
||||||
|
local target="$HOME/$rel"
|
||||||
if [[ -e $target && ! -L $target ]]; then
|
if [[ -e $target && ! -L $target ]]; then
|
||||||
conflicts+=("$target")
|
conflicts+=("$target")
|
||||||
fi
|
fi
|
||||||
done < <(find "$CONFIG_DIR" -type f)
|
done < <(find "$stow_config_dir" -type f 2>/dev/null)
|
||||||
|
|
||||||
if (( ${#conflicts[@]} )); then
|
if (( ${#conflicts[@]} )); then
|
||||||
warn "${#conflicts[@]} existing file(s) will be backed up (.bak):"
|
warn "${#conflicts[@]} existing file(s) will be backed up (.bak):"
|
||||||
|
|
@ -565,29 +610,9 @@ stow_dotfiles() {
|
||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Create DOTFILES_DIR as a symlink to CONFIG_DIR, or use CONFIG_DIR directly
|
# Stow from ~/.atlas-dotfiles treating config/ as the stow package
|
||||||
# We symlink ~/.atlas-dotfiles → repo's config dir so stow state lives in the repo
|
|
||||||
if [[ -L $DOTFILES_DIR ]]; then
|
|
||||||
local existing_target; existing_target=$(readlink -f "$DOTFILES_DIR")
|
|
||||||
if [[ $existing_target != "$CONFIG_DIR" ]]; then
|
|
||||||
warn "~/.atlas-dotfiles already points elsewhere: $existing_target"
|
|
||||||
warn "Removing and re-linking to $CONFIG_DIR"
|
|
||||||
rm "$DOTFILES_DIR"
|
|
||||||
ln -s "$CONFIG_DIR" "$DOTFILES_DIR"
|
|
||||||
fi
|
|
||||||
elif [[ -d $DOTFILES_DIR ]]; then
|
|
||||||
warn "~/.atlas-dotfiles exists as a real directory. Renaming to ~/.atlas-dotfiles.bak"
|
|
||||||
mv "$DOTFILES_DIR" "${DOTFILES_DIR}.bak"
|
|
||||||
ln -s "$CONFIG_DIR" "$DOTFILES_DIR"
|
|
||||||
else
|
|
||||||
ln -s "$CONFIG_DIR" "$DOTFILES_DIR"
|
|
||||||
fi
|
|
||||||
|
|
||||||
ok "~/.atlas-dotfiles → $CONFIG_DIR"
|
|
||||||
|
|
||||||
# Now run stow from inside the repo's parent, treating config as the package
|
|
||||||
run_quiet "Stowing config" \
|
run_quiet "Stowing config" \
|
||||||
stow --dir="$REPO_DIR" --target="$HOME" --restow config
|
stow --dir="$DOTFILES_DIR" --target="$HOME" --restow config
|
||||||
|
|
||||||
phase_done
|
phase_done
|
||||||
}
|
}
|
||||||
|
|
@ -709,28 +734,37 @@ enable_services() {
|
||||||
install_updater() {
|
install_updater() {
|
||||||
phase "Dotfiles updater"
|
phase "Dotfiles updater"
|
||||||
|
|
||||||
local updater_src="$SCRIPTS_DIR/update.sh"
|
local updater_in_dotfiles="$DOTFILES_DIR/scripts/update.sh"
|
||||||
local updater_link="$HOME/.local/bin/atlas-update"
|
local updater_link="$HOME/.local/bin/dotfiles-update"
|
||||||
|
|
||||||
if [[ ! -f $updater_src ]]; then
|
if [[ ! -f $updater_in_dotfiles ]]; then
|
||||||
warn "Updater not found at $updater_src — skipping"
|
warn "update.sh not found in ~/.atlas-dotfiles/scripts/ — skipping"
|
||||||
|
info "Expected: $updater_in_dotfiles"
|
||||||
phase_done
|
phase_done
|
||||||
return
|
return
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
chmod +x "$updater_in_dotfiles"
|
||||||
mkdir -p "$HOME/.local/bin"
|
mkdir -p "$HOME/.local/bin"
|
||||||
chmod +x "$updater_src"
|
|
||||||
|
|
||||||
# Create symlink (stow might also handle this if update.sh is in config/)
|
# Symlink into PATH — stow may also handle this if scripts/ is a stow pkg,
|
||||||
# Here we link directly so it's always in PATH regardless of stow layout
|
# but we do it explicitly here so it works regardless of stow layout.
|
||||||
ln -sf "$updater_src" "$updater_link"
|
ln -sf "$updater_in_dotfiles" "$updater_link"
|
||||||
ok "atlas-update → $updater_src"
|
ok "dotfiles-update → $updater_in_dotfiles"
|
||||||
info "Run ${BOLD}atlas-update${RESET} any time to sync with upstream"
|
info "Run ${BOLD}dotfiles-update${RESET} any time to sync with upstream"
|
||||||
|
|
||||||
# Save repo path into state so updater knows where it lives
|
# Initialise state inside the permanent repo
|
||||||
mkdir -p "$STATE_DIR"
|
local state_dir="$DOTFILES_DIR/.state"
|
||||||
state_set "repo_dir" "$REPO_DIR"
|
mkdir -p "$state_dir"
|
||||||
state_set "last_commit" "$(git -C "$REPO_DIR" rev-parse HEAD)"
|
# Point state file at the permanent repo, not the installer's location
|
||||||
|
grep -q "^repo_dir=" "$state_dir/update.state" 2>/dev/null || echo "repo_dir=$DOTFILES_DIR" >> "$state_dir/update.state"
|
||||||
|
# Stamp the current HEAD so the first `dotfiles-update` knows the baseline
|
||||||
|
local head; head=$(git -C "$DOTFILES_DIR" rev-parse HEAD)
|
||||||
|
if grep -q "^last_commit=" "$state_dir/update.state" 2>/dev/null; then
|
||||||
|
sed -i "s|^last_commit=.*|last_commit=${head}|" "$state_dir/update.state"
|
||||||
|
else
|
||||||
|
echo "last_commit=$head" >> "$state_dir/update.state"
|
||||||
|
fi
|
||||||
|
|
||||||
phase_done
|
phase_done
|
||||||
}
|
}
|
||||||
|
|
@ -744,7 +778,7 @@ finish() {
|
||||||
cat << 'EOF'
|
cat << 'EOF'
|
||||||
╔══════════════════════════════════════════════════════════╗
|
╔══════════════════════════════════════════════════════════╗
|
||||||
║ ║
|
║ ║
|
||||||
║ ✔ Installation complete! ║
|
║ ✔ Installation complete! ║
|
||||||
║ ║
|
║ ║
|
||||||
╚══════════════════════════════════════════════════════════╝
|
╚══════════════════════════════════════════════════════════╝
|
||||||
EOF
|
EOF
|
||||||
|
|
|
||||||
|
|
@ -190,9 +190,13 @@ git_fetch_and_check() {
|
||||||
|
|
||||||
# ── Conflict detection ────────────────────────────────────────────────────────
|
# ── Conflict detection ────────────────────────────────────────────────────────
|
||||||
collect_changed_files() {
|
collect_changed_files() {
|
||||||
# Files changed between old commit and new commit in the repo
|
# Files changed inside the config/ stow package between old and new commit.
|
||||||
|
# Strip the leading "config/" prefix so paths are relative to $HOME,
|
||||||
|
# matching what stow creates as symlink targets.
|
||||||
git -C "$DOTFILES_DIR" diff --name-only "${OLD_HASH}" "${NEW_HASH}" \
|
git -C "$DOTFILES_DIR" diff --name-only "${OLD_HASH}" "${NEW_HASH}" \
|
||||||
| grep -v '^packages/' | grep -v '^\.' || true
|
| grep '^config/' \
|
||||||
|
| sed 's|^config/||' \
|
||||||
|
|| true
|
||||||
}
|
}
|
||||||
|
|
||||||
handle_conflicts() {
|
handle_conflicts() {
|
||||||
|
|
@ -292,33 +296,17 @@ apply_git_update() {
|
||||||
# ── Stow ─────────────────────────────────────────────────────────────────────
|
# ── Stow ─────────────────────────────────────────────────────────────────────
|
||||||
apply_stow() {
|
apply_stow() {
|
||||||
section "Stowing dotfiles"
|
section "Stowing dotfiles"
|
||||||
cd "$DOTFILES_DIR"
|
|
||||||
|
|
||||||
# Discover stow packages (top-level dirs, excluding hidden & packages/)
|
local err_file; err_file=$(mktemp)
|
||||||
local stow_pkgs=()
|
if stow --dir="$STOW_DIR" --target="$STOW_TARGET" --restow "$STOW_PKG" 2>"$err_file"; then
|
||||||
while IFS= read -r d; do
|
ok "stow: $STOW_PKG"
|
||||||
local name
|
else
|
||||||
name=$(basename "$d")
|
warn "stow: $STOW_PKG (errors below)"
|
||||||
[[ $name == packages ]] && continue
|
while IFS= read -r line; do
|
||||||
stow_pkgs+=("$name")
|
echo " ${DIM}${line}${RESET}"
|
||||||
done < <(find "$DOTFILES_DIR" -mindepth 1 -maxdepth 1 -type d ! -name '.*' | sort)
|
done < "$err_file"
|
||||||
|
|
||||||
if (( ${#stow_pkgs[@]} == 0 )); then
|
|
||||||
warn "No stow packages found in $DOTFILES_DIR"
|
|
||||||
return
|
|
||||||
fi
|
fi
|
||||||
|
rm -f "$err_file"
|
||||||
for pkg in "${stow_pkgs[@]}"; do
|
|
||||||
if stow --restow --target="$STOW_TARGET" "$pkg" 2>/tmp/stow_err; then
|
|
||||||
ok "stow: $pkg"
|
|
||||||
else
|
|
||||||
warn "stow: $pkg (see error below)"
|
|
||||||
while IFS= read -r line; do
|
|
||||||
echo " ${DIM}${line}${RESET}"
|
|
||||||
done < /tmp/stow_err
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
rm -f /tmp/stow_err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# ── Package management ────────────────────────────────────────────────────────
|
# ── Package management ────────────────────────────────────────────────────────
|
||||||
|
|
@ -493,7 +481,8 @@ process_aur_group() {
|
||||||
# ── Entry point ───────────────────────────────────────────────────────────────
|
# ── Entry point ───────────────────────────────────────────────────────────────
|
||||||
main() {
|
main() {
|
||||||
echo
|
echo
|
||||||
echo "${BOLD} Hyprland Dotfiles Updater${RESET} ${DIM}(Arch Linux)${RESET}"
|
echo "${BOLD} Atlas Desktop Updater${RESET}"
|
||||||
|
echo "${DIM} Arch Linux${RESET}"
|
||||||
echo " ${DIM}Target: ${DOTFILES_DIR}${RESET}"
|
echo " ${DIM}Target: ${DOTFILES_DIR}${RESET}"
|
||||||
|
|
||||||
[[ -d $DOTFILES_DIR/.git ]] || die "$DOTFILES_DIR is not a git repository."
|
[[ -d $DOTFILES_DIR/.git ]] || die "$DOTFILES_DIR is not a git repository."
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue