feat(install): rewrite install.sh with interactive mode selection
- 3 install modes: Full, Minimal, Custom (pick categories) - Dry-run flag (-n) to preview packages without installing - Progress bar with percentage during package install - Better visual hierarchy with section headers and dividers - Package categories: Core, Shell, Hyprland, UI, Hardware, Network, Audio, Build - Failed package summary at end - Cleaner banner and completion output
This commit is contained in:
1 file changed
+284
-186
+284
-186
@@ -10,104 +10,156 @@
|
||||
# A hackable shell for Hyprland
|
||||
# Installation Script for Arch Linux
|
||||
#
|
||||
# Repository: https://github.com/S4NKALP/Modus --branch macos
|
||||
# Repository: https://github.com/S4NKALP/Modus
|
||||
# License: GPLv3
|
||||
|
||||
set -e
|
||||
set -u
|
||||
set -o pipefail
|
||||
|
||||
# ── CLI flags ──────────────────────────────────────────────────────
|
||||
AUTO_YES=false
|
||||
DRY_RUN=false
|
||||
MINIMAL=false
|
||||
for arg in "$@"; do
|
||||
case "$arg" in
|
||||
-y|--yes) AUTO_YES=true ;;
|
||||
-y|--yes) AUTO_YES=true ;;
|
||||
-n|--dry-run) DRY_RUN=true ;;
|
||||
-m|--minimal) MINIMAL=true ;;
|
||||
-h|--help)
|
||||
echo "Usage: install.sh [OPTIONS]"
|
||||
echo ""
|
||||
echo "Options:"
|
||||
echo " -y, --yes Skip all prompts"
|
||||
echo " -n, --dry-run Show what would be installed without installing"
|
||||
echo " -m, --minimal Install only core packages"
|
||||
echo " -h, --help Show this help"
|
||||
exit 0
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
REPO_URL="https://github.com/S4NKALP/Modus.git"
|
||||
INSTALL_DIR="$HOME/.config/Modus"
|
||||
|
||||
PACKAGES=(
|
||||
# ── Package definitions ────────────────────────────────────────────
|
||||
CORE_PACKAGES=(
|
||||
uv
|
||||
fabric-cli-git
|
||||
uwsm
|
||||
)
|
||||
|
||||
SHELL_PACKAGES=(
|
||||
cliphist
|
||||
gnome-bluetooth-3.0
|
||||
slurp
|
||||
ffmpeg
|
||||
grim
|
||||
swappy
|
||||
wl-clipboard
|
||||
wtype
|
||||
libnotify
|
||||
playerctl
|
||||
matugen-bin
|
||||
)
|
||||
|
||||
HYPRLAND_PACKAGES=(
|
||||
hypridle
|
||||
hyprsunset
|
||||
hyprpicker
|
||||
hyprshot
|
||||
grim
|
||||
libnotify
|
||||
matugen-bin
|
||||
playerctl
|
||||
gtk-session-lock
|
||||
)
|
||||
|
||||
UI_PACKAGES=(
|
||||
awww
|
||||
apple-fonts
|
||||
swappy
|
||||
wl-clipboard
|
||||
webp-pixbuf-loader
|
||||
wf-recorder
|
||||
cinnamon-desktop
|
||||
libmediaart
|
||||
)
|
||||
|
||||
HARDWARE_PACKAGES=(
|
||||
acpi
|
||||
brightnessctl
|
||||
power-profiles-daemon
|
||||
uwsm
|
||||
cinnamon-desktop
|
||||
ddcutil
|
||||
at-spi2-core
|
||||
gcc
|
||||
make
|
||||
pkgconf
|
||||
appmenu-gtk-module
|
||||
libdbusmenu-gtk3
|
||||
libdbusmenu-qt5
|
||||
meson
|
||||
ninja
|
||||
wayland-protocols
|
||||
libmediaart
|
||||
)
|
||||
|
||||
NETWORK_PACKAGES=(
|
||||
networkmanager
|
||||
network-manager-applet
|
||||
blueman
|
||||
libqalculate
|
||||
wtype
|
||||
pipewire
|
||||
libpulse
|
||||
pciutils
|
||||
gtk-layer-shell
|
||||
librsvg
|
||||
gobject-introspection
|
||||
)
|
||||
|
||||
# Colors and formatting
|
||||
AUDIO_PACKAGES=(
|
||||
pipewire
|
||||
libpulse
|
||||
)
|
||||
|
||||
BUILD_PACKAGES=(
|
||||
gcc
|
||||
make
|
||||
pkgconf
|
||||
meson
|
||||
ninja
|
||||
wayland-protocols
|
||||
gobject-introspection
|
||||
gtk-layer-shell
|
||||
librsvg
|
||||
libqalculate
|
||||
appmenu-gtk-module
|
||||
libdbusmenu-gtk3
|
||||
libdbusmenu-qt5
|
||||
pciutils
|
||||
wf-recorder
|
||||
ffmpeg
|
||||
)
|
||||
|
||||
ALL_PACKAGES=(
|
||||
"${CORE_PACKAGES[@]}"
|
||||
"${SHELL_PACKAGES[@]}"
|
||||
"${HYPRLAND_PACKAGES[@]}"
|
||||
"${UI_PACKAGES[@]}"
|
||||
"${HARDWARE_PACKAGES[@]}"
|
||||
"${NETWORK_PACKAGES[@]}"
|
||||
"${AUDIO_PACKAGES[@]}"
|
||||
"${BUILD_PACKAGES[@]}"
|
||||
)
|
||||
|
||||
# ── Colors ─────────────────────────────────────────────────────────
|
||||
if [ -t 1 ]; then
|
||||
GREEN=$(tput setaf 2)
|
||||
YELLOW=$(tput setaf 3)
|
||||
RED=$(tput setaf 1)
|
||||
CYAN=$(tput setaf 6)
|
||||
BLUE=$(tput setaf 4)
|
||||
MAGENTA=$(tput setaf 5)
|
||||
BOLD=$(tput bold)
|
||||
DIM=$(tput dim)
|
||||
RESET=$(tput sgr0)
|
||||
else
|
||||
GREEN="" YELLOW="" RED="" CYAN="" BLUE="" BOLD="" DIM="" RESET=""
|
||||
GREEN="" YELLOW="" RED="" CYAN="" BLUE="" MAGENTA="" BOLD="" DIM="" RESET=""
|
||||
fi
|
||||
|
||||
# Status symbols
|
||||
ARROW="→"
|
||||
CHECK="✔"
|
||||
CROSS="✖"
|
||||
INFO="ℹ"
|
||||
WARN="⚠"
|
||||
BULLET="•"
|
||||
|
||||
# Progress tracking
|
||||
TOTAL_STEPS=12
|
||||
CURRENT_STEP=0
|
||||
# ── Helpers ────────────────────────────────────────────────────────
|
||||
header() {
|
||||
echo ""
|
||||
echo -e " ${BOLD}${CYAN}╔══════════════════════════════════════════════╗${RESET}"
|
||||
echo -e " ${BOLD}${CYAN}║${RESET} ${BOLD}Modus Installer${RESET} ${DIM}v2.0${RESET} ${BOLD}${CYAN}║${RESET}"
|
||||
echo -e " ${BOLD}${CYAN}╚══════════════════════════════════════════════╝${RESET}"
|
||||
echo ""
|
||||
}
|
||||
|
||||
# Function for progress indicator
|
||||
progress() {
|
||||
CURRENT_STEP=$((CURRENT_STEP + 1))
|
||||
echo -e "\n${BOLD}${BLUE}[${CURRENT_STEP}/${TOTAL_STEPS}]${RESET} ${BOLD}$1${RESET}"
|
||||
section() {
|
||||
echo ""
|
||||
echo -e " ${BOLD}${MAGENTA}── $1 ──${RESET}"
|
||||
}
|
||||
|
||||
step() {
|
||||
@@ -123,13 +175,33 @@ warn() {
|
||||
}
|
||||
|
||||
error() {
|
||||
echo -e "\n${RED}${CROSS}${RESET} ${RED}${BOLD}ERROR:${RESET} ${RED}$1${RESET}\n" >&2
|
||||
echo -e " ${RED}${CROSS}${RESET} ${RED}$1${RESET}"
|
||||
}
|
||||
|
||||
info() {
|
||||
echo -e " ${BLUE}${INFO}${RESET} ${DIM}$1${RESET}"
|
||||
}
|
||||
|
||||
divider() {
|
||||
echo -e " ${DIM}──────────────────────────────────────────────${RESET}"
|
||||
}
|
||||
|
||||
confirm() {
|
||||
local prompt="$1"
|
||||
local default="${2:-n}"
|
||||
local yn
|
||||
if [ "$AUTO_YES" = true ]; then
|
||||
return 0
|
||||
fi
|
||||
if [ "$default" = "y" ]; then
|
||||
read -rp " ${BOLD}${prompt} [Y/n]:${RESET} " yn
|
||||
[[ ! "$yn" =~ ^[Nn]$ ]]
|
||||
else
|
||||
read -rp " ${BOLD}${prompt} [y/N]:${RESET} " yn
|
||||
[[ "$yn" =~ ^[Yy]$ ]]
|
||||
fi
|
||||
}
|
||||
|
||||
spinner() {
|
||||
local pid=$1
|
||||
local message=$2
|
||||
@@ -141,34 +213,36 @@ spinner() {
|
||||
i=$(((i + 1) % 10))
|
||||
sleep 0.1
|
||||
done
|
||||
printf "\r"
|
||||
printf "\r %b%s%b %s\n" "$GREEN" "${CHECK}" "$RESET" "$message"
|
||||
}
|
||||
|
||||
# Cleanup handler
|
||||
print_packages() {
|
||||
local -n pkgs=$1
|
||||
local count=${#pkgs[@]}
|
||||
echo -e " ${DIM}${BULLET}${RESET} ${BOLD}$2${RESET} ${DIM}(${count} packages)${RESET}"
|
||||
for pkg in "${pkgs[@]}"; do
|
||||
echo -e " ${DIM}${BULLET}${RESET} ${pkg}"
|
||||
done
|
||||
}
|
||||
|
||||
# ── Cleanup ────────────────────────────────────────────────────────
|
||||
cleanup() {
|
||||
if [ -n "${SUDO_KEEPER_PID:-}" ]; then
|
||||
kill $SUDO_KEEPER_PID 2>/dev/null || true
|
||||
kill "$SUDO_KEEPER_PID" 2>/dev/null || true
|
||||
fi
|
||||
}
|
||||
trap cleanup EXIT INT TERM
|
||||
|
||||
# Header
|
||||
# ── Banner ─────────────────────────────────────────────────────────
|
||||
clear
|
||||
echo -e "${BOLD}${CYAN}"
|
||||
cat << "EOF"
|
||||
███╗ ███╗ ██████╗ ██████╗ ██╗ ██╗███████╗
|
||||
████╗ ████║██╔═══██╗██╔══██╗██║ ██║██╔════╝
|
||||
██╔████╔██║██║ ██║██║ ██║██║ ██║███████╗
|
||||
██║╚██╔╝██║██║ ██║██║ ██║██║ ██║╚════██║
|
||||
██║ ╚═╝ ██║╚██████╔╝██████╔╝╚██████╔╝███████║
|
||||
╚═╝ ╚═╝ ╚═════╝ ╚═════╝ ╚═════╝ ╚══════╝
|
||||
EOF
|
||||
echo -e "${RESET}"
|
||||
echo -e "${BOLD} A hackable shell for Hyprland${RESET}"
|
||||
echo -e "${DIM} Installation Script v1.0${RESET}\n"
|
||||
header
|
||||
|
||||
# Pre-flight checks
|
||||
progress "Pre-flight checks"
|
||||
echo -e " ${BOLD}A hackable shell for Hyprland${RESET}"
|
||||
echo -e " ${DIM}https://github.com/S4NKALP/Modus${RESET}"
|
||||
echo ""
|
||||
|
||||
# ── Pre-flight checks ─────────────────────────────────────────────
|
||||
section "Pre-flight checks"
|
||||
|
||||
step "Checking operating system..."
|
||||
if ! grep -qi "arch" /etc/os-release; then
|
||||
@@ -184,25 +258,68 @@ if [ "$(id -u)" -eq 0 ]; then
|
||||
fi
|
||||
success "Running as regular user"
|
||||
|
||||
step "Checking system requirements..."
|
||||
step "Checking git..."
|
||||
if ! command -v git &>/dev/null; then
|
||||
error "git is not installed. Please install it first: sudo pacman -S git"
|
||||
error "git is not installed. Run: sudo pacman -S git"
|
||||
exit 1
|
||||
fi
|
||||
success "All requirements met"
|
||||
success "git found"
|
||||
|
||||
# Sudo authentication
|
||||
progress "Requesting permissions"
|
||||
# ── Install mode selection ────────────────────────────────────────
|
||||
section "Install mode"
|
||||
|
||||
info "Some packages require root privileges for installation"
|
||||
echo ""
|
||||
if ! sudo -v; then
|
||||
if [ "$MINIMAL" = true ]; then
|
||||
PACKAGES=("${CORE_PACKAGES[@]}")
|
||||
info "Minimal mode: ${#PACKAGES[@]} core packages only"
|
||||
elif [ "$AUTO_YES" = true ]; then
|
||||
PACKAGES=("${ALL_PACKAGES[@]}")
|
||||
info "Full install: ${#PACKAGES[@]} packages"
|
||||
else
|
||||
echo -e " ${BOLD}Choose install mode:${RESET}"
|
||||
echo ""
|
||||
echo -e " ${GREEN}${ARROW}${RESET} ${BOLD}1) Full${RESET} ${DIM}— everything (${#ALL_PACKAGES[@]} packages)${RESET}"
|
||||
echo -e " ${YELLOW}${ARROW}${RESET} ${BOLD}2) Minimal${RESET} ${DIM}— core only (${#CORE_PACKAGES[@]} packages)${RESET}"
|
||||
echo -e " ${CYAN}${ARROW}${RESET} ${BOLD}3) Custom${RESET} ${DIM}— pick categories${RESET}"
|
||||
echo ""
|
||||
read -rp " ${BOLD}Select [1-3]:${RESET} " mode_choice
|
||||
|
||||
case "$mode_choice" in
|
||||
2)
|
||||
PACKAGES=("${CORE_PACKAGES[@]}")
|
||||
;;
|
||||
3)
|
||||
PACKAGES=("${CORE_PACKAGES[@]}")
|
||||
echo ""
|
||||
for cat in "SHELL:Shell tools" "HYPRLAND:Hyprland extras" "UI:Desktop widgets" "HARDWARE:Hardware control" "NETWORK:Bluetooth & network" "AUDIO:Audio" "BUILD:Build tools"; do
|
||||
local_name="${cat%%:*}"
|
||||
local_label="${cat#*:}"
|
||||
local_ref="${local_name}_PACKAGES[@]"
|
||||
local_count="${#${!local_ref}}"
|
||||
if confirm "${local_label} (${local_count} packages)?" "y"; then
|
||||
PACKAGES+=("${!local_ref}")
|
||||
fi
|
||||
done
|
||||
;;
|
||||
*)
|
||||
PACKAGES=("${ALL_PACKAGES[@]}")
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
divider
|
||||
echo -e " ${BOLD}Will install ${GREEN}${#PACKAGES[@]}${RESET}${BOLD} packages${RESET}"
|
||||
divider
|
||||
|
||||
# ── Sudo ───────────────────────────────────────────────────────────
|
||||
section "Permissions"
|
||||
|
||||
info "Some packages require root privileges"
|
||||
if ! sudo -v 2>/dev/null; then
|
||||
error "Sudo authentication failed"
|
||||
exit 1
|
||||
fi
|
||||
success "Permissions granted"
|
||||
success "Sudo authenticated"
|
||||
|
||||
# Keep sudo alive
|
||||
while true; do
|
||||
sudo -n true
|
||||
sleep 60
|
||||
@@ -210,65 +327,62 @@ while true; do
|
||||
done 2>/dev/null &
|
||||
SUDO_KEEPER_PID=$!
|
||||
|
||||
# Show package list
|
||||
progress "Package information"
|
||||
# ── Show package list ─────────────────────────────────────────────
|
||||
section "Packages"
|
||||
|
||||
info "Total packages to install: ${BOLD}${#PACKAGES[@]}${RESET}"
|
||||
echo ""
|
||||
if [ "$AUTO_YES" = false ]; then
|
||||
read -rp " ${YELLOW}${INFO}${RESET} View full package list? (y/N): " view_packages
|
||||
else
|
||||
view_packages="n"
|
||||
fi
|
||||
if [[ "$view_packages" =~ ^[Yy]$ ]]; then
|
||||
if [ "$DRY_RUN" = true ]; then
|
||||
echo ""
|
||||
printf " ${DIM}• %s${RESET}\n" "${PACKAGES[@]}"
|
||||
printf " ${DIM}%s${RESET}\n" "${PACKAGES[@]}"
|
||||
echo ""
|
||||
fi
|
||||
|
||||
# Confirmation
|
||||
if [ "$AUTO_YES" = false ]; then
|
||||
read -rp " ${BOLD}Proceed with installation? (y/N):${RESET} " confirm
|
||||
else
|
||||
confirm="y"
|
||||
fi
|
||||
if [[ ! "$confirm" =~ ^[Yy]$ ]]; then
|
||||
warn "Installation cancelled by user"
|
||||
info "Dry run — no packages will be installed"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# AUR helper setup
|
||||
progress "Setting up AUR helper"
|
||||
if confirm "View full package list?"; then
|
||||
echo ""
|
||||
printf " ${DIM}${BULLET} %s${RESET}\n" "${PACKAGES[@]}"
|
||||
echo ""
|
||||
fi
|
||||
|
||||
aur_helper="yay"
|
||||
if ! confirm "Proceed with installation?"; then
|
||||
warn "Cancelled"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# ── AUR helper ─────────────────────────────────────────────────────
|
||||
section "AUR helper"
|
||||
|
||||
AUR=""
|
||||
if command -v paru &>/dev/null; then
|
||||
aur_helper="paru"
|
||||
success "Found paru"
|
||||
AUR="paru"
|
||||
success "Using paru"
|
||||
elif command -v yay &>/dev/null; then
|
||||
success "Found yay"
|
||||
AUR="yay"
|
||||
success "Using yay"
|
||||
else
|
||||
step "Installing yay-bin..."
|
||||
tmpdir=$(mktemp -d)
|
||||
(
|
||||
git clone --quiet --depth=1 https://aur.archlinux.org/yay-bin.git "$tmpdir/yay-bin" 2>/dev/null || true
|
||||
git clone --quiet --depth=1 https://aur.archlinux.org/yay-bin.git "$tmpdir/yay-bin"
|
||||
cd "$tmpdir/yay-bin"
|
||||
makepkg -si --noconfirm >/dev/null 2>&1
|
||||
) &
|
||||
spinner $! "Building yay-bin..."
|
||||
spinner $! "Building yay-bin"
|
||||
wait $! || {
|
||||
error "Failed to install yay-bin"
|
||||
rm -rf "$tmpdir"
|
||||
exit 1
|
||||
}
|
||||
rm -rf "$tmpdir"
|
||||
success "yay-bin installed successfully"
|
||||
AUR="yay"
|
||||
success "yay-bin installed"
|
||||
fi
|
||||
|
||||
# Repository setup
|
||||
progress "Setting up Modus repository"
|
||||
# ── Repository ─────────────────────────────────────────────────────
|
||||
section "Repository"
|
||||
|
||||
if [ -d "$INSTALL_DIR" ]; then
|
||||
step "Updating existing repository..."
|
||||
step "Pulling latest changes..."
|
||||
git -C "$INSTALL_DIR" pull --quiet 2>/dev/null || true
|
||||
success "Repository updated"
|
||||
else
|
||||
@@ -276,70 +390,59 @@ else
|
||||
git clone --quiet "$REPO_URL" "$INSTALL_DIR" 2>/dev/null || true
|
||||
success "Repository cloned"
|
||||
fi
|
||||
info "Location: ${INSTALL_DIR}"
|
||||
info "${INSTALL_DIR}"
|
||||
|
||||
# Package installation
|
||||
progress "Installing packages"
|
||||
# ── Install packages ──────────────────────────────────────────────
|
||||
section "Installing packages"
|
||||
|
||||
step "Syncing package databases..."
|
||||
$aur_helper -Syy --noconfirm >/dev/null 2>&1 || true
|
||||
success "Database synced"
|
||||
step "Syncing databases..."
|
||||
$AUR -Syy --noconfirm >/dev/null 2>&1 || true
|
||||
success "Databases synced"
|
||||
|
||||
step "Installing required packages (this may take a while)..."
|
||||
installed=0
|
||||
failed=0
|
||||
failed_pkgs=()
|
||||
total=${#PACKAGES[@]}
|
||||
|
||||
for pkg in "${PACKAGES[@]}"; do
|
||||
if $aur_helper -S --needed --noconfirm "$pkg" >/dev/null 2>&1; then
|
||||
if $AUR -S --needed --noconfirm "$pkg" >/dev/null 2>&1; then
|
||||
installed=$((installed + 1))
|
||||
else
|
||||
failed=$((failed + 1))
|
||||
warn "Failed to install: $pkg"
|
||||
failed_pkgs+=("$pkg")
|
||||
fi
|
||||
printf "\r %b%s%b Progress: %s/%s packages" "$CYAN" "$ARROW" "$RESET" "$installed" "${#PACKAGES[@]}"
|
||||
pct=$((installed * 100 / total))
|
||||
printf "\r ${CYAN}${ARROW}${RESET} [%-50s] %3d%% (%d/%d)" "$(printf '#%.0s' $(seq 1 $((pct / 2))))" "$pct" "$installed" "$total"
|
||||
done
|
||||
echo ""
|
||||
|
||||
if [ $failed -eq 0 ]; then
|
||||
success "All packages installed successfully"
|
||||
success "All ${installed} packages installed"
|
||||
else
|
||||
warn "$failed package(s) failed to install"
|
||||
warn "${failed} package(s) failed:"
|
||||
for pkg in "${failed_pkgs[@]}"; do
|
||||
echo -e " ${RED}${CROSS}${RESET} ${pkg}"
|
||||
done
|
||||
fi
|
||||
|
||||
# Update check
|
||||
step "Checking for package updates..."
|
||||
outdated=$($aur_helper -Qu 2>/dev/null | awk '{print $1}' || true)
|
||||
to_update=()
|
||||
for pkg in "${PACKAGES[@]}"; do
|
||||
if echo "$outdated" | grep -q "^$pkg\$"; then
|
||||
to_update+=("$pkg")
|
||||
fi
|
||||
done
|
||||
|
||||
if [ ${#to_update[@]} -gt 0 ]; then
|
||||
step "Updating ${#to_update[@]} outdated package(s)..."
|
||||
$aur_helper -S --noconfirm "${to_update[@]}" >/dev/null 2>&1 || true
|
||||
success "Packages updated"
|
||||
else
|
||||
success "All packages are up-to-date"
|
||||
fi
|
||||
|
||||
progress "Building Global Menu shim"
|
||||
# ── Build native modules ──────────────────────────────────────────
|
||||
section "Building native modules"
|
||||
|
||||
# Global Menu shim
|
||||
step "Compiling libmenu_button_shim.so..."
|
||||
SHIM_SRC="$INSTALL_DIR/src/window/globalmenu/libmenu_button_shim.c"
|
||||
SHIM_OUT="$INSTALL_DIR/src/window/globalmenu/libmenu_button_shim.so"
|
||||
if [ -f "$SHIM_SRC" ]; then
|
||||
if gcc -shared -fPIC -O2 -o "$SHIM_OUT" "$SHIM_SRC" "$(pkg-config --cflags --libs gtk+-3.0)" -ldl 2>/dev/null; then
|
||||
success "libmenu_button_shim.so built successfully"
|
||||
success "libmenu_button_shim.so built"
|
||||
else
|
||||
warn "Failed to compile libmenu_button_shim.so - global menu may not work"
|
||||
warn "Failed to compile shim — global menu may not work"
|
||||
fi
|
||||
else
|
||||
warn "libmenu_button_shim.c not found - skipping shim build"
|
||||
warn "Shim source not found — skipped"
|
||||
fi
|
||||
|
||||
progress "Building App Capture module"
|
||||
|
||||
# App Capture
|
||||
step "Compiling libappcapture.so..."
|
||||
if [ -d "$INSTALL_DIR/src/window/switcher/app-capture" ]; then
|
||||
if (
|
||||
@@ -347,38 +450,35 @@ if [ -d "$INSTALL_DIR/src/window/switcher/app-capture" ]; then
|
||||
meson setup builddir --wipe >/dev/null 2>&1 || meson setup builddir >/dev/null 2>&1
|
||||
meson compile -C builddir >/dev/null 2>&1
|
||||
); then
|
||||
success "libappcapture.so built successfully"
|
||||
success "libappcapture.so built"
|
||||
else
|
||||
warn "Failed to compile App Capture module"
|
||||
warn "Failed to compile app-capture"
|
||||
fi
|
||||
else
|
||||
warn "App Capture module directory not found"
|
||||
warn "App-capture source not found — skipped"
|
||||
fi
|
||||
|
||||
progress "Configuring Hyprland"
|
||||
# ── Hyprland config ───────────────────────────────────────────────
|
||||
section "Hyprland configuration"
|
||||
|
||||
HYPR_CONFIG="$HOME/.config/hypr/hyprland.lua"
|
||||
MODUS_MODULE_LINE="dofile(\"$INSTALL_DIR/config/hypr/modus.lua\")"
|
||||
|
||||
if [ -f "$HYPR_CONFIG" ]; then
|
||||
step "Checking Hyprland Lua configuration..."
|
||||
|
||||
if grep -qF "$MODUS_MODULE_LINE" "$HYPR_CONFIG"; then
|
||||
success "Modus module already loaded"
|
||||
success "Modus module already in hyprland.lua"
|
||||
else
|
||||
step "Adding Modus module to Hyprland Lua config..."
|
||||
|
||||
step "Adding Modus module to hyprland.lua..."
|
||||
{
|
||||
echo ""
|
||||
echo "-- Modus configuration"
|
||||
echo "$MODUS_MODULE_LINE"
|
||||
} >> "$HYPR_CONFIG"
|
||||
|
||||
success "Modus configuration added"
|
||||
success "Module added"
|
||||
fi
|
||||
else
|
||||
warn "Hyprland Lua config not found at $HYPR_CONFIG"
|
||||
info "You may need to manually add: $MODUS_MODULE_LINE"
|
||||
warn "hyprland.lua not found at ${HYPR_CONFIG}"
|
||||
info "Add manually: ${MODUS_MODULE_LINE}"
|
||||
fi
|
||||
|
||||
step "Symlinking hypridle.conf..."
|
||||
@@ -387,16 +487,14 @@ HYPRIDLE_CONF="$INSTALL_DIR/config/hypr/hypridle.conf"
|
||||
HYPRIDLE_TARGET="$HYPR_DIR/hypridle.conf"
|
||||
mkdir -p "$HYPR_DIR"
|
||||
if [ -f "$HYPRIDLE_CONF" ]; then
|
||||
if [ -L "$HYPRIDLE_TARGET" ]; then
|
||||
rm "$HYPRIDLE_TARGET"
|
||||
fi
|
||||
ln -sf "$HYPRIDLE_CONF" "$HYPRIDLE_TARGET"
|
||||
success "hypridle.conf symlinked"
|
||||
else
|
||||
warn "hypridle.conf not found at $HYPRIDLE_CONF"
|
||||
warn "hypridle.conf not found — skipped"
|
||||
fi
|
||||
|
||||
progress "Configuring global environment"
|
||||
# ── Environment ───────────────────────────────────────────────────
|
||||
section "Global environment"
|
||||
|
||||
APP_CONF_DIR="$HOME/.config/environment.d"
|
||||
APP_CONF_FILE="$APP_CONF_DIR/appmenu.conf"
|
||||
@@ -407,7 +505,7 @@ cat > "$APP_CONF_FILE" << 'EOF'
|
||||
GTK_MODULES=appmenu-gtk-module
|
||||
UBUNTU_MENUPROXY=1
|
||||
EOF
|
||||
success "Environment config written to $APP_CONF_FILE"
|
||||
success "environment.d/appmenu.conf written"
|
||||
|
||||
PAM_FILE="$HOME/.pam_environment"
|
||||
step "Updating pam_environment..."
|
||||
@@ -417,9 +515,11 @@ for entry in "GTK_MODULES DEFAULT=appmenu-gtk-module" "UBUNTU_MENUPROXY DEFAULT=
|
||||
echo "$entry" >> "$PAM_FILE"
|
||||
fi
|
||||
done
|
||||
success ".pam_environment updated"
|
||||
success "pam_environment updated"
|
||||
|
||||
# ── Matugen ────────────────────────────────────────────────────────
|
||||
section "Matugen"
|
||||
|
||||
progress "Configuring Matugen"
|
||||
MATUGEN_CONFIG="$HOME/.config/matugen/config.toml"
|
||||
|
||||
MODUS_BLOCK='[templates.modus]
|
||||
@@ -432,34 +532,30 @@ input_path = "~/.config/Modus/config/matugen/templates/hyprland-colors.lua"
|
||||
output_path = "~/.config/Modus/config/matugen/colors.lua"'
|
||||
|
||||
if [ -f "$MATUGEN_CONFIG" ]; then
|
||||
step "Checking matugen config..."
|
||||
|
||||
# ---- Modus1 ----
|
||||
if grep -qF "[templates.modus]" "$MATUGEN_CONFIG"; then
|
||||
success "modus1 template already exists"
|
||||
success "Modus template already configured"
|
||||
else
|
||||
step "Adding modus1 template..."
|
||||
step "Adding Modus template..."
|
||||
echo "" >> "$MATUGEN_CONFIG"
|
||||
echo "$MODUS_BLOCK" >> "$MATUGEN_CONFIG"
|
||||
success "modus template added"
|
||||
success "Modus template added"
|
||||
fi
|
||||
|
||||
# ---- Hyprland ----
|
||||
if grep -qF "[templates.hyprland]" "$MATUGEN_CONFIG"; then
|
||||
success "hyprland template already exists"
|
||||
success "Hyprland template already configured"
|
||||
else
|
||||
step "Adding hyprland template..."
|
||||
step "Adding Hyprland template..."
|
||||
echo "" >> "$MATUGEN_CONFIG"
|
||||
echo "$HYPR_BLOCK" >> "$MATUGEN_CONFIG"
|
||||
success "hyprland template added"
|
||||
success "Hyprland template added"
|
||||
fi
|
||||
|
||||
else
|
||||
warn "matugen config not found at $MATUGEN_CONFIG"
|
||||
info "Create it first or install matugen"
|
||||
warn "matugen config not found at ${MATUGEN_CONFIG}"
|
||||
info "Install matugen first, then re-run this script"
|
||||
fi
|
||||
|
||||
progress "Launching Modus"
|
||||
# ── Launch ─────────────────────────────────────────────────────────
|
||||
section "Launch"
|
||||
|
||||
step "Stopping existing instances..."
|
||||
if killall modus 2>/dev/null; then
|
||||
@@ -474,24 +570,26 @@ if uwsm app -- uv run --project "$INSTALL_DIR" start >/dev/null 2>&1 & then
|
||||
disown
|
||||
sleep 2
|
||||
if pgrep -x "modus" >/dev/null; then
|
||||
success "Modus is now running"
|
||||
success "Modus is running"
|
||||
else
|
||||
warn "Modus may not have started correctly"
|
||||
warn "Modus may not have started — check logs"
|
||||
fi
|
||||
else
|
||||
error "Failed to start Modus"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Completion
|
||||
# ── Summary ────────────────────────────────────────────────────────
|
||||
echo ""
|
||||
echo -e "${GREEN}${BOLD}╔════════════════════════════════════════╗${RESET}"
|
||||
echo -e "${GREEN}${BOLD}║ ║${RESET}"
|
||||
echo -e "${GREEN}${BOLD}║ Installation completed! ║${RESET}"
|
||||
echo -e "${GREEN}${BOLD}║ ║${RESET}"
|
||||
echo -e "${GREEN}${BOLD}╚════════════════════════════════════════╝${RESET}"
|
||||
echo -e " ${GREEN}${BOLD}╔══════════════════════════════════════════╗${RESET}"
|
||||
echo -e " ${GREEN}${BOLD}║${RESET} ${GREEN}${BOLD}║${RESET}"
|
||||
echo -e " ${GREEN}${BOLD}║${RESET} ${GREEN}${BOLD}Installation complete!${RESET} ${GREEN}${BOLD}║${RESET}"
|
||||
echo -e " ${GREEN}${BOLD}║${RESET} ${GREEN}${BOLD}║${RESET}"
|
||||
echo -e " ${GREEN}${BOLD}╚══════════════════════════════════════════╝${RESET}"
|
||||
echo ""
|
||||
info "Modus is running in the background"
|
||||
info "Config location: ${INSTALL_DIR}"
|
||||
info "Repository: ${REPO_URL}"
|
||||
divider
|
||||
info "Packages: ${GREEN}${installed}${RESET} installed${RED:+, ${failed} failed}"
|
||||
info "Location: ${INSTALL_DIR}"
|
||||
info "Config: ${INSTALL_DIR}/config/"
|
||||
divider
|
||||
echo ""
|
||||
Reference in new issue
Block a user