From f77ac7575073e3131e06718243754dae7cf4eb57 Mon Sep 17 00:00:00 2001 From: edythawne Date: Tue, 28 Jul 2026 12:04:34 -0600 Subject: [PATCH 01/12] Debian Testing Support --- exoinstall.py | 226 ++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 210 insertions(+), 16 deletions(-) diff --git a/exoinstall.py b/exoinstall.py index b0f7588..c956f44 100644 --- a/exoinstall.py +++ b/exoinstall.py @@ -225,6 +225,11 @@ def detect_distro(self): print( f"{self.Colors.GREEN}Detected Fedora-based distribution.{self.Colors.ENDC}" ) + elif os.path.exists("/etc/debian_version"): + self.distro = "debian" + print( + f"{self.Colors.GREEN}Detected Debian distribution.{self.Colors.ENDC}" + ) elif os.path.exists("/etc/lsb-release"): try: with open("/etc/lsb-release") as f: @@ -250,14 +255,16 @@ def detect_distro(self): ) return False + def get_package_manager(self): if self.distro == "arch": self.package_manager = "pacman" elif self.distro == "fedora": self.package_manager = "dnf" - elif self.distro == "ubuntu": + elif self.distro in ["ubuntu", "debian"]: self.package_manager = "apt" + def check_aur_helper(self): self.print_header("Checking for AUR Helper") if shutil.which("paru"): @@ -317,6 +324,18 @@ def install_yay(self): os.chdir("..") return False + def check_pkgconfig_file(self, pc_name): + paths = [ + "/usr/lib64/pkgconfig", + "/usr/lib/pkgconfig", + "/usr/share/pkgconfig", + "/usr/lib/x86_64-linux-gnu/pkgconfig" + ] + for path in paths: + if os.path.exists(os.path.join(path, pc_name)): + return path + return None + def install_dependencies(self): self.print_header("Installing Dependencies") @@ -382,6 +401,38 @@ def install_dependencies(self): "libdisplay-info-dev", "libliftoff-dev", ], + "debian": [ + "python3-pip", + "cargo", + "libgnome-bluetooth-3.0-13", + "fonts-material-design-icons-iconfont", + "meson", + "ninja-build", + "pkg-config", + "scdoc", + "libxkbcommon-dev", + "libdisplay-info-dev", + "libliftoff-dev", + "pkg-config", + "npm", + "build-essential", + "wayland-protocols", + "libgirepository1.0-dev", + "gobject-introspection", + "git", + "tar", + "libcairo2-dev", + "python3-dev", + "libpulse-dev", + "liblz4-dev", + "libwayland-dev", + "libgtk4-layer-shell-dev", + "gir1.2-glib-2.0", + "gir1.2-gtk-4.0", + "network-manager", + "gir1.2-nm-1.0", + "gir1.2-gnomebluetooth-3.0" + ], } if self.distro in dependencies: @@ -461,7 +512,7 @@ def install_dependencies(self): ) else: self.run_command(["fc-cache", "-v"]) - elif self.distro == "ubuntu": + elif self.distro in ["ubuntu", "debian"]: result = self.run_command(["sudo", "apt", "update"]) if result is None or ( hasattr(result, "returncode") and result.returncode != 0 @@ -484,6 +535,7 @@ def install_dependencies(self): "install", "--user", "git+https://github.com/ignis-sh/ignis.git", + "--break-system-packages" ] ) if result is None or ( @@ -507,7 +559,10 @@ def install_dependencies(self): f"{self.Colors.YELLOW}No automatic dependency installation for your distribution.{self.Colors.ENDC}" ) - if self.distro in ["fedora", "ubuntu"]: + if self.distro == "debian": + self.install_adw_gtk_theme() + + if self.distro in ["fedora", "ubuntu", "debian"]: print("\nChecking for dart-sass...") if not shutil.which("sass"): print( @@ -552,19 +607,8 @@ def install_dependencies(self): gvc_repo_dir = os.path.join(gvc_temp_dir, "ignis-gvc") self.run_command(["git", "clone", gvc_repo_url, gvc_repo_dir]) - def check_pkgconfig_file(pc_name): - paths = [ - "/usr/lib64/pkgconfig", - "/usr/lib/pkgconfig", - "/usr/share/pkgconfig", - ] - for path in paths: - if os.path.exists(os.path.join(path, pc_name)): - return path - return None - env = os.environ.copy() - pc_path = check_pkgconfig_file("gobject-introspection-1.0.pc") + pc_path = self.check_pkgconfig_file("gobject-introspection-1.0.pc") if pc_path: env["PKG_CONFIG_PATH"] = f"{pc_path}:{env.get('PKG_CONFIG_PATH', '')}" else: @@ -607,6 +651,11 @@ def check_pkgconfig_file(pc_name): ) shutil.rmtree(gvc_temp_dir) + if self.distro == "debian": + self.install_ignis_gvc_debian() + self.install_awww_debian() + return + if not shutil.which("swww"): print("\nswww not found, attempting to build from source...") temp_dir = tempfile.mkdtemp() @@ -619,7 +668,7 @@ def check_pkgconfig_file(pc_name): ) if result and result.returncode == 0: env = os.environ.copy() - pc_path = check_pkgconfig_file("wayland-protocols.pc") + pc_path = self.check_pkgconfig_file("wayland-protocols.pc") if pc_path: env["PKG_CONFIG_PATH"] = ( f"{pc_path}:{env.get('PKG_CONFIG_PATH', '')}" @@ -666,6 +715,151 @@ def check_pkgconfig_file(pc_name): shutil.rmtree(temp_dir) else: print("swww found in PATH.") + + def install_awww_debian(self): + # Evitamos reinstalar si ya existen los binarios en el sistema + if shutil.which("swww") or shutil.which("awww"): + print("awww/swww found in PATH. Skipping build.") + return True + + print("\nawww/swww not found, attempting to build awww from Codeberg for Debian...") + temp_dir = tempfile.mkdtemp() + awww_repo_url = "https://codeberg.org/LGFae/awww.git" + awww_repo_dir = os.path.join(temp_dir, "awww") + + print(f"Cloning {awww_repo_url} to {awww_repo_dir}...") + result = self.run_command( + ["git", "clone", awww_repo_url, awww_repo_dir], cwd=temp_dir + ) + if result and result.returncode == 0: + env = os.environ.copy() + pc_path = self.check_pkgconfig_file("wayland-protocols.pc") + if pc_path: + env["PKG_CONFIG_PATH"] = f"{pc_path}:{env.get('PKG_CONFIG_PATH', '')}" + else: + print( + f"{self.Colors.RED}wayland-protocols.pc not found. Please install wayland-protocols.{self.Colors.ENDC}" + ) + + print("Building awww with cargo...") + result = self.run_command( + ["cargo", "build", "--release"], cwd=awww_repo_dir, env=env + ) + if result and result.returncode == 0: + # Iteramos sobre los nombres de los nuevos binarios oficiales + for binary in ["awww", "awww-daemon"]: + src = os.path.join(awww_repo_dir, "target", "release", binary) + dest = os.path.join("/usr/local/bin", binary) + + if os.path.exists(src): + # Copiamos el binario nativo (awww o awww-daemon) + copy_result = self.run_command(["sudo", "cp", src, dest]) + if copy_result and copy_result.returncode == 0: + print(f"{self.Colors.GREEN}Installed {binary} to /usr/local/bin.{self.Colors.ENDC}") + + # Generamos el enlace simbólico clásico (swww o swww-daemon) apuntando al nuevo binario + legacy_binary = binary.replace("awww", "swww") + legacy_dest = os.path.join("/usr/local/bin", legacy_binary) + print(f"Creating compatibility symlink: {legacy_binary} -> {binary}") + self.run_command(["sudo", "ln", "-sf", dest, legacy_dest]) + else: + print(f"{self.Colors.RED}Failed to copy {binary} to /usr/local/bin.{self.Colors.ENDC}") + else: + print(f"{self.Colors.RED}Binary {binary} not found after build.{self.Colors.ENDC}") + else: + print(f"{self.Colors.RED}Error building awww with cargo.{self.Colors.ENDC}") + else: + print(f"{self.Colors.RED}Error cloning awww repository.{self.Colors.ENDC}") + + shutil.rmtree(temp_dir) + return True + + def install_ignis_gvc_debian(self): + self.print_header("Compiling and Installing ignis-gvc") + + temp_dir = tempfile.mkdtemp() + gvc_repo_url = "https://github.com/ignis-sh/ignis-gvc" + gvc_repo_dir = os.path.join(temp_dir, "ignis-gvc") + + print(f"Cloning {gvc_repo_url}...") + result = self.run_command( + ["git", "clone", gvc_repo_url, gvc_repo_dir], cwd=temp_dir + ) + + if result and result.returncode == 0: + print("Running meson setup...") + setup_result = self.run_command( + ["meson", "setup", "build", "--prefix=/usr"], cwd=gvc_repo_dir + ) + + if setup_result and setup_result.returncode == 0: + print("Running meson compile...") + compile_result = self.run_command( + ["meson", "compile", "-C", "build"], cwd=gvc_repo_dir + ) + + if compile_result and compile_result.returncode == 0: + print("Running meson install...") + install_result = self.run_command( + ["sudo", "meson", "install", "-C", "build"], cwd=gvc_repo_dir + ) + else: + print(f"{self.Colors.RED}Error: meson compile failed.{self.Colors.ENDC}") + else: + print(f"{self.Colors.RED}Error: meson setup failed.{self.Colors.ENDC}") + else: + print(f"{self.Colors.RED}Error: git clone failed.{self.Colors.ENDC}") + + shutil.rmtree(temp_dir) + return True + + + def install_adw_gtk_theme(self): + self.print_header("Installing adw-gtk3 Theme") + + import shutil + themes_dir = os.path.expanduser("~/.local/share/themes") + url = "https://github.com/lassekongo83/adw-gtk3/releases/download/v6.5/adw-gtk3v6.5.tar.xz" + tar_path = os.path.join(themes_dir, "adw-gtk3v6.5.tar.xz") + + # 1. Asegurar la carpeta base de temas + if not self.dry_run: + os.makedirs(themes_dir, exist_ok=True) + else: + print(f"{self.Colors.YELLOW}[DRY RUN] Would create directory: {themes_dir}{self.Colors.ENDC}") + + # 2. Reemplazar carpetas viejas si ya existen para actualizar limpiamente + for old_dir in ["adw-gtk3", "adw-gtk3-dark"]: + target = os.path.join(themes_dir, old_dir) + if os.path.exists(target): + if not self.dry_run: + print(f"Removing old theme directory to replace it: {target}") + shutil.rmtree(target) + else: + print(f"{self.Colors.YELLOW}[DRY RUN] Would remove old theme directory: {target}{self.Colors.ENDC}") + + # 3. Descargar el archivo .tar.xz usando tu método run_command + download_cmd = ["curl", "-L", "-o", tar_path, url] + print(f"Downloading theme from GitHub...") + if self.run_command(download_cmd) is None: + print(f"{self.Colors.RED}Failed to download the theme.{self.Colors.ENDC}") + return False + + # 4. Extraer el archivo .tar.xz usando tu método run_command + extract_cmd = ["tar", "-xvf", tar_path, "-C", themes_dir] + print(f"Extracting theme to {themes_dir}...") + if self.run_command(extract_cmd) is None: + print(f"{self.Colors.RED}Failed to extract the theme.{self.Colors.ENDC}") + return False + + # 5. Limpieza del archivo comprimido temporal + if not self.dry_run: + if os.path.exists(tar_path): + os.remove(tar_path) + + print(f"{self.Colors.GREEN}adw-gtk3 theme installed and replaced successfully!{self.Colors.ENDC}") + return True + def check_desktop(self): self.print_header("Checking Desktop Environment") From 1acf3f298feff2b4e78470a834a9b2732f9e9fe7 Mon Sep 17 00:00:00 2001 From: edythawne Date: Thu, 30 Jul 2026 10:29:50 -0600 Subject: [PATCH 02/12] Repo dms para instalar niri --- exoinstall.py | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/exoinstall.py b/exoinstall.py index c956f44..0c89df3 100644 --- a/exoinstall.py +++ b/exoinstall.py @@ -435,6 +435,9 @@ def install_dependencies(self): ], } + if self.distro == "debian": + self.add_danklinux_repository_debian() + if self.distro in dependencies: packages = dependencies[self.distro] print( @@ -715,6 +718,53 @@ def install_dependencies(self): shutil.rmtree(temp_dir) else: print("swww found in PATH.") + + def add_danklinux_repository_debian(self): + self.print_header("Adding DankLinux Repository") + + repo_list_path = "/etc/apt/sources.list.d/danklinux.list" + keyring_path = "/etc/apt/keyrings/danklinux.gpg" + + if os.path.exists(repo_list_path): + print("DankLinux repository already exists. Skipping installation.") + return True + + print("DankLinux repository not found. Adding to the system...") + import subprocess + + if not self.dry_run: + try: + # Aseguramos que la carpeta de llaveros de apt exista + subprocess.run("sudo mkdir -p /etc/apt/keyrings", shell=True, check=True) + + # Descargamos e instalamos la clave GPG (Release.key) de OpenSUSE + print("Downloading and processing GPG key...") + gpg_cmd = ( + "curl -fsSL https://download.opensuse.org/repositories/home:AvengeMedia:danklinux/Debian_Testing/Release.key | " + f"sudo gpg --dearmor -o {keyring_path}" + ) + subprocess.run(gpg_cmd, shell=True, check=True) + + # Agregamos el archivo sources.list usando tee + print("Writing repository list file...") + list_cmd = ( + f'echo "deb [signed-by={keyring_path}] https://download.opensuse.org/repositories/home:/AvengeMedia:/danklinux/Debian_Testing/ /" | ' + f"sudo tee {repo_list_path} > /dev/null" + ) + subprocess.run(list_cmd, shell=True, check=True) + + # Actualizamos los índices de apt para registrar el nuevo repositorio + print("Updating apt package lists...") + subprocess.run("sudo apt update", shell=True, check=True) + + print(f"{self.Colors.GREEN}DankLinux repository added successfully!{self.Colors.ENDC}") + except subprocess.CalledProcessError as e: + print(f"{self.Colors.RED}Error adding DankLinux repository: {e}{self.Colors.ENDC}") + return False + else: + print(f"{self.Colors.YELLOW}[DRY RUN] Would download key to {keyring_path} and create {repo_list_path}{self.Colors.ENDC}") + + return True def install_awww_debian(self): # Evitamos reinstalar si ya existen los binarios en el sistema From f80b6a3d4caed10aa4f5cc98b667266474b8811d Mon Sep 17 00:00:00 2001 From: edythawne Date: Thu, 30 Jul 2026 10:57:12 -0600 Subject: [PATCH 03/12] gnupg install --- exoinstall.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/exoinstall.py b/exoinstall.py index 0c89df3..43078ba 100644 --- a/exoinstall.py +++ b/exoinstall.py @@ -722,6 +722,10 @@ def install_dependencies(self): def add_danklinux_repository_debian(self): self.print_header("Adding DankLinux Repository") + # Agregado al script: Instalamos de forma obligatoria el paquete gnupg + print("Ensuring gnupg is installed on Debian...") + subprocess.run("sudo apt install -y gnupg", shell=True, check=True) + repo_list_path = "/etc/apt/sources.list.d/danklinux.list" keyring_path = "/etc/apt/keyrings/danklinux.gpg" From 8509aba440a74163f634832b1ff78550ef5c3168 Mon Sep 17 00:00:00 2001 From: edythawne Date: Thu, 30 Jul 2026 11:01:00 -0600 Subject: [PATCH 04/12] actualcion de repo --- exoinstall.py | 37 ++++++++++++++++++------------------- 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/exoinstall.py b/exoinstall.py index 43078ba..a7f0891 100644 --- a/exoinstall.py +++ b/exoinstall.py @@ -722,10 +722,6 @@ def install_dependencies(self): def add_danklinux_repository_debian(self): self.print_header("Adding DankLinux Repository") - # Agregado al script: Instalamos de forma obligatoria el paquete gnupg - print("Ensuring gnupg is installed on Debian...") - subprocess.run("sudo apt install -y gnupg", shell=True, check=True) - repo_list_path = "/etc/apt/sources.list.d/danklinux.list" keyring_path = "/etc/apt/keyrings/danklinux.gpg" @@ -734,14 +730,19 @@ def add_danklinux_repository_debian(self): return True print("DankLinux repository not found. Adding to the system...") - import subprocess if not self.dry_run: - try: - # Aseguramos que la carpeta de llaveros de apt exista - subprocess.run("sudo mkdir -p /etc/apt/keyrings", shell=True, check=True) + print("Ensuring gnupg is installed on Debian...") + if self.run_command(["sudo", "apt", "update"]) is None or \ + self.run_command(["sudo", "apt", "install", "-y", "gnupg"]) is None: + print(f"{self.Colors.RED}Failed to install gnupg.{self.Colors.ENDC}") + return False + + if self.run_command(["sudo", "mkdir", "-p", "/etc/apt/keyrings"]) is None: + return False - # Descargamos e instalamos la clave GPG (Release.key) de OpenSUSE + try: + import subprocess print("Downloading and processing GPG key...") gpg_cmd = ( "curl -fsSL https://download.opensuse.org/repositories/home:AvengeMedia:danklinux/Debian_Testing/Release.key | " @@ -749,29 +750,27 @@ def add_danklinux_repository_debian(self): ) subprocess.run(gpg_cmd, shell=True, check=True) - # Agregamos el archivo sources.list usando tee print("Writing repository list file...") list_cmd = ( f'echo "deb [signed-by={keyring_path}] https://download.opensuse.org/repositories/home:/AvengeMedia:/danklinux/Debian_Testing/ /" | ' f"sudo tee {repo_list_path} > /dev/null" ) subprocess.run(list_cmd, shell=True, check=True) + except (subprocess.CalledProcessError, FileNotFoundError) as e: + print(f"{self.Colors.RED}Error executing repository shell command: {e}{self.Colors.ENDC}") + return False - # Actualizamos los índices de apt para registrar el nuevo repositorio - print("Updating apt package lists...") - subprocess.run("sudo apt update", shell=True, check=True) - - print(f"{self.Colors.GREEN}DankLinux repository added successfully!{self.Colors.ENDC}") - except subprocess.CalledProcessError as e: - print(f"{self.Colors.RED}Error adding DankLinux repository: {e}{self.Colors.ENDC}") + print("Updating apt package lists...") + if self.run_command(["sudo", "apt", "update"]) is None: return False + + print(f"{self.Colors.GREEN}DankLinux repository added successfully!{self.Colors.ENDC}") else: - print(f"{self.Colors.YELLOW}[DRY RUN] Would download key to {keyring_path} and create {repo_list_path}{self.Colors.ENDC}") + print(f"{self.Colors.YELLOW}[DRY RUN] Would install gnupg, download key to {keyring_path} and create {repo_list_path}{self.Colors.ENDC}") return True def install_awww_debian(self): - # Evitamos reinstalar si ya existen los binarios en el sistema if shutil.which("swww") or shutil.which("awww"): print("awww/swww found in PATH. Skipping build.") return True From 859a45a6b8c54db6af3167a65ef9cbbe7db42778 Mon Sep 17 00:00:00 2001 From: edythawne Date: Thu, 30 Jul 2026 12:16:40 -0600 Subject: [PATCH 05/12] En debian al instalar niri usar bandera de no recomendados --- exoinstall.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/exoinstall.py b/exoinstall.py index a7f0891..2cc90bf 100644 --- a/exoinstall.py +++ b/exoinstall.py @@ -942,6 +942,7 @@ def install_desktop(self): choice = self.get_user_choice("Select an option: ", ["1", "2", "3", "q"]) install_cmd = ["sudo", self.package_manager] + if self.distro == "fedora": install_cmd.extend(["install", "-y"]) else: @@ -951,6 +952,10 @@ def install_desktop(self): if choice == "1": print("Installing Niri...") + + if self.distro == "debian": + install_cmd.extend(["--no-install-recommends"]) + if self.run_command(install_cmd + ["niri"]): return "niri" elif choice == "2": From 5d0fea4814beafeac166ae029371237278daf021 Mon Sep 17 00:00:00 2001 From: edythawne Date: Fri, 31 Jul 2026 10:32:28 -0600 Subject: [PATCH 06/12] Enlaces simbolicos de ignis --- exoinstall.py | 150 +++++++++++++++++++++++++++++++------------------- 1 file changed, 93 insertions(+), 57 deletions(-) diff --git a/exoinstall.py b/exoinstall.py index 2cc90bf..8a68398 100644 --- a/exoinstall.py +++ b/exoinstall.py @@ -438,6 +438,34 @@ def install_dependencies(self): if self.distro == "debian": self.add_danklinux_repository_debian() + print("\n Installing required fonts...") + result = self.run_command(["wget", "https://github.com/google/material-design-icons/raw/refs/heads/master/variablefont/MaterialSymbolsOutlined%5BFILL,GRAD,opsz,wght%5D.ttf"]) + + if result is None or ( + hasattr(result, "returncode") and result.returncode != 0 + ): + print( + f"{self.Colors.RED}Failed to download the font.{self.Colors.ENDC}" + ) + else: + result = self.run_command(["sudo", "mkdir", "-p", "/usr/share/fonts/material-symbols-icons"]) + if result is None or ( + hasattr(result, "returncode") and result.returncode != 0 + ): + print( + f"{self.Colors.RED}Failed to create the folder for the font.{self.Colors.ENDC}" + ) + else: + result = self.run_command(["sudo", "mv", "MaterialSymbolsOutlined[FILL,GRAD,opsz,wght].ttf", "/usr/share/fonts/material-symbols-icons"]) + if result is None or ( + hasattr(result, "returncode") and result.returncode != 0 + ): + print( + f"{self.Colors.RED}Failed to install the font.{self.Colors.ENDC}" + ) + else: + self.run_command(["fc-cache", "-v"]) + if self.distro in dependencies: packages = dependencies[self.distro] print( @@ -489,32 +517,6 @@ def install_dependencies(self): else: self.run_command(["export", "PATH=\"$PATH:~/.cargo/bin\""]) - print("\n Installing required fonts...") - result = self.run_command(["wget", "https://github.com/google/material-design-icons/raw/refs/heads/master/variablefont/MaterialSymbolsOutlined%5BFILL,GRAD,opsz,wght%5D.ttf"]) - if result is None or ( - hasattr(result, "returncode") and result.returncode != 0 - ): - print( - f"{self.Colors.RED}Failed to download the font.{self.Colors.ENDC}" - ) - else: - result = self.run_command(["sudo", "mkdir", "-p", "/usr/share/fonts/material-symbols-icons"]) - if result is None or ( - hasattr(result, "returncode") and result.returncode != 0 - ): - print( - f"{self.Colors.RED}Failed to create the folder for the font.{self.Colors.ENDC}" - ) - else: - result = self.run_command(["sudo", "mv", "MaterialSymbolsOutlined[FILL,GRAD,opsz,wght].ttf", "/usr/share/fonts/material-symbols-icons"]) - if result is None or ( - hasattr(result, "returncode") and result.returncode != 0 - ): - print( - f"{self.Colors.RED}Failed to install the font.{self.Colors.ENDC}" - ) - else: - self.run_command(["fc-cache", "-v"]) elif self.distro in ["ubuntu", "debian"]: result = self.run_command(["sudo", "apt", "update"]) if result is None or ( @@ -556,6 +558,8 @@ def install_dependencies(self): print( f"{self.Colors.RED}Failed to install matugen via cargo.{self.Colors.ENDC}" ) + else: + self.run_command(["export", "PATH=\"$PATH:~/.cargo/bin\""]) else: print( @@ -828,42 +832,74 @@ def install_awww_debian(self): return True def install_ignis_gvc_debian(self): - self.print_header("Compiling and Installing ignis-gvc") - - temp_dir = tempfile.mkdtemp() - gvc_repo_url = "https://github.com/ignis-sh/ignis-gvc" - gvc_repo_dir = os.path.join(temp_dir, "ignis-gvc") + self.print_header("Configurando directorios y enlaces simbólicos para ignis-gvc") + + lib_dir = "/usr/lib/ignis-gvc" + share_dir = "/usr/share/ignis-gvc" + + so_target = os.path.join(lib_dir, "libgvc.so") + typelib_target = os.path.join(lib_dir, "Gvc-1.0.typelib") + gir_target = os.path.join(share_dir, "Gvc-1.0.gir") + + # 1. Crear directorios /usr/lib/ignis-gvc y /usr/share/ignis-gvc si no existen + for directory in [lib_dir, share_dir]: + if not os.path.exists(directory): + print(f"Creando directorio {directory}...") + self.run_command(["sudo", "mkdir", "-p", directory]) + + # 2. Buscar y enlazar libgvc.so + if not os.path.exists(so_target): + so_sources = [ + "/usr/lib/x86_64-linux-gnu/libgvc.so", + "/usr/local/lib/libgvc.so", + "/usr/lib/libgvc.so", + ] + so_source = next((s for s in so_sources if os.path.exists(s)), None) + + if so_source: + print(f"Enlazando {so_source} -> {so_target}") + self.run_command(["sudo", "ln", "-sf", so_source, so_target]) + else: + print( + f"{self.Colors.YELLOW}Advertencia: No se encontró libgvc.so en las rutas estándar.{self.Colors.ENDC}" + ) - print(f"Cloning {gvc_repo_url}...") - result = self.run_command( - ["git", "clone", gvc_repo_url, gvc_repo_dir], cwd=temp_dir - ) - - if result and result.returncode == 0: - print("Running meson setup...") - setup_result = self.run_command( - ["meson", "setup", "build", "--prefix=/usr"], cwd=gvc_repo_dir + # 3. Buscar y enlazar Gvc-1.0.typelib + if not os.path.exists(typelib_target): + typelib_sources = [ + "/usr/lib/x86_64-linux-gnu/girepository-1.0/Gvc-1.0.typelib", + "/usr/local/lib/girepository-1.0/Gvc-1.0.typelib", + "/usr/lib/girepository-1.0/Gvc-1.0.typelib", + ] + typelib_source = next( + (t for t in typelib_sources if os.path.exists(t)), None ) - - if setup_result and setup_result.returncode == 0: - print("Running meson compile...") - compile_result = self.run_command( - ["meson", "compile", "-C", "build"], cwd=gvc_repo_dir + + if typelib_source: + print(f"Enlazando {typelib_source} -> {typelib_target}") + self.run_command( + ["sudo", "ln", "-sf", typelib_source, typelib_target] ) - - if compile_result and compile_result.returncode == 0: - print("Running meson install...") - install_result = self.run_command( - ["sudo", "meson", "install", "-C", "build"], cwd=gvc_repo_dir - ) - else: - print(f"{self.Colors.RED}Error: meson compile failed.{self.Colors.ENDC}") else: - print(f"{self.Colors.RED}Error: meson setup failed.{self.Colors.ENDC}") - else: - print(f"{self.Colors.RED}Error: git clone failed.{self.Colors.ENDC}") + print( + f"{self.Colors.YELLOW}Advertencia: No se encontró Gvc-1.0.typelib en las rutas estándar.{self.Colors.ENDC}" + ) + + # 4. Buscar y enlazar Gvc-1.0.gir (si está en otra ruta del sistema) + if not os.path.exists(gir_target): + gir_sources = [ + "/usr/share/gir-1.0/Gvc-1.0.gir", + "/usr/local/share/gir-1.0/Gvc-1.0.gir", + ] + gir_source = next((g for g in gir_sources if os.path.exists(g)), None) + + if gir_source: + print(f"Enlazando {gir_source} -> {gir_target}") + self.run_command(["sudo", "ln", "-sf", gir_source, gir_target]) + + # 5. Actualizar la caché de bibliotecas del sistema + self.run_command(["sudo", "ldconfig"]) - shutil.rmtree(temp_dir) return True From eb6523e94e90a93ac1869530312e6f35d1eac253 Mon Sep 17 00:00:00 2001 From: edythawne Date: Fri, 31 Jul 2026 10:52:25 -0600 Subject: [PATCH 07/12] dart-sass en path --- exoinstall.py | 118 +++++++++++++++++++++++--------------------------- 1 file changed, 53 insertions(+), 65 deletions(-) diff --git a/exoinstall.py b/exoinstall.py index 8a68398..3704996 100644 --- a/exoinstall.py +++ b/exoinstall.py @@ -586,21 +586,47 @@ def install_dependencies(self): ] ) if result_local is None or ( - hasattr(result_local, "returncode") - and result_local.returncode != 0 + hasattr(result_local, "returncode") and result_local.returncode != 0 ): print( - f"{self.Colors.RED}Failed to install dart-sass via npm. You may need to add ~/.local/bin to your PATH if using user-local install.{self.Colors.ENDC}" + f"{self.Colors.RED}Failed to install dart-sass via npm.{self.Colors.ENDC}" ) else: print( - f"{self.Colors.GREEN}Installed dart-sass locally via npm. Add ~/.local/bin to your PATH if not already present.{self.Colors.ENDC}" + f"{self.Colors.GREEN}Installed dart-sass locally via npm.{self.Colors.ENDC}" ) + user_local_bin = os.path.expanduser("~/.local/bin") + + # 1. Añadir al PATH de la sesión activa del proceso en ejecución if user_local_bin not in os.environ.get("PATH", ""): + os.environ["PATH"] = ( + f"{user_local_bin}:{os.environ.get('PATH', '')}" + ) print( - f"{self.Colors.YELLOW}Reminder: ~/.local/bin is not in your PATH. Add it to use 'sass' globally.{self.Colors.ENDC}" + f"{self.Colors.GREEN}Added {user_local_bin} to current session PATH.{self.Colors.ENDC}" ) + + # 2. Añadir al PATH permanentemente en la configuración de la shell + for rc_file in [".bashrc", ".zshrc"]: + shell_rc_path = os.path.expanduser(f"~/{rc_file}") + if os.path.exists(shell_rc_path): + try: + with open(shell_rc_path, "r") as f: + content = f.read() + + if ".local/bin" not in content: + with open(shell_rc_path, "a") as f: + f.write( + '\n# Added by Ignis setup script\nexport PATH="$HOME/.local/bin:$PATH"\n' + ) + print( + f"{self.Colors.GREEN}Added PATH export to {rc_file} permanently.{self.Colors.ENDC}" + ) + except Exception as e: + print( + f"{self.Colors.YELLOW}Could not update {rc_file}: {e}{self.Colors.ENDC}" + ) else: print( f"{self.Colors.RED}npm is not installed. Please install npm and then run 'npm install --prefix ~/.local sass'.{self.Colors.ENDC}" @@ -831,73 +857,35 @@ def install_awww_debian(self): shutil.rmtree(temp_dir) return True + import os + + def install_ignis_gvc_debian(self): - self.print_header("Configurando directorios y enlaces simbólicos para ignis-gvc") + self.print_header("Creando estructura y enlaces para ignis-gvc") lib_dir = "/usr/lib/ignis-gvc" - share_dir = "/usr/share/ignis-gvc" - - so_target = os.path.join(lib_dir, "libgvc.so") - typelib_target = os.path.join(lib_dir, "Gvc-1.0.typelib") - gir_target = os.path.join(share_dir, "Gvc-1.0.gir") - - # 1. Crear directorios /usr/lib/ignis-gvc y /usr/share/ignis-gvc si no existen - for directory in [lib_dir, share_dir]: - if not os.path.exists(directory): - print(f"Creando directorio {directory}...") - self.run_command(["sudo", "mkdir", "-p", directory]) - - # 2. Buscar y enlazar libgvc.so - if not os.path.exists(so_target): - so_sources = [ - "/usr/lib/x86_64-linux-gnu/libgvc.so", - "/usr/local/lib/libgvc.so", - "/usr/lib/libgvc.so", - ] - so_source = next((s for s in so_sources if os.path.exists(s)), None) - - if so_source: - print(f"Enlazando {so_source} -> {so_target}") - self.run_command(["sudo", "ln", "-sf", so_source, so_target]) - else: - print( - f"{self.Colors.YELLOW}Advertencia: No se encontró libgvc.so en las rutas estándar.{self.Colors.ENDC}" - ) - # 3. Buscar y enlazar Gvc-1.0.typelib - if not os.path.exists(typelib_target): - typelib_sources = [ - "/usr/lib/x86_64-linux-gnu/girepository-1.0/Gvc-1.0.typelib", - "/usr/local/lib/girepository-1.0/Gvc-1.0.typelib", - "/usr/lib/girepository-1.0/Gvc-1.0.typelib", - ] - typelib_source = next( - (t for t in typelib_sources if os.path.exists(t)), None - ) + # 1. Crear el directorio si no existe + if not os.path.exists(lib_dir): + print(f"Creando directorio {lib_dir}...") + self.run_command(["sudo", "mkdir", "-p", lib_dir]) - if typelib_source: - print(f"Enlazando {typelib_source} -> {typelib_target}") - self.run_command( - ["sudo", "ln", "-sf", typelib_source, typelib_target] - ) - else: - print( - f"{self.Colors.YELLOW}Advertencia: No se encontró Gvc-1.0.typelib en las rutas estándar.{self.Colors.ENDC}" - ) - - # 4. Buscar y enlazar Gvc-1.0.gir (si está en otra ruta del sistema) - if not os.path.exists(gir_target): - gir_sources = [ - "/usr/share/gir-1.0/Gvc-1.0.gir", - "/usr/local/share/gir-1.0/Gvc-1.0.gir", - ] - gir_source = next((g for g in gir_sources if os.path.exists(g)), None) + # 2. Definir los enlaces simbólicos origen -> destino + links = { + "/usr/lib/x86_64-linux-gnu/libgvc.so": os.path.join( + lib_dir, "libgvc.so" + ), + "/usr/lib/x86_64-linux-gnu/girepository-1.0/Gvc-1.0.typelib": os.path.join( + lib_dir, "Gvc-1.0.typelib" + ), + } - if gir_source: - print(f"Enlazando {gir_source} -> {gir_target}") - self.run_command(["sudo", "ln", "-sf", gir_source, gir_target]) + # 3. Crear los enlaces + for source, target in links.items(): + print(f"Enlazando {source} -> {target}") + self.run_command(["sudo", "ln", "-sf", source, target]) - # 5. Actualizar la caché de bibliotecas del sistema + # 4. Refrescar caché de librerías self.run_command(["sudo", "ldconfig"]) return True From 3b8599e0a1a8983a98df66a8e46ff1e74559280d Mon Sep 17 00:00:00 2001 From: edythawne Date: Fri, 31 Jul 2026 11:00:12 -0600 Subject: [PATCH 08/12] dart-sass en path --- exoinstall.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/exoinstall.py b/exoinstall.py index 3704996..772d093 100644 --- a/exoinstall.py +++ b/exoinstall.py @@ -872,10 +872,10 @@ def install_ignis_gvc_debian(self): # 2. Definir los enlaces simbólicos origen -> destino links = { - "/usr/lib/x86_64-linux-gnu/libgvc.so": os.path.join( + "/usr/lib/x86_64-linux-gnu/ignis-gvc/libgvc.so": os.path.join( lib_dir, "libgvc.so" ), - "/usr/lib/x86_64-linux-gnu/girepository-1.0/Gvc-1.0.typelib": os.path.join( + "/usr/lib/x86_64-linux-gnu/ignis-gvc/Gvc-1.0.typelib": os.path.join( lib_dir, "Gvc-1.0.typelib" ), } From bbfda2bb74d31c626dcacf0da8d5b4ac690f90ec Mon Sep 17 00:00:00 2001 From: edythawne Date: Fri, 31 Jul 2026 11:38:18 -0600 Subject: [PATCH 09/12] dart-sass en path --- exoinstall.py | 41 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 37 insertions(+), 4 deletions(-) diff --git a/exoinstall.py b/exoinstall.py index 772d093..bb0dc20 100644 --- a/exoinstall.py +++ b/exoinstall.py @@ -586,7 +586,8 @@ def install_dependencies(self): ] ) if result_local is None or ( - hasattr(result_local, "returncode") and result_local.returncode != 0 + hasattr(result_local, "returncode") + and result_local.returncode != 0 ): print( f"{self.Colors.RED}Failed to install dart-sass via npm.{self.Colors.ENDC}" @@ -596,9 +597,41 @@ def install_dependencies(self): f"{self.Colors.GREEN}Installed dart-sass locally via npm.{self.Colors.ENDC}" ) - user_local_bin = os.path.expanduser("~/.local/bin") + # 1. Resolver la ubicación del ejecutable (evaluando ambas rutas posibles) + possible_sass_paths = [ + os.path.expanduser("~/.local/bin/sass"), + os.path.expanduser("~/.local/node_modules/.bin/sass"), + ] + npm_sass_binary = next( + ( + path + for path in possible_sass_paths + if os.path.exists(path) + ), + None, + ) - # 1. Añadir al PATH de la sesión activa del proceso en ejecución + # 2. Enlazar globalmente en /usr/local/bin/sass para greetd/systemd + if npm_sass_binary: + print( + f"{self.Colors.GREEN}Linking {npm_sass_binary} -> /usr/local/bin/sass{self.Colors.ENDC}" + ) + self.run_command( + [ + "sudo", + "ln", + "-sf", + npm_sass_binary, + "/usr/local/bin/sass", + ] + ) + else: + print( + f"{self.Colors.YELLOW}Warning: Sass installed but binary not found in expected locations.{self.Colors.ENDC}" + ) + + # 3. Añadir ~/.local/bin al PATH de la sesión activa + user_local_bin = os.path.expanduser("~/.local/bin") if user_local_bin not in os.environ.get("PATH", ""): os.environ["PATH"] = ( f"{user_local_bin}:{os.environ.get('PATH', '')}" @@ -607,7 +640,7 @@ def install_dependencies(self): f"{self.Colors.GREEN}Added {user_local_bin} to current session PATH.{self.Colors.ENDC}" ) - # 2. Añadir al PATH permanentemente en la configuración de la shell + # 4. Añadir al PATH permanentemente en la configuración de la shell for rc_file in [".bashrc", ".zshrc"]: shell_rc_path = os.path.expanduser(f"~/{rc_file}") if os.path.exists(shell_rc_path): From 5a02377d22c0d55bf8af49dbe3e72513835faaa7 Mon Sep 17 00:00:00 2001 From: edythawne Date: Fri, 31 Jul 2026 11:41:43 -0600 Subject: [PATCH 10/12] REGION error --- exoinstall.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/exoinstall.py b/exoinstall.py index bb0dc20..d874419 100644 --- a/exoinstall.py +++ b/exoinstall.py @@ -431,7 +431,10 @@ def install_dependencies(self): "gir1.2-gtk-4.0", "network-manager", "gir1.2-nm-1.0", - "gir1.2-gnomebluetooth-3.0" + "gir1.2-gnomebluetooth-3.0", + "gir1.2-gtk-3.0", + "gir1.2-freedesktop", + "gir1.2-gdkpixbuf-2.0" ], } From 8492609fd2f10b2583d2b2a51837d9f5bf86a262 Mon Sep 17 00:00:00 2001 From: edythawne Date: Fri, 31 Jul 2026 11:44:08 -0600 Subject: [PATCH 11/12] REGION error --- exoinstall.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/exoinstall.py b/exoinstall.py index d874419..2bda4de 100644 --- a/exoinstall.py +++ b/exoinstall.py @@ -434,7 +434,9 @@ def install_dependencies(self): "gir1.2-gnomebluetooth-3.0", "gir1.2-gtk-3.0", "gir1.2-freedesktop", - "gir1.2-gdkpixbuf-2.0" + "gir1.2-gdkpixbuf-2.0", + "python3-cairo", + "gir1.2-cairo-1.0" ], } From f51db7a6ef6bdd70624cafb2e12b7d487de7abbc Mon Sep 17 00:00:00 2001 From: edythawne Date: Fri, 31 Jul 2026 15:25:52 -0700 Subject: [PATCH 12/12] bashrc backup --- bashrc.backup | 117 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 117 insertions(+) create mode 100644 bashrc.backup diff --git a/bashrc.backup b/bashrc.backup new file mode 100644 index 0000000..4e768a9 --- /dev/null +++ b/bashrc.backup @@ -0,0 +1,117 @@ +# ~/.bashrc: executed by bash(1) for non-login shells +# see /usr/share/doc/bash/examples/startup-files (in the package bash-doc) +# for examples + +# If not running interactively, don't do anything +case $- in + *i*) ;; + *) return;; +esac + +# don't put duplicate lines or lines starting with space in the history. +# See bash(1) for more options +HISTCONTROL=ignoreboth + +# append to the history file, don't overwrite it +shopt -s histappend + +# for setting history length see HISTSIZE and HISTFILESIZE in bash(1) +HISTSIZE=1000 +HISTFILESIZE=2000 + +# check the window size after each command and, if necessary, +# update the values of LINES and COLUMNS. +shopt -s checkwinsize + +# If set, the pattern "**" used in a pathname expansion context will +# match all files and zero or more directories and subdirectories. +#shopt -s globstar + +# make less more friendly for non-text input files, see lesspipe(1) +#[ -x /usr/bin/lesspipe ] && eval "$(SHELL=/bin/sh lesspipe)" + +# set variable identifying the chroot you work in (used in the prompt below) +if [ -z "${debian_chroot:-}" ] && [ -r /etc/debian_chroot ]; then + debian_chroot=$(cat /etc/debian_chroot) +fi + +# set a fancy prompt (non-color, unless we know we "want" color) +case "$TERM" in + xterm-color|*-256color) color_prompt=yes;; +esac + +# uncomment for a colored prompt, if the terminal has the capability; turned +# off by default to not distract the user: the focus in a terminal window +# should be on the output of commands, not on the prompt +#force_color_prompt=yes + +if [ -n "$force_color_prompt" ]; then + if [ -x /usr/bin/tput ] && tput setaf 1 >&/dev/null; then + # We have color support; assume it's compliant with Ecma-48 + # (ISO/IEC-6429). (Lack of such support is extremely rare, and such + # a case would tend to support setf rather than setaf.) + color_prompt=yes + else + color_prompt= + fi +fi + +if [ "$color_prompt" = yes ]; then + PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ ' +else + PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ ' +fi +unset color_prompt force_color_prompt + +# If this is an xterm set the title to user@host:dir +case "$TERM" in +xterm*|rxvt*) + PS1="\[\e]0;${debian_chroot:+($debian_chroot)}\u@\h: \w\a\]$PS1" + ;; +*) + ;; +esac + +# enable color support of ls and also add handy aliases +if [ -x /usr/bin/dircolors ]; then + test -r ~/.dircolors && eval "$(dircolors -b ~/.dircolors)" || eval "$(dircolors -b)" + alias ls='ls --color=auto' + #alias dir='dir --color=auto' + #alias vdir='vdir --color=auto' + + #alias grep='grep --color=auto' + #alias fgrep='fgrep --color=auto' + #alias egrep='egrep --color=auto' +fi + +# colored GCC warnings and errors +#export GCC_COLORS='error=01;31:warning=01;35:note=01;36:caret=01;32:locus=01:quote=01' + +# some more ls aliases +#alias ll='ls -l' +#alias la='ls -A' +#alias l='ls -CF' + +# Alias definitions. +# You may want to put all your additions into a separate file like +# ~/.bash_aliases, instead of adding them here directly. +# See /usr/share/doc/bash-doc/examples in the bash-doc package. + +if [ -f ~/.bash_aliases ]; then + . ~/.bash_aliases +fi + +# enable programmable completion features (you don't need to enable +# this, if it's already enabled in /etc/bash.bashrc and /etc/profile +# sources /etc/bash.bashrc). +if ! shopt -oq posix; then + if [ -f /usr/share/bash-completion/bash_completion ]; then + . /usr/share/bash-completion/bash_completion + elif [ -f /etc/bash_completion ]; then + . /etc/bash_completion + fi +fi + +# Added by Ignis setup script +export PATH="$HOME/.local/bin:$PATH" +export PATH="$HOME/.cargo/bin:$PATH"