-
-
Notifications
You must be signed in to change notification settings - Fork 0
Claude/finalize yadm stow setup 5 quk u #147
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
5d878d6
356f7d7
f02576b
18a5669
4e2ff99
8fb42f0
e65be90
2263b7a
75fcfca
4e24c27
ecb1b46
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -29,7 +29,11 @@ install_base_deps(){ | |
| local pac_cmd="sudo pacman" | ||
| has paru && pac_cmd="paru" | ||
| has yay && pac_cmd="yay" | ||
| $pac_cmd -Sq --needed --noconfirm git gitoxide aria2 curl zsh fd sd ripgrep bat jq zoxide starship fzf stow tuckr rsync konsave || warn "Some packages may have failed to install" | ||
| # Try tuckr first, fall back to stow if unavailable | ||
| if ! $pac_cmd -Sq --needed --noconfirm git gitoxide aria2 curl zsh fd sd ripgrep bat jq zoxide starship fzf tuckr rsync konsave; then | ||
| warn "tuckr install failed, installing stow as fallback" | ||
| $pac_cmd -Sq --needed --noconfirm git gitoxide aria2 curl zsh fd sd ripgrep bat jq zoxide starship fzf stow rsync konsave || warn "Some packages may have failed to install" | ||
| fi | ||
| elif has apt-get; then | ||
| sudo apt-get update -y | ||
| sudo apt-get install -y git curl zsh fd-find ripgrep bat jq fzf stow rsync || warn "Some packages may have failed" | ||
|
|
@@ -64,20 +68,34 @@ configure_shell(){ | |
| fi | ||
| } | ||
| deploy_system_configs(){ | ||
| if ! has tuckr; then | ||
| warn "tuckr not installed; skipping etc/usr." | ||
| warn "Install tuckr then run: sudo tuckr link -d $REPO_DIR -t / etc usr" | ||
| local pkg | ||
| if has tuckr; then | ||
| info "Using tuckr for system config deployment" | ||
| local hooks_file="${REPO_DIR}/hooks.toml" | ||
| for pkg in etc usr; do | ||
| local src="${REPO_DIR}/${pkg}" | ||
| [[ -d $src ]] || { warn "Missing dir: $src"; continue; } | ||
| info "Linking ${pkg}/ → / (tuckr)" | ||
| local cmd=(sudo tuckr link -d "$REPO_DIR" -t / "$pkg") | ||
| [[ -f $hooks_file ]] && cmd+=(-H "$hooks_file") | ||
| "${cmd[@]}" || warn "Failed to link $pkg" | ||
| done | ||
| elif has stow; then | ||
| info "tuckr not found, using stow as fallback" | ||
| for pkg in etc usr; do | ||
| local src="${REPO_DIR}/${pkg}" | ||
| [[ -d $src ]] || { warn "Missing dir: $src"; continue; } | ||
| info "Linking ${pkg}/ → / (stow)" | ||
| (cd "$REPO_DIR" && sudo stow -t / -d . "$pkg") || warn "Failed to stow $pkg" | ||
| done | ||
| else | ||
| warn "Neither tuckr nor stow installed; skipping etc/usr deployment." | ||
| warn "Install tuckr: paru -S tuckr" | ||
| warn " OR stow: paru -S stow" | ||
| warn "Then run: sudo tuckr link -d $REPO_DIR -t / etc usr" | ||
| warn " OR: cd $REPO_DIR && sudo stow -t / etc usr" | ||
| return 0 | ||
| fi | ||
|
Comment on lines
+72
to
98
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
| local hooks_file="${REPO_DIR}/hooks.toml" pkg | ||
| for pkg in etc usr; do | ||
| local src="${REPO_DIR}/${pkg}" | ||
| [[ -d $src ]] || { warn "Missing dir: $src"; continue; } | ||
| info "Linking ${pkg}/ → /" | ||
| local cmd=(sudo tuckr link -d "$REPO_DIR" -t / "$pkg") | ||
| [[ -f $hooks_file ]] && cmd+=(-H "$hooks_file") | ||
| "${cmd[@]}" || warn "Failed to link $pkg" | ||
| done | ||
| } | ||
| setup_alternates(){ | ||
| info "Processing yadm alternates..." | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,114 @@ | ||
| #!/usr/bin/env bash | ||
|
||
| # shellcheck enable=all shell=bash source-path=SCRIPTDIR | ||
| set -euo pipefail; shopt -s nullglob globstar | ||
| export LC_ALL=C; IFS=$'\n\t' | ||
| has(){ command -v -- "$1" &>/dev/null; } | ||
| info(){ printf '==> %s\n' "$*"; } | ||
| warn(){ printf '==> WARNING: %s\n' "$*"; } | ||
| die(){ printf '==> ERROR: %s\n' "$*" >&2; exit 1; } | ||
|
|
||
| # Get repository directory | ||
| get_repo_dir(){ | ||
| if yadm rev-parse --show-toplevel &>/dev/null; then | ||
| yadm rev-parse --show-toplevel | ||
| elif [[ -d "${HOME}/.local/share/yadm/repo.git" ]]; then | ||
| echo "${HOME}" | ||
| elif git rev-parse --show-toplevel &>/dev/null; then | ||
| git rev-parse --show-toplevel | ||
| else | ||
| die "Cannot determine repository location" | ||
| fi | ||
| } | ||
|
|
||
| usage(){ | ||
| cat <<'EOF' | ||
| deploy-system-configs - Deploy system configs using tuckr or stow | ||
|
|
||
| Usage: deploy-system-configs [OPTIONS] [PACKAGES...] | ||
|
|
||
| Options: | ||
| -h, --help Show this help | ||
| -d, --dir DIR Repository directory (auto-detected if omitted) | ||
| -u, --unlink Unlink/unstow packages instead of linking | ||
|
|
||
| Packages: | ||
| etc Deploy /etc configs | ||
| usr Deploy /usr configs | ||
| (default: etc usr) | ||
|
|
||
| This script automatically uses tuckr if available, otherwise falls back to stow. | ||
|
|
||
| Examples: | ||
| sudo deploy-system-configs # Deploy both etc and usr | ||
| sudo deploy-system-configs etc # Deploy only etc | ||
| sudo deploy-system-configs --unlink # Unlink all packages | ||
| EOF | ||
| } | ||
|
|
||
| REPO_DIR="" | ||
| UNLINK=false | ||
| PACKAGES=() | ||
|
|
||
| while [[ $# -gt 0 ]]; do | ||
| case "$1" in | ||
| -h|--help) usage; exit 0 ;; | ||
| -d|--dir) | ||
|
||
| if [[ -z ${2:-} ]]; then die "Option '$1' requires an argument."; fi | ||
| REPO_DIR="$2"; shift | ||
| ;; | ||
| -u|--unlink) UNLINK=true ;; | ||
| -*) die "Unknown option: $1" ;; | ||
| *) PACKAGES+=("$1") ;; | ||
| esac | ||
| shift | ||
| done | ||
Ven0m0 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| # Auto-detect repo dir if not provided | ||
| [[ -z $REPO_DIR ]] && REPO_DIR="$(get_repo_dir)" | ||
| [[ -d $REPO_DIR ]] || die "Repository not found: $REPO_DIR" | ||
|
|
||
| # Default to etc and usr if no packages specified | ||
| ((${#PACKAGES[@]} == 0)) && PACKAGES=(etc usr) | ||
|
|
||
| # Check if running as root | ||
| [[ $EUID -eq 0 ]] || die "This script must be run as root (use sudo)" | ||
|
|
||
| # Deploy using tuckr or stow | ||
|
||
| if has tuckr; then | ||
| info "Using tuckr for deployment" | ||
| local hooks_file="${REPO_DIR}/hooks.toml" | ||
|
||
| for pkg in "${PACKAGES[@]}"; do | ||
| local src="${REPO_DIR}/${pkg}" | ||
| [[ -d $src ]] || { warn "Directory not found: $src"; continue; } | ||
|
|
||
| if [[ $UNLINK == true ]]; then | ||
| info "Unlinking ${pkg}/" | ||
| tuckr unlink -d "$REPO_DIR" -t / "$pkg" || warn "Failed to unlink $pkg" | ||
| else | ||
| info "Linking ${pkg}/ → / (tuckr)" | ||
| local cmd=(tuckr link -d "$REPO_DIR" -t / "$pkg") | ||
|
Comment on lines
+81
to
+89
|
||
| [[ -f $hooks_file ]] && cmd+=(-H "$hooks_file") | ||
| "${cmd[@]}" || warn "Failed to link $pkg" | ||
|
Comment on lines
+79
to
+91
|
||
| fi | ||
| done | ||
| elif has stow; then | ||
|
Comment on lines
+78
to
+94
|
||
| info "Using stow for deployment (tuckr not available)" | ||
| for pkg in "${PACKAGES[@]}"; do | ||
| local src="${REPO_DIR}/${pkg}" | ||
|
||
| [[ -d $src ]] || { warn "Directory not found: $src"; continue; } | ||
|
|
||
| if [[ $UNLINK == true ]]; then | ||
| info "Unstowing ${pkg}/" | ||
| (cd "$REPO_DIR" && stow -t / -d . -D "$pkg") || warn "Failed to unstow $pkg" | ||
| else | ||
| info "Stowing ${pkg}/ → / (stow)" | ||
| (cd "$REPO_DIR" && stow -t / -d . "$pkg") || warn "Failed to stow $pkg" | ||
| fi | ||
| done | ||
| else | ||
| die "Neither tuckr nor stow is installed. Install one of them: | ||
| Arch: paru -S tuckr OR paru -S stow | ||
| Debian: apt install stow" | ||
| fi | ||
|
Comment on lines
+77
to
+112
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The script will fail at runtime because |
||
|
|
||
| info "Deployment complete" | ||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -8,8 +8,8 @@ clean, hierarchical folder structure. | |||||
| ``` | ||||||
| dotfiles/ | ||||||
| ├── Home/ # User-level dotfiles (~/.*) [Managed by yadm] | ||||||
| ├── etc/ # System configs (/etc/*) [Managed by tuckr] | ||||||
| ├── usr/ # System configs (/usr/*) [Managed by tuckr] | ||||||
| ├── etc/ # System configs (/etc/*) [Managed by tuckr/stow] | ||||||
| ├── usr/ # System configs (/usr/*) [Managed by tuckr/stow] | ||||||
| ├── .yadm/ # YADM configuration | ||||||
| │ ├── bootstrap # Main bootstrap script | ||||||
| │ └── config # Repository-wide yadm config | ||||||
|
|
@@ -20,9 +20,10 @@ dotfiles/ | |||||
|
|
||||||
| - **Separation of concerns**: User configs vs. system configs | ||||||
| - **Easy to understand**: Mirrors Linux filesystem structure | ||||||
| - **Flexible deployment**: yadm for user files, tuckr for system files | ||||||
| - **Flexible deployment**: yadm for user files, tuckr/stow for system files | ||||||
| - **Git-friendly**: Clean repository with minimal clutter | ||||||
| - **Portable**: Works across different systems | ||||||
| - **Fallback support**: Automatically uses stow if tuckr is unavailable | ||||||
|
|
||||||
| --- | ||||||
|
|
||||||
|
|
@@ -169,7 +170,7 @@ yadm push | |||||
|
|
||||||
| ### Update System Configs (etc/, usr/) | ||||||
|
|
||||||
| System configs are managed separately with **tuckr**: | ||||||
| System configs are managed separately with **tuckr** (or **stow** as fallback): | ||||||
|
|
||||||
| ```bash | ||||||
| # Navigate to repository | ||||||
|
|
@@ -184,8 +185,14 @@ git commit -m "Update pacman configuration" | |||||
| git push | ||||||
|
|
||||||
| # Re-link system configs (creates symlinks) | ||||||
| sudo tuckr link -d $(yadm rev-parse --show-toplevel) -t / etc | ||||||
| sudo tuckr link -d $(yadm rev-parse --show-toplevel) -t / usr | ||||||
| # Option 1: Using tuckr (preferred) | ||||||
| sudo tuckr link -d $(yadm rev-parse --show-toplevel) -t / etc usr | ||||||
|
|
||||||
| # Option 2: Using stow (fallback) | ||||||
| cd $(yadm rev-parse --show-toplevel) && sudo stow -t / etc usr | ||||||
|
||||||
| cd $(yadm rev-parse --show-toplevel) && sudo stow -t / etc usr | |
| sudo stow -t / etc usr |
Copilot
AI
Dec 29, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Inconsistent capitalization of tool name. The heading uses "Tuckr" with capital T, but throughout the rest of the documentation, the tool name is consistently lowercase "tuckr". The heading should be "System Configs with tuckr or stow" for consistency.
| ### System Configs with Tuckr or Stow | |
| ### System Configs with tuckr or stow |
Copilot
AI
Dec 29, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The stow command is missing the -d . argument. According to stow documentation and the pattern used elsewhere in the codebase, the command should be cd /path/to/repo && sudo stow -t / -d . etc. The -d . explicitly specifies the stow directory (current directory after cd).
| cd /path/to/repo && sudo stow -t / etc | |
| cd /path/to/repo && sudo stow -t / -d . etc |
Copilot
AI
Dec 29, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The stow command is missing the -d . argument. According to stow documentation and the pattern used elsewhere in the codebase, the command should be sudo stow -t / -d . etc usr. The -d . explicitly specifies the stow directory (current directory).
| sudo stow -t / etc usr | |
| sudo stow -t / -d . etc usr |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -48,15 +48,19 @@ main(){ | |
| install_packages(){ | ||
| info "Installing packages..." | ||
| local paru_opts=(--needed --noconfirm --skipreview --sudoloop --batchinstall --combinedupgrade) | ||
| local pkgs=(git gitoxide aria2 curl zsh fd sd ripgrep bat jq zoxide starship fzf yadm tuckr konsave) | ||
| local pkgs=(git gitoxide aria2 curl zsh fd sd ripgrep bat jq zoxide starship fzf yadm konsave) | ||
| if ! has paru; then | ||
| die "paru not found." | ||
| fi | ||
| if [[ $DRY_RUN == true ]]; then | ||
| info "[DRY-RUN] Would install: ${pkgs[*]}" | ||
| info "[DRY-RUN] Would install: ${pkgs[*]} tuckr (or stow)" | ||
| return 0 | ||
| fi | ||
| paru -Syuq "${paru_opts[@]}" "${pkgs[@]}" || die "Failed to install packages" | ||
| # Try installing with tuckr first | ||
| if ! paru -Syuq "${paru_opts[@]}" "${pkgs[@]}" tuckr; then | ||
| warn "tuckr install failed, using stow as fallback" | ||
| paru -Syuq "${paru_opts[@]}" "${pkgs[@]}" stow || die "Failed to install packages" | ||
| fi | ||
| } | ||
| setup_dotfiles(){ | ||
| if ! has yadm; then | ||
|
|
@@ -83,23 +87,39 @@ deploy_home(){ | |
| fi | ||
| } | ||
| link_system_configs(){ | ||
| if ! has tuckr; then | ||
| warn "tuckr not found; skipping etc/usr deploy" | ||
| local pkg | ||
| if has tuckr; then | ||
| info "Using tuckr for system config deployment" | ||
| local hooks_file="${WORKTREE}/hooks.toml" | ||
| for pkg in etc usr; do | ||
| local src="${WORKTREE}/${pkg}" | ||
| [[ -d $src ]] || { warn "Directory not found: $src"; continue; } | ||
| info "Linking ${pkg}/ → / (tuckr)" | ||
| local cmd=(sudo tuckr link -d "$WORKTREE" -t / "$pkg") | ||
| [[ -f $hooks_file ]] && cmd+=(-H "$hooks_file") | ||
| "${cmd[@]}" || warn "Failed to link ${pkg}" | ||
| done | ||
| elif has stow; then | ||
| info "tuckr not found, using stow as fallback" | ||
| for pkg in etc usr; do | ||
| local src="${WORKTREE}/${pkg}" | ||
| [[ -d $src ]] || { warn "Directory not found: $src"; continue; } | ||
| info "Linking ${pkg}/ → / (stow)" | ||
| (cd "$WORKTREE" && sudo stow -t / -d . "$pkg") || warn "Failed to stow ${pkg}" | ||
|
||
| done | ||
| else | ||
| warn "Neither tuckr nor stow found; skipping etc/usr deploy" | ||
| warn "Install with: paru -S tuckr OR paru -S stow" | ||
| return 0 | ||
| fi | ||
| local hooks_file="${WORKTREE}/hooks.toml" pkg | ||
| for pkg in etc usr; do | ||
| local src="${WORKTREE}/${pkg}" | ||
| [[ -d $src ]] || { warn "Directory not found: $src"; continue; } | ||
| info "Linking ${pkg}/ → /" | ||
| local cmd=(sudo tuckr link -d "$WORKTREE" -t / "$pkg") | ||
| [[ -f $hooks_file ]] && cmd+=(-H "$hooks_file") | ||
| "${cmd[@]}" || warn "Failed to link ${pkg}" | ||
| done | ||
| } | ||
|
Comment on lines
89
to
115
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
| final_steps(){ | ||
| info "Run 'yadm status' to review." | ||
| info "For system configs: sudo tuckr link -d $WORKTREE -t / etc usr" | ||
| if has tuckr; then | ||
| info "For system configs: sudo tuckr link -d $WORKTREE -t / etc usr" | ||
| elif has stow; then | ||
| info "For system configs: cd $WORKTREE && sudo stow -t / etc usr" | ||
| fi | ||
| info "Validate /etc/fstab with: sudo systemd-analyze verify /etc/fstab" | ||
| info "Setup complete." | ||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| # This directory is managed by tuckr and deployed to /usr |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The stow command uses different syntax in different places. Here it uses
stow -t / -d . "$pkg"with individual package names, but in YADM.md line 192 and 400 it showssudo stow -t / etc usr(multiple packages at once). For consistency and efficiency, the documentation pattern should be followed:sudo stow -t / -d . etc usrto deploy both packages in a single command.