What would you like to be added?
maybe add freeBSD support i made the installer
How will it help?
manifest.toml
packages = ["caelestia-shell", "caelestia-cli"]
post_install = [
"test -f ${XDG_STATE_HOME:-$HOME/.local/state}/caelestia/scheme.json || caelestia scheme set -n caelestia",
"caelestia shell -d >/dev/null",
]
post_update = ["caelestia shell -k; sleep 1; caelestia shell -d >/dev/null"]
--- Core components ---
[[components]]
name = "hypr"
default = true
packages = [
"hyprland",
"xdg-desktop-portal-hyprland",
"xdg-desktop-portal-gtk",
"nerd-fonts", # FreeBSD combines nerd fonts or handles them via specific port naming
]
post_install = ["hyprctl reload >/dev/null"]
post_update = ["hyprctl reload >/dev/null"]
[[components.entries]]
src = "hypr"
dest = "$XDG_CONFIG_HOME/hypr"
[[components]]
name = "fish"
default = true
packages = ["fish", "eza", "zoxide", "direnv"]
post_install = [
"mkdir -p ${XDG_CONFIG_HOME:-$HOME/.config}/caelestia",
"touch ${XDG_CONFIG_HOME:-$HOME/.config}/caelestia/user-config.fish",
]
[[components.entries]]
src = "fish"
dest = "$XDG_CONFIG_HOME/fish"
[[components]]
name = "foot"
default = true
packages = ["foot", "fish"]
[[components.entries]]
src = "foot"
dest = "$XDG_CONFIG_HOME/foot"
[[components]]
name = "fastfetch"
default = true
packages = ["fastfetch"]
[[components.entries]]
src = "fastfetch"
dest = "$XDG_CONFIG_HOME/fastfetch"
[[components]]
name = "btop"
default = true
packages = ["btop"]
post_install = ["killall -USR2 btop 2>/dev/null || true"]
post_update = ["killall -USR2 btop 2>/dev/null || true"]
[[components.entries]]
src = "btop"
dest = "$XDG_CONFIG_HOME/btop"
[[components]]
name = "micro"
default = true
packages = ["micro"]
[[components.entries]]
src = "micro"
dest = "$XDG_CONFIG_HOME/micro"
[[components]]
name = "thunar"
default = true
packages = ["thunar"]
[[components.entries]]
src = "thunar"
dest = "$XDG_CONFIG_HOME/Thunar"
[[components]]
name = "starship"
default = true
packages = ["starship"]
[[components.entries]]
src = "starship.toml"
dest = "$XDG_CONFIG_HOME/starship.toml"
[[components]]
name = "firefox"
default = true
packages = ["firefox"] # Removed local custom build dependency trigger
post_package = ["bash $CAELESTIA_DOTS/firefox/init_firefox.sh"]
[[components.entries]]
src = "firefox/userChrome.css"
dest = "$HOME/.mozilla/firefox/.default/chrome/userChrome.css"
[[components.entries]]
src = "firefox/user.js"
dest = "$HOME/.mozilla/firefox/.default/user.js"
[[components]]
name = "gtk"
default = true
packages = ["adwaita-icon-theme", "papirus-icon-theme"] # Standard FreeBSD theme names
[[components]]
name = "qt"
default = true
packages = [
"qt6-base", # Uses standard FreeBSD Qt6 libraries instead of individual arch configs
"papirus-icon-theme",
]
[[components]]
name = "auth"
default = true
packages = ["gnome-keyring", "polkit"]
[[components]]
name = "network"
default = true
FreeBSD uses standard system networking configuration natively,
but if you manage it through networkmanager, use the generic name:
packages = ["NetworkManager"]
[[components]]
name = "bluetooth"
default = true
FreeBSD includes its bluetooth stack directly in the base system!
No extra packages required here.
packages = []
[[components]]
name = "pipewire"
default = true
packages = [
"pipewire",
"wireplumber",
"pavucontrol",
]
[[components]]
name = "clipboard"
default = true
packages = ["wl-clipboard"] # Dropped cliphist (AUR tool)
[[components]]
name = "fonts"
default = true
packages = ["noto"]
[[components]]
name = "tools"
default = true
packages = [
"curl",
"git",
"jq",
"lazygit",
"bat",
"ripgrep",
"xdg-user-dirs",
]
post_install = ["xdg-user-dirs-update"]
--- Optional components ---
Note: Optional binary-only packages like 'vscodium-bin', 'todoist-appimage', and 'equibop'
are Linux-exclusive binaries. For FreeBSD, replaced with standard ports where supported.
[[components]]
name = "vscode"
packages = ["vscode"] # Standard FreeBSD open-source VSCode port name
[[components.entries]]
src = "vscode/settings.json"
dest = "$XDG_CONFIG_HOME/Code/User/settings.json"
[[components.entries]]
src = "vscode/keybindings.json"
dest = "$XDG_CONFIG_HOME/Code/User/keybindings.json"
[[components.entries]]
src = "vscode/flags.conf"
dest = "$XDG_CONFIG_HOME/code-flags.conf"
[[components]]
name = "zed"
packages = ["zed-editor"]
[[components]]
name = "discord"
packages = ["discord"] # Native FreeBSD discord port package
import subprocess
import shutil
import textwrap
from argparse import Namespace
from pathlib import Path
Cleaned up imports - removing legacy Arch modules
from caelestia.utils.dots.deployer import Deployer
from caelestia.utils.dots.manifest import ComponentError, Manifest, ManifestError
from caelestia.utils.dots.source import DotsSource, SourceError
from caelestia.utils.dots.state import DotsState
from caelestia.utils.io import confirm, disable_input, fatal, info, log, pause, prompt_selection, warn
from caelestia.utils.paths import (
config_backup_dir,
config_dir,
)
def _parse_list_arg(value: str | None) -> list[str] | None:
if value is None:
return None
return [item.strip() for item in value.split(",") if item.strip()]
class FreeBSDPackageInstaller:
"""Native FreeBSD Package Manager (pkg) Interface."""
def __init__(self, noconfirm: bool = False) -> None:
self.flags = ["-y"] if noconfirm else []
self.privilege_escalator = self._detect_escalator()
def _detect_escalator(self) -> str:
"""Determines if the system uses 'doas' or 'sudo' for admin actions."""
if shutil.which("doas"):
return "doas"
if shutil.which("sudo"):
return "sudo"
return ""
def install(self, packages: list[str]) -> None:
if not packages:
return
base_cmd = ["pkg", "install"] + self.flags + packages
cmd = [self.privilege_escalator] + base_cmd if self.privilege_escalator else base_cmd
try:
subprocess.run(cmd, check=True)
except subprocess.CalledProcessError as e:
raise RuntimeError(f"FreeBSD pkg install failed: {e}")
def is_installed(self, package: str) -> bool:
cmd = ["pkg", "info", "-e", package]
res = subprocess.run(cmd, capture_output=True)
return res.returncode == 0
def remove(self, packages: list[str]) -> None:
if not packages:
return
base_cmd = ["pkg", "delete"] + self.flags + packages
cmd = [self.privilege_escalator] + base_cmd if self.privilege_escalator else base_cmd
subprocess.run(cmd, check=True)
class Command:
args: Namespace
def __init__(self, args: Namespace) -> None:
self.args = args
def run(self) -> None:
if self.args.noconfirm:
disable_input()
self.print_greeting()
self.create_backup()
source, tip, manifest = self.fetch_manifest()
# Instantiate the FreeBSD native package system
installer = FreeBSDPackageInstaller(noconfirm=getattr(self.args, "noconfirm", False))
packages = manifest.enabled_packages()
if packages:
print()
log("Installing FreeBSD dependencies...")
try:
installer.install(packages)
except RuntimeError as e:
fatal(e)
# Core configuration file deployment
deployed = self.deploy_configs(source, manifest)
# Save deployment state cleanly for FreeBSD
DotsState(
applied_rev=tip,
enabled_components=manifest.enabled_components,
packages=packages,
deployed_files=deployed,
).save()
self.print_done()
def print_greeting(self) -> None:
print(
"\033[38;2;150;241;241m"
+ textwrap.dedent(
r"""
╭─────────────────────────────────────────────────╮
│ ______ __ __ _ │
│ / ____/___ ____ / /__ _____/ /_(_)___ _ │
│ / / / __ `/ _ \/ / _ \/ ___/ __/ / __ `/ │
│ / /___/ /_/ / __/ / __(__ ) /_/ / /_/ / │
│ \____/\__,_/\___/_/\___/____/\__/_/\__,_/ │
│ │
│ --- FREEBSD ENGINE --- │
╰─────────────────────────────────────────────────╯
"""
)
+ "\033[0m"
)
info("Welcome to the Caelestia installer for FreeBSD!")
info("This tool will configure your packages and environment automatically.")
pause()
print()
def create_backup(self) -> None:
if config_dir.exists():
if not confirm("Back up the existing config directory?", default=True):
return
log(f"Creating a backup of {config_dir}...")
if config_backup_dir.exists():
if not confirm("A backup already exists, overwrite?", default=False):
info("Not creating backup.")
return
log("Deleting old backup...")
shutil.rmtree(config_backup_dir)
shutil.copytree(config_dir, config_backup_dir, symlinks=True)
info(f"Created backup at {config_backup_dir}")
def fetch_manifest(self) -> tuple[DotsSource, str, Manifest]:
print()
log("Fetching dots repository...")
source = DotsSource()
try:
source.ensure()
tip = source.checkout_tip()
except SourceError as e:
fatal(e)
enable = _parse_list_arg(getattr(self.args, "enable_components", None))
disable = _parse_list_arg(getattr(self.args, "disable_components", None))
try:
manifest = source.manifest_at(tip)
if enable is None and disable is None:
optional = [name for name, comp in manifest.components.items() if not comp.default]
if optional:
enable = prompt_selection(optional, "Components to enable?")
manifest.resolve_components(enable=enable, disable=disable)
except (SourceError, ManifestError, ComponentError) as e:
fatal(e)
names = ", ".join(manifest.enabled_components) or "none"
info(f"Enabled components: {names}")
return source, tip, manifest
def deploy_configs(self, source: DotsSource, manifest: Manifest) -> dict[str, str]:
print()
log("Deploying configuration links...")
deployer = Deployer()
for entry in manifest.enabled_entries():
src = source.working_path(entry.expanded_src())
if not src.exists():
warn(f"missing in source, skipping: {entry.src}")
continue
dests = entry.expanded_dests()
if not dests:
warn(f"dest glob matched nothing, skipping: {entry.dest}")
continue
for dest in dests:
deployer.place(src, Path(dest))
info(f"{entry.src} -> {dest}")
return deployer.deployed_files
def print_done(self) -> None:
print()
info("All done! Caelestia has been installed successfully.")
info("Plug-and-Play Verification Steps:")
info(" - Ensure your user belongs to the 'video' group: pw groupmod video -m <username>")
info(" - Ensure seatd is running: sysrc seatd_enable=\"YES\" && service seatd start")
info(" - Launch via terminal using: Hyprland")
Extra info
No response
What would you like to be added?
maybe add freeBSD support i made the installer
How will it help?
manifest.toml
packages = ["caelestia-shell", "caelestia-cli"]
post_install = [
"test -f ${XDG_STATE_HOME:-$HOME/.local/state}/caelestia/scheme.json || caelestia scheme set -n caelestia",
"caelestia shell -d >/dev/null",
]
post_update = ["caelestia shell -k; sleep 1; caelestia shell -d >/dev/null"]
--- Core components ---
[[components]]
name = "hypr"
default = true
packages = [
"hyprland",
"xdg-desktop-portal-hyprland",
"xdg-desktop-portal-gtk",
"nerd-fonts", # FreeBSD combines nerd fonts or handles them via specific port naming
]
post_install = ["hyprctl reload >/dev/null"]
post_update = ["hyprctl reload >/dev/null"]
[[components.entries]]
src = "hypr"
dest = "$XDG_CONFIG_HOME/hypr"
[[components]]
name = "fish"
default = true
packages = ["fish", "eza", "zoxide", "direnv"]
post_install = [
"mkdir -p ${XDG_CONFIG_HOME:-$HOME/.config}/caelestia",
"touch ${XDG_CONFIG_HOME:-$HOME/.config}/caelestia/user-config.fish",
]
[[components.entries]]
src = "fish"
dest = "$XDG_CONFIG_HOME/fish"
[[components]]
name = "foot"
default = true
packages = ["foot", "fish"]
[[components.entries]]
src = "foot"
dest = "$XDG_CONFIG_HOME/foot"
[[components]]
name = "fastfetch"
default = true
packages = ["fastfetch"]
[[components.entries]]
src = "fastfetch"
dest = "$XDG_CONFIG_HOME/fastfetch"
[[components]]
name = "btop"
default = true
packages = ["btop"]
post_install = ["killall -USR2 btop 2>/dev/null || true"]
post_update = ["killall -USR2 btop 2>/dev/null || true"]
[[components.entries]]
src = "btop"
dest = "$XDG_CONFIG_HOME/btop"
[[components]]
name = "micro"
default = true
packages = ["micro"]
[[components.entries]]
src = "micro"
dest = "$XDG_CONFIG_HOME/micro"
[[components]]
name = "thunar"
default = true
packages = ["thunar"]
[[components.entries]]
src = "thunar"
dest = "$XDG_CONFIG_HOME/Thunar"
[[components]]
name = "starship"
default = true
packages = ["starship"]
[[components.entries]]
src = "starship.toml"
dest = "$XDG_CONFIG_HOME/starship.toml"
[[components]]
name = "firefox"
default = true
packages = ["firefox"] # Removed local custom build dependency trigger
post_package = ["bash $CAELESTIA_DOTS/firefox/init_firefox.sh"]
[[components.entries]]
src = "firefox/userChrome.css"
dest = "$HOME/.mozilla/firefox/.default/chrome/userChrome.css"
[[components.entries]]
src = "firefox/user.js"
dest = "$HOME/.mozilla/firefox/.default/user.js"
[[components]]
name = "gtk"
default = true
packages = ["adwaita-icon-theme", "papirus-icon-theme"] # Standard FreeBSD theme names
[[components]]
name = "qt"
default = true
packages = [
"qt6-base", # Uses standard FreeBSD Qt6 libraries instead of individual arch configs
"papirus-icon-theme",
]
[[components]]
name = "auth"
default = true
packages = ["gnome-keyring", "polkit"]
[[components]]
name = "network"
default = true
FreeBSD uses standard system networking configuration natively,
but if you manage it through networkmanager, use the generic name:
packages = ["NetworkManager"]
[[components]]
name = "bluetooth"
default = true
FreeBSD includes its bluetooth stack directly in the base system!
No extra packages required here.
packages = []
[[components]]
name = "pipewire"
default = true
packages = [
"pipewire",
"wireplumber",
"pavucontrol",
]
[[components]]
name = "clipboard"
default = true
packages = ["wl-clipboard"] # Dropped cliphist (AUR tool)
[[components]]
name = "fonts"
default = true
packages = ["noto"]
[[components]]
name = "tools"
default = true
packages = [
"curl",
"git",
"jq",
"lazygit",
"bat",
"ripgrep",
"xdg-user-dirs",
]
post_install = ["xdg-user-dirs-update"]
--- Optional components ---
Note: Optional binary-only packages like 'vscodium-bin', 'todoist-appimage', and 'equibop'
are Linux-exclusive binaries. For FreeBSD, replaced with standard ports where supported.
[[components]]
name = "vscode"
packages = ["vscode"] # Standard FreeBSD open-source VSCode port name
[[components.entries]]
src = "vscode/settings.json"
dest = "$XDG_CONFIG_HOME/Code/User/settings.json"
[[components.entries]]
src = "vscode/keybindings.json"
dest = "$XDG_CONFIG_HOME/Code/User/keybindings.json"
[[components.entries]]
src = "vscode/flags.conf"
dest = "$XDG_CONFIG_HOME/code-flags.conf"
[[components]]
name = "zed"
packages = ["zed-editor"]
[[components]]
name = "discord"
packages = ["discord"] # Native FreeBSD discord port package
import subprocess
import shutil
import textwrap
from argparse import Namespace
from pathlib import Path
Cleaned up imports - removing legacy Arch modules
from caelestia.utils.dots.deployer import Deployer
from caelestia.utils.dots.manifest import ComponentError, Manifest, ManifestError
from caelestia.utils.dots.source import DotsSource, SourceError
from caelestia.utils.dots.state import DotsState
from caelestia.utils.io import confirm, disable_input, fatal, info, log, pause, prompt_selection, warn
from caelestia.utils.paths import (
config_backup_dir,
config_dir,
)
def _parse_list_arg(value: str | None) -> list[str] | None:
if value is None:
return None
return [item.strip() for item in value.split(",") if item.strip()]
class FreeBSDPackageInstaller:
"""Native FreeBSD Package Manager (pkg) Interface."""
class Command:
args: Namespace
Extra info
No response