163 lines
4.0 KiB
Python
Executable File
163 lines
4.0 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
|
|
import subprocess
|
|
import shutil
|
|
from argparse import ArgumentParser
|
|
from pathlib import Path
|
|
|
|
BASE_PKGS = [
|
|
"clang", # C/C++ development
|
|
"scripts", # scripts & snippets
|
|
"stow", # --target=~
|
|
]
|
|
|
|
# for TUI only setups
|
|
# e.g. servers that are accessed via SSH only
|
|
TUI_PKGS = [
|
|
*BASE_PKGS,
|
|
"fastfetch", # sys info,
|
|
"helix", # editor
|
|
"nvim", # editor
|
|
"shell", # fish & .bash_profile & shell prompt
|
|
"yazi", # terminal file manager
|
|
]
|
|
|
|
# for all WMs and DEs
|
|
GUI_BASE_PKGS = [
|
|
*TUI_PKGS,
|
|
"cava",
|
|
"kitty", # terminal emulator
|
|
"ghostty", # alternative terminal emulator
|
|
"misc", # miscellaneous GUI configs (e.g. *-flags)
|
|
# "mpv", # media player
|
|
"wallpaper", # wallpapers & manager
|
|
"kvantum", # qt theming
|
|
"nwg-look", # gtk theming
|
|
"wezterm", # alternative terminal emulator
|
|
]
|
|
|
|
# for Hyprland setup
|
|
# HYPRLAND_PKGS = [
|
|
# *GUI_BASE_PKGS,
|
|
# "eww", # widgets
|
|
# "hypr", # hypr family
|
|
# "hyprland", # wm config
|
|
# "mako", # notifications
|
|
# "rofi", # application launcher
|
|
# "waybar", # status bar
|
|
# "wlogout", # logout menu
|
|
# ]
|
|
|
|
# for Niri setup
|
|
NIRI_PKGS = [
|
|
*GUI_BASE_PKGS,
|
|
"hypr", # for hyprlock & hypridle
|
|
"niri", # wm config
|
|
"quickshell", # widgets & status bar & notifications & ...
|
|
"rofi", # application launcher
|
|
"wlogout", # logout menu
|
|
]
|
|
|
|
PKGS = {
|
|
"base": BASE_PKGS,
|
|
"tui": TUI_PKGS,
|
|
"gui": GUI_BASE_PKGS,
|
|
# "hyprland": HYPRLAND_PKGS,
|
|
"niri": NIRI_PKGS,
|
|
}
|
|
|
|
SESSION_NAME = {
|
|
"hyprland": "Hyprland",
|
|
"niri": "niri",
|
|
"default": "default",
|
|
}
|
|
|
|
|
|
PKGS_PATH = Path(__file__).resolve().parent.resolve() / "config"
|
|
DEST_PATH = Path.home().expanduser()
|
|
|
|
|
|
def _log(level: str, message: str):
|
|
color = (
|
|
"\033[92m" if level == "INFO" else "\033[91m" if level == "ERROR" else "\033[0m"
|
|
)
|
|
reset = "\033[0m"
|
|
print(f"{color}[{level}] {message}{reset}")
|
|
|
|
|
|
def check_deps() -> bool:
|
|
required_deps = ["stow"]
|
|
for dep in required_deps:
|
|
if not shutil.which(dep):
|
|
_log("ERROR", f"Required dependency '{dep}' is not installed.")
|
|
return False
|
|
return True
|
|
|
|
|
|
def stow(pkg: str):
|
|
subprocess.run(
|
|
["stow", "-v", "-d", str(PKGS_PATH), "-t", str(DEST_PATH), pkg], check=True
|
|
)
|
|
|
|
|
|
def unstow(pkg: str):
|
|
subprocess.run(
|
|
["stow", "-v", "-d", str(PKGS_PATH), "-t", str(DEST_PATH), "-D", pkg], check=True,
|
|
)
|
|
|
|
|
|
def switch(session: str):
|
|
subprocess.run(
|
|
[str(Path("~/.local/scripts/config-switch").expanduser()), session], check=True
|
|
)
|
|
|
|
|
|
def main():
|
|
if not check_deps():
|
|
exit(1)
|
|
|
|
parser = ArgumentParser(
|
|
description="Stow configuration packages in this repository."
|
|
)
|
|
parser.add_argument(
|
|
"package", choices=PKGS.keys(), help="The configuration package group to stow."
|
|
)
|
|
parser.add_argument(
|
|
"--unstow",
|
|
action="store_true",
|
|
help="Unstow the specified package group instead of stowing it.",
|
|
)
|
|
args = parser.parse_args()
|
|
|
|
selected_pkgs = PKGS[args.package]
|
|
is_unstow = args.unstow
|
|
|
|
for pkg in selected_pkgs:
|
|
try:
|
|
if is_unstow:
|
|
unstow(pkg)
|
|
_log("INFO", f"Successfully unstowed package '{pkg}'.")
|
|
else:
|
|
stow(pkg)
|
|
_log("INFO", f"Successfully stowed package '{pkg}'.")
|
|
except subprocess.CalledProcessError as e:
|
|
_log("ERROR", f"Failed to stow package '{pkg}': {e}")
|
|
|
|
if is_unstow:
|
|
return # No need to switch session if we're just unstowing
|
|
|
|
if args.package in SESSION_NAME:
|
|
session = SESSION_NAME[args.package]
|
|
else:
|
|
session = SESSION_NAME["default"]
|
|
|
|
try:
|
|
switch(session)
|
|
_log("INFO", f"Switched to session profile '{session}'.")
|
|
except subprocess.CalledProcessError as e:
|
|
_log("ERROR", f"Failed to switch session profile '{session}': {e}")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|