aylurs-gtk-shell-git provides aylurs-gtk-shell, but pacman -Qi only matches exact package names. This caused the installer to think ags was missing and try to install aylurs-gtk-shell from AUR, which conflicts with the already-installed -git variant. Now uses expac (fast) or pacman loop (fallback) to check if any installed package provides the requested virtual package name.
327 lines
8.2 KiB
Bash
Executable File
327 lines
8.2 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
|
|
require() {
|
|
local cmd="$1"
|
|
local pkg="${2:-$1}"
|
|
|
|
if ! command -v "$cmd" >/dev/null 2>&1; then
|
|
log_error "Required command '$cmd' not found. Install with: sudo pacman -S $pkg"
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
require_optional() {
|
|
local cmd="$1"
|
|
local pkg="${2:-$1}"
|
|
|
|
if ! command -v "$cmd" >/dev/null 2>&1; then
|
|
log_warn "'$cmd' not found. Install with: sudo pacman -S $pkg"
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
have() {
|
|
command -v "$1" >/dev/null 2>&1
|
|
}
|
|
|
|
is_arch() {
|
|
[[ -f /etc/arch-release ]] || [[ -d /etc/pacman.d ]]
|
|
}
|
|
|
|
is_root() {
|
|
[[ "$EUID" -eq 0 ]]
|
|
}
|
|
|
|
sudo_run() {
|
|
if is_root; then
|
|
"$@"
|
|
else
|
|
sudo "$@"
|
|
fi
|
|
}
|
|
|
|
backup_file() {
|
|
local target="$1"
|
|
local backup_dir="${2:-$HOME/.dotfiles-backup/$(date +%Y%m%d-%H%M%S)}"
|
|
local relative="${target#"$HOME"/}"
|
|
local backup="$backup_dir/$relative"
|
|
|
|
[[ -e "$target" || -L "$target" ]] || return 0
|
|
|
|
mkdir -p "$(dirname "$backup")"
|
|
cp -a "$target" "$backup"
|
|
log_info "Backed up $target -> $backup"
|
|
printf '%s' "$backup_dir"
|
|
}
|
|
|
|
symlink_path() {
|
|
local source="$1"
|
|
local target="$2"
|
|
|
|
backup_file "$target"
|
|
rm -rf "$target"
|
|
mkdir -p "$(dirname "$target")"
|
|
ln -sfn "$source" "$target"
|
|
log_info "Linked $source -> $target"
|
|
}
|
|
|
|
copy_path() {
|
|
local source="$1"
|
|
local target="$2"
|
|
|
|
backup_file "$target"
|
|
rm -rf "$target"
|
|
mkdir -p "$(dirname "$target")"
|
|
cp -a "$source" "$target"
|
|
log_info "Copied $source -> $target"
|
|
}
|
|
|
|
platform_packages() {
|
|
if is_arch; then
|
|
printf '%s\n' "arch"
|
|
fi
|
|
if [[ -f /etc/os-release ]]; then
|
|
local id
|
|
id="$(grep -oP '^ID=\K.*' /etc/os-release)"
|
|
printf '%s\n' "$id"
|
|
fi
|
|
}
|
|
|
|
is_package_installed() {
|
|
local pkg="$1"
|
|
|
|
if command -v pacman >/dev/null 2>&1; then
|
|
pacman -Qi "$pkg" >/dev/null 2>&1 && return 0
|
|
if command -v expac >/dev/null 2>&1; then
|
|
expac -Q '%n %P' 2>/dev/null | awk -v pkg="$pkg" '
|
|
{ for (i=2; i<=NF; i++) if ($i == pkg) {found=1; exit} }
|
|
END {exit !found}
|
|
' && return 0
|
|
else
|
|
while IFS= read -r installed; do
|
|
[[ -z "$installed" ]] && continue
|
|
pacman -Qi "$installed" 2>/dev/null | grep -qP "Provides\s*:\s*.*\b${pkg}\b" && return 0
|
|
done < <(pacman -Qq 2>/dev/null)
|
|
fi
|
|
return 1
|
|
fi
|
|
|
|
return 1
|
|
}
|
|
|
|
install_pacman() {
|
|
local packages=("$@")
|
|
local to_install=()
|
|
local pkg
|
|
|
|
for pkg in "${packages[@]}"; do
|
|
if ! pacman -Si "$pkg" >/dev/null 2>&1; then
|
|
log_warn "Package '$pkg' not found in pacman repositories"
|
|
continue
|
|
fi
|
|
if ! is_package_installed "$pkg"; then
|
|
to_install+=("$pkg")
|
|
fi
|
|
done
|
|
|
|
if ((${#to_install[@]})); then
|
|
log_info "Installing: ${to_install[*]}"
|
|
sudo_run pacman -S --needed --noconfirm "${to_install[@]}"
|
|
else
|
|
log_info "All packages already installed"
|
|
fi
|
|
}
|
|
|
|
install_aur() {
|
|
local packages=("$@")
|
|
local aur_helper=""
|
|
|
|
if have paru; then
|
|
aur_helper="paru"
|
|
elif have yay; then
|
|
aur_helper="yay"
|
|
else
|
|
log_error "No AUR helper found (install paru or yay)"
|
|
return 1
|
|
fi
|
|
|
|
local to_install=()
|
|
local pkg
|
|
|
|
for pkg in "${packages[@]}"; do
|
|
if ! is_package_installed "$pkg"; then
|
|
to_install+=("$pkg")
|
|
fi
|
|
done
|
|
|
|
if ((${#to_install[@]})); then
|
|
log_info "Installing from AUR: ${to_install[*]}"
|
|
"$aur_helper" -S --needed --noconfirm "${to_install[@]}"
|
|
else
|
|
log_info "All AUR packages already installed"
|
|
fi
|
|
}
|
|
|
|
replace_home_paths() {
|
|
local dir="$1"
|
|
local original_home="${2:-/home/pascal}"
|
|
|
|
if [[ "$original_home" == "$HOME" ]]; then
|
|
return 0
|
|
fi
|
|
|
|
find "$dir" -type f -exec sed -i "s#${original_home}#${HOME}#g" {} + 2>/dev/null || true
|
|
log_info "Rewrote home paths in $dir"
|
|
}
|
|
|
|
detect_gpu() {
|
|
if ! command -v lspci >/dev/null 2>&1; then
|
|
if have pacman; then
|
|
sudo_run pacman -S --needed --noconfirm pciutils >/dev/null 2>&1 || true
|
|
fi
|
|
fi
|
|
|
|
local gpu_info
|
|
gpu_info="$(lspci -nn 2>/dev/null | grep -E '\[0300\]|\[0302\]|\[0380\]' || true)"
|
|
[[ -z "$gpu_info" ]] && gpu_info="$(lspci -nn 2>/dev/null | grep -iE '(VGA|3D|Display).*controller' || true)"
|
|
|
|
if printf '%s' "$gpu_info" | grep -qi "\[10de:"; then
|
|
printf 'nvidia'
|
|
elif printf '%s' "$gpu_info" | grep -qi "\[1002:\|\[1022:"; then
|
|
printf 'amd'
|
|
elif printf '%s' "$gpu_info" | grep -qi "\[8086:"; then
|
|
printf 'intel'
|
|
elif printf '%s' "$gpu_info" | grep -qi "vmware\|qemu\|virtualbox\|virtio"; then
|
|
printf 'vm'
|
|
elif printf '%s' "$gpu_info" | grep -qi "nvidia"; then
|
|
printf 'nvidia'
|
|
elif printf '%s' "$gpu_info" | grep -qi "amd\|advanced micro devices"; then
|
|
printf 'amd'
|
|
elif printf '%s' "$gpu_info" | grep -qi "intel"; then
|
|
printf 'intel'
|
|
else
|
|
printf 'unknown'
|
|
fi
|
|
}
|
|
|
|
gpu_packages() {
|
|
local gpu_type
|
|
gpu_type="$(detect_gpu)"
|
|
|
|
case "$gpu_type" in
|
|
intel)
|
|
printf '%s\n' "xf86-video-intel" "vulkan-intel" "intel-media-driver" "libva-intel-driver"
|
|
;;
|
|
amd)
|
|
printf '%s\n' "xf86-video-amdgpu" "vulkan-radeon" "libva-mesa-driver" "mesa-vdpau"
|
|
;;
|
|
nvidia)
|
|
printf '%s\n' "nvidia-dkms" "nvidia-utils" "nvidia-settings" "libva-nvidia-driver" "vulkan-tools"
|
|
;;
|
|
vm)
|
|
printf '%s\n' "xf86-video-vmware" "mesa" "vulkan-swrast"
|
|
;;
|
|
*)
|
|
printf '%s\n' "mesa" "vulkan-swrast"
|
|
;;
|
|
esac
|
|
}
|
|
|
|
is_fresh_install() {
|
|
have hyprctl && return 1
|
|
|
|
if have hyprland; then
|
|
hyprland --version >/dev/null 2>&1 && return 1
|
|
fi
|
|
|
|
if [[ -n "${WAYLAND_DISPLAY:-}" || -n "${DISPLAY:-}" ]]; then
|
|
return 1
|
|
fi
|
|
|
|
return 0
|
|
}
|
|
|
|
count_missing_packages() {
|
|
local packages=("$@")
|
|
local missing=0
|
|
local pkg
|
|
|
|
for pkg in "${packages[@]}"; do
|
|
if ! is_package_installed "$pkg"; then
|
|
((missing++))
|
|
fi
|
|
done
|
|
|
|
printf '%d' "$missing"
|
|
}
|
|
|
|
system_summary() {
|
|
local gpu
|
|
gpu="$(detect_gpu)"
|
|
|
|
cat <<SUMMARY
|
|
┌─────────────────────────────────────────────┐
|
|
│ System Summary │
|
|
├─────────────────────────────────────────────┤
|
|
│ OS: $(grep -oP '^PRETTY_NAME="?\K[^"\n]+' /etc/os-release 2>/dev/null | sed 's/"$//' || echo "Arch Linux")
|
|
│ Kernel: $(uname -r)
|
|
│ GPU: ${gpu} ($(lspci -nn 2>/dev/null | grep -E '\[0300\]|\[0302\]|\[0380\]' | sed 's/.*: //' | head -1 || echo "unknown"))
|
|
│ Session: $(printenv XDG_SESSION_TYPE || echo "none (TTY)")
|
|
│ Hyprland: $(have hyprctl && echo "installed" || echo "NOT installed")
|
|
│ AUR: $(have paru && echo "paru" || (have yay && echo "yay" || echo "none"))
|
|
└─────────────────────────────────────────────┘
|
|
SUMMARY
|
|
}
|
|
|
|
install_aur_helper() {
|
|
if have paru || have yay; then
|
|
return 0
|
|
fi
|
|
|
|
if is_root; then
|
|
tui_warn "Running as root — makepkg refuses to run as root."
|
|
tui_info "Switch to a normal user with sudo access and re-run, or install paru manually:"
|
|
tui_info " pacman -S --needed git && git clone https://aur.archlinux.org/paru-bin.git"
|
|
tui_info " cd paru-bin && makepkg -si"
|
|
return 1
|
|
fi
|
|
|
|
command -v git >/dev/null 2>&1 || sudo_run pacman -S --needed --noconfirm git
|
|
sudo_run pacman -S --needed --noconfirm base-devel
|
|
|
|
local build_dir
|
|
build_dir="$(mktemp -d)"
|
|
|
|
tui_info "Downloading paru-bin from AUR..."
|
|
if ! git clone https://aur.archlinux.org/paru-bin.git "$build_dir/paru-bin"; then
|
|
tui_error "Failed to download paru-bin. Check network connectivity."
|
|
rm -rf "$build_dir"
|
|
return 1
|
|
fi
|
|
|
|
tui_info "Building paru-bin with makepkg..."
|
|
if (cd "$build_dir/paru-bin" && makepkg -si --needed --noconfirm); then
|
|
tui_success "paru installed successfully"
|
|
rm -rf "$build_dir"
|
|
return 0
|
|
fi
|
|
|
|
local rc=$?
|
|
tui_warn "makepkg failed (exit $rc). Trying yay-bin..."
|
|
rm -rf "$build_dir/paru-bin"
|
|
|
|
if git clone https://aur.archlinux.org/yay-bin.git "$build_dir/yay-bin"; then
|
|
if (cd "$build_dir/yay-bin" && makepkg -si --needed --noconfirm); then
|
|
tui_success "yay installed successfully"
|
|
rm -rf "$build_dir"
|
|
return 0
|
|
fi
|
|
fi
|
|
|
|
tui_warn "Could not install AUR helper. Install manually:"
|
|
tui_info " cd /tmp && git clone https://aur.archlinux.org/paru-bin.git"
|
|
tui_info " cd paru-bin && makepkg -si"
|
|
rm -rf "$build_dir"
|
|
return 1
|
|
}
|