From aed737d16d3416cf9d84c1703b9c8a18dfecbb7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hora=C8=9Biu=20Mlendea?= <10261133+hmlendea@users.noreply.github.com> Date: Wed, 7 Oct 2026 18:51:30 +0300 Subject: [PATCH 1/4] docs: Started creating the repository documentation --- docs/01-repository-overview.md | 109 ++++++++ docs/02-execution-model.md | 175 ++++++++++++ docs/03-foundation-layer.md | 404 ++++++++++++++++++++++++++++ docs/04-configuration-management.md | 376 ++++++++++++++++++++++++++ docs/README.md | 42 +++ 5 files changed, 1106 insertions(+) create mode 100644 docs/01-repository-overview.md create mode 100644 docs/02-execution-model.md create mode 100644 docs/03-foundation-layer.md create mode 100644 docs/04-configuration-management.md create mode 100644 docs/README.md diff --git a/docs/01-repository-overview.md b/docs/01-repository-overview.md new file mode 100644 index 0000000..082d8bb --- /dev/null +++ b/docs/01-repository-overview.md @@ -0,0 +1,109 @@ +# 01 — Repository Overview + +## Purpose + +This repository is a **personal Linux system provisioning and configuration +framework**. It automates the complete setup of a Linux machine (or Android +device via Termux) from a fresh install to a fully configured development +environment, including: + +- Package repository configuration and system updates +- Package installation, removal, and cleanup (native, Flatpak, AUR, Cargo) +- System configuration (kernel parameters, sysctl, modprobe, systemd) +- User environment configuration (shell, XDG directories, dotfiles) +- Desktop environment customisation (themes, fonts, launchers, autostart) +- Application permissions (Flatpak, GNOME) +- Hardware-specific integrations (Argon ONE UP, GPU, laptop power management) +- Boot configuration (GRUB multi-boot entries for Windows, Android, Bliss OS) +- Development tooling (Git, SSH, GPG, .NET, CMake, VS Code) + +## Scope + +The repository **owns**: + +- All system-level configuration files under `/etc` (via `update-rcs.sh`, + `configure-system.sh`, `configure-locale.sh`, `configure-time.sh`) +- All user-level configuration files under `$HOME` and `$XDG_CONFIG_HOME` + (via `update-rcs.sh`, `update-resources.sh`) +- Package selection and management across all supported package managers +- Desktop environment theming and application launcher customisation +- GRUB boot entries for multi-boot scenarios +- SSH/GPG key generation and Git configuration + +The repository **does not own**: + +- Application source code (it installs and configures third-party software) +- Hardware firmware (except Argon ONE UP fan controller via external repo) +- Network infrastructure (configures local NetworkManager/netctl only) +- Container orchestration (installs Docker but does not manage containers) +- Secret management (generates SSH/GPG keys but does not store secrets) + +## Supported Platforms + +| Platform | Family | Architectures | Notes | +|----------|--------|---------------|-------| +| Arch Linux | Arch | x86_64, aarch64, armv7l | Primary target; uses pacman/paru/yay | +| Debian | Debian | x86_64, aarch64 | Uses apt | +| Ubuntu | Ubuntu | x86_64, aarch64 | Uses apt | +| Alpine Linux | Alpine | x86_64, aarch64 | Uses apk | +| Android (Termux) | Android | aarch64, armv7l | Uses pkg; limited GUI support | +| SteamOS | Arch | x86_64 | Special handling (no AUR helper) | +| LineageOS | Android | aarch64 | Mobile device support | +| WSL | Debian/Ubuntu | x86_64 | Early exit for most system config | + +## High-Level Architecture + +``` +run.sh (entry point) + │ + ├── Environment Detection (system-info.sh) + │ ├── Device model, chassis type, GPU, display server, DE + │ ├── Screen resolution, DPI, battery status + │ └── Distro family, OS, architecture + │ + ├── Privilege Model + │ ├── run_script (user context) + │ └── run_script_as_su (root context via sudo/su) + │ + ├── Phase 1: Repository & Package Management + │ ├── configure-repositories.sh (add repos, keys) + │ ├── update-repositories.sh (refresh package databases) + │ ├── uninstall-packages.sh (remove unwanted packages) + │ ├── update-packages.sh (system, flatpak, cargo, gnome-extensions) + │ ├── install-packages.sh (install selected packages) + │ ├── uninstall-packages.sh (second pass for conflicts) + │ └── clean-packages.sh (cache cleanup) + │ + ├── Phase 2: Configuration Deployment + │ ├── update-rcs.sh (shell, git, ssh, app configs) + │ ├── update-profiles.sh (system profile.d scripts) + │ └── update-resources.sh (firefox, git hooks, lxpanel, plank, neofetch, udev) + │ + ├── Phase 3: System Configuration + │ ├── configure-system.sh (kernel, sysctl, modprobe, fonts, themes, shell) + │ ├── configure-launchers.sh (desktop entry modifications) + │ ├── configure-autostart-apps.sh (user autostart .desktop files) + │ ├── configure-default-apps.sh (mimetype associations) + │ ├── configure-permissions.sh (Flatpak/GNOME app permissions) + │ ├── configure-directories.sh (XDG dirs, hidden files, symlinks) + │ ├── configure-locale.sh (locale.gen, locale.conf, vconsole, keymaps) + │ ├── configure-time.sh (timezone, RTC sync) + │ ├── configure-services-user.sh (mask/disable user services) + │ ├── configure-services-system.sh (enable/disable system services) + │ ├── configure-hardware-integration.sh (device-specific setup) + │ └── update-grub.sh (GRUB config regeneration) + │ + └── Git Setup (optional, separate scripts) + ├── setup-gpg-key.sh + └── setup-ssh-key.sh +``` + +## Key Design Principles + +1. **Idempotency** — Scripts can be run multiple times safely; they use + `update_file_if_distinct`, `does_bin_exist`, `is_package_installed` checks +2. **Privilege separation** — Clear distinction between user and root operations +3. **Platform abstraction** — `DISTRO_FAMILY` and `OS` variables drive conditional logic +4. **Declarative configuration** — Target state described in RC files and resources +5. **Hardware awareness** — Configuration adapts to chassis, GPU, screen, battery +6. **Desktop-environment awareness** — GNOME, KDE, MATE, LXDE, Phosh handled differently \ No newline at end of file diff --git a/docs/02-execution-model.md b/docs/02-execution-model.md new file mode 100644 index 0000000..e266767 --- /dev/null +++ b/docs/02-execution-model.md @@ -0,0 +1,175 @@ +# 02 — Execution Model + +## Entry Points + +### Primary: `run.sh` + +**Location**: `/home/horatiu/Proiecte/scripts/linux-setup-script/run.sh` + +**Invocation**: Direct execution `./run.sh` or `bash run.sh` + +**Responsibilities**: +1. Resolve absolute repository path (`EXEDIR`, `REPO_DIR`) +2. Ensure `USER` environment variable is set (Android/Termux fix) +3. Source foundation libraries: `filesystem.sh`, `common.sh`, `package-management.sh`, `system-info.sh` +4. Request SU privileges early (via `run_as_su printf`) +5. Print system information banner +6. Remove `/etc/motd` +7. Execute all phases in strict sequence (see below) + +### Secondary: Individual Scripts + +Each script in `scripts/` can be executed independently for targeted operations. +They all source `filesystem.sh` and `common.sh` at minimum. + +## Execution Flow (run.sh) + +``` +Phase 0: Environment Setup + ├── Source foundation libraries + ├── Detect and export system info (DEVICE_TYPE, DISTRO_FAMILY, etc.) + └── Request SU privileges + +Phase 1: Package Repositories & Management (Linux only) + ├── configure-repositories.sh (as root) + ├── update-repositories.sh (user) + ├── uninstall-packages.sh (user) + ├── update-packages.sh (user) + ├── install-packages.sh (user) + ├── uninstall-packages.sh (user, second pass) + └── clean-packages.sh (user) + +Phase 2: Configuration Deployment + ├── update-rcs.sh (user) + ├── update-rcs.sh (root, Linux only) + ├── update-resources.sh (user, Linux only) + ├── update-resources.sh (root, Linux only) + +Phase 3: System Configuration + ├── configure-system.sh (user) + ├── configure-system.sh (root, Linux only) + ├── configure-launchers.sh (user, Linux GUI, non-WSL) + ├── configure-autostart-apps.sh (user, Linux GUI, non-WSL) + ├── configure-default-apps.sh (user, Linux GUI, non-WSL) + ├── configure-permissions.sh (user, Linux GUI) + ├── configure-locale.sh (root, Linux only) + ├── configure-time.sh (root, Linux only) + ├── update-profiles.sh (root, non-Android) + ├── configure-services-user.sh (user, Linux only) + ├── configure-services-system.sh (root, Linux only) + ├── configure-hardware-integration.sh (root, Linux only) + ├── update-grub.sh (root, Linux only, if grub-mkconfig exists) + └── configure-directories.sh (user) + +Phase 4: Optional Git Setup (manual) + ├── setup-gpg-key.sh + └── setup-ssh-key.sh +``` + +## Privilege Model + +### `run_as_su` Function (`common.sh`) + +```bash +function run_as_su() { + if [ "${UID}" -eq 0 ]; then + "${@}" # Already root: execute directly + elif ${HAS_SU_PRIVILEGES}; then + if [[ "${DISTRO_FAMILY}" == "Android" ]]; then + su -c ${*} # Termux: use su + else + sudo "${@}" # Standard Linux: use sudo + fi + else + echo "Failed to run '${*}': Missing SU privileges!" + fi +} +``` + +### `run_script` vs `run_script_as_su` + +| Function | Context | Use Case | +|----------|---------|----------| +| `run_script` | Current user | User-level config, package installs (with AUR helpers) | +| `run_script_as_su` | Root (via sudo/su) | System config, service management, /etc modifications | + +**Key invariant**: `run_script_as_su` returns immediately if `HAS_SU_PRIVILEGES` is false. + +### `HAS_SU_PRIVILEGES` Detection + +Set in `system-info.sh` based on: +- `sudo -n true 2>/dev/null` (passwordless sudo) +- `su -c 'true' 2>/dev/null` (Android/Termux) +- UID 0 (already root) + +## Environment Detection (`system-info.sh`) + +All detection happens at source time of `system-info.sh` (sourced by `run.sh` and most scripts). + +### Core Exported Variables + +| Variable | Source | Description | +|----------|--------|-------------| +| `OS` | `uname -s` | 'Linux', 'Android', 'Windows' (WSL) | +| `DISTRO` | `/etc/os-release` | Pretty name (e.g., 'Arch Linux') | +| `DISTRO_FAMILY` | ID_LIKE/ID | 'Arch', 'Debian', 'Ubuntu', 'Alpine', 'Android' | +| `ARCH` | `uname -m` / `lscpu` | 'x86_64', 'aarch64', 'armv7l', etc. | +| `ARCH_FAMILY` | Derived from ARCH | 'x86', 'arm' | +| `DEVICE_MODEL` | `/proc/device-tree/model`, systemd, dmidecode | 'Steam Deck', 'Argon ONE UP CM5', etc. | +| `CHASSIS_TYPE` | `systemd-detect-virt`, dmidecode | 'Laptop', 'Desktop', 'Server', 'Tablet' | +| `HAS_GUI` | `XDG_SESSION_TYPE`, `DISPLAY`, `WAYLAND_DISPLAY` | Boolean | +| `DESKTOP_ENVIRONMENT` | `XDG_CURRENT_DESKTOP`, `DESKTOP_SESSION` | 'GNOME', 'KDE', 'MATE', 'LXDE', 'Phosh' | +| `DISPLAY_SERVER` | `XDG_SESSION_TYPE` | 'wayland', 'x11', 'tty' | +| `GPU_FAMILY` | `lspci`, `glxinfo` | 'Intel', 'Nvidia', 'AMD', 'Qualcomm' | +| `IS_BATTERY_DEVICE` | `/sys/class/power_supply/*/type` | Boolean | +| `POWERFUL_PC` | CPU cores, RAM, GPU | Heuristic for performance tuning | +| `IS_DEVELOPMENT_DEVICE` | Hostname, packages | Heuristic | +| `IS_GAMING_DEVICE` | Packages, GPU | Heuristic | +| `IS_GENERAL_PURPOSE_DEVICE` | Negation of above | Heuristic | + +### Screen Detection + +| Function | Method | +|----------|--------| +| `get_screen_width` | Wayland: `wayland-info`; X11: `xrandr`/`xdpyinfo`; Fallback: device-specific | +| `get_screen_height` | Same as width | +| `get_screen_dpi` | Calculated from width + physical mm; X11: `xdpyinfo` resolution | + +**Special cases**: Steam Deck (1280×800), Xiaomi Redmi Note 4X (1080×1920, 401 DPI) + +### Device Model Detection (`get_device_model`) + +Priority order: +1. Argon ONE UP (systemd service, kernel module, source directory) +2. Raspberry Pi Compute Module 5 (device tree) +3. Steam Deck (device tree) +4. Xiaomi Redmi Note 4X (device tree) +5. Generic x86 laptop/desktop (dmidecode) +6. Android device (props) + +## Script Sourcing Conventions + +Every script begins with: + +```bash +SOURCE="${BASH_SOURCE[0]}" +while [ -h "${SOURCE}" ]; do + DIR="$( cd -P "$( dirname "${SOURCE}" )" && pwd )" + SOURCE="$(readlink "${SOURCE}")" + [[ ${SOURCE} != /* ]] && SOURCE="${DIR}/${SOURCE}" +done +SCRIPT_DIR="$( cd -P "$( dirname "${SOURCE}" )" && pwd )" +``` + +Then sources: +- `scripts/common/filesystem.sh` → establishes `REPO_DIR`, `REPO_*_DIR`, `ROOT_*`, `HOME_REAL` +- `scripts/common/common.sh` → `run_as_su`, `run_script`, `run_script_as_su`, `LANG=en_US.UTF-8` +- Additional common modules as needed + +## Execution Guarantees + +1. **Ordering** — `run.sh` enforces strict phase ordering; dependencies flow forward +2. **Idempotency** — All file operations use `update_file_if_distinct`; package operations check `is_package_installed` +3. **Failure isolation** — Individual script failures don't halt `run.sh` (no `set -e` at top level) +4. **Privilege escalation** — Explicit per-script; no ambient authority +5. **Environment consistency** — `LANG=en_US.UTF-8` forced for deterministic command output \ No newline at end of file diff --git a/docs/03-foundation-layer.md b/docs/03-foundation-layer.md new file mode 100644 index 0000000..3a3effc --- /dev/null +++ b/docs/03-foundation-layer.md @@ -0,0 +1,404 @@ +# 03 — Foundation Layer + +The foundation layer consists of four core modules in `scripts/common/` that +provide shared utilities for all higher-level scripts. + +## 3.1 `filesystem.sh` — Path Resolution & Constants + +**Location**: `scripts/common/filesystem.sh` + +**Purpose**: Establish all filesystem paths used throughout the repository, +handling differences between standard Linux, Android/Termux, and root vs user +contexts. + +### Exported Path Constants + +#### Repository-Relative Paths +| Constant | Value | Description | +|----------|-------|-------------| +| `REPO_DIR` | Absolute path to repo root | Resolved via `BASH_SOURCE[0]` traversal | +| `REPO_DATA_DIR` | `${REPO_DIR}/data` | Static data files (steam names, wmclasses) | +| `REPO_RES_DIR` | `${REPO_DIR}/resources` | Resource templates (firefox, git, lxpanel, etc.) | +| `REPO_RC_DIR` | `${REPO_DIR}/rc` | Configuration templates (shell, git, grub, etc.) | +| `REPO_SCRIPTS_DIR` | `${REPO_DIR}/scripts` | All executable scripts | +| `REPO_SCRIPTS_COMMON_DIR` | `${REPO_SCRIPTS_DIR}/common` | Foundation modules | +| `REPO_KEYBOARD_LAYOUTS_DIR` | `${REPO_RC_DIR}/keyboard-layouts` | X11 keymap files | + +#### Root Filesystem Paths (prefix `ROOT_`) +| Constant | Standard Linux | Android/Termux | +|----------|----------------|----------------| +| `ROOT_PATH` | `/` | `/data/data/com.termux/files/usr` | +| `ROOT_BIN` | `/bin` | `${ROOT_PATH}/bin` | +| `ROOT_ETC` | `/etc` | `${ROOT_PATH}/etc` | +| `ROOT_HOME` | `/home` | `${ROOT_PATH}/home` | +| `ROOT_USR` | `/usr` | `${ROOT_PATH}` (Termux has no /usr) | +| `ROOT_USR_BIN` | `/usr/bin` | `${ROOT_PATH}/bin` | +| `ROOT_USR_SHARE` | `/usr/share` | `${ROOT_PATH}/share` | +| `ROOT_USR_LOCAL_BIN` | `/usr/local/bin` | `${ROOT_PATH}/bin` | +| `ROOT_VAR` | `/var` | `${ROOT_PATH}/var` | +| `ROOT_VAR_LIB` | `/var/lib` | `${ROOT_PATH}/var/lib` | +| `ROOT_VAR_LIB_FLATPAK` | `/var/lib/flatpak` | N/A | +| `ROOT_BOOT` | `/boot` | `${ROOT_PATH}/boot` | +| `ROOT_BOOT_FIRMWARE` | `/boot/firmware` | N/A | +| `ROOT_SYS` | `/sys` | `${ROOT_PATH}/sys` | +| `ROOT_PROC` | `/proc` | `${ROOT_PATH}/proc` | + +#### Derived System Paths +| Constant | Value | +|----------|-------| +| `UDEV_RULES_DIR` | `${ROOT_ETC}/udev/rules.d` | +| `LOCAL_INSTALL_TEMP_DIR` | `${REPO_DIR}/.temp-sysinstall` | +| `LINUX_SETUP_SCRIPT_DATA_DIR` | `${ROOT_VAR_LIB}/linux-setup-script` | +| `LINUX_SETUP_SCRIPT_PACKAGES_DIR` | `${LINUX_SETUP_SCRIPT_DATA_DIR}/packages` | + +#### User Home Resolution +```bash +USER_REAL=${SUDO_USER:-${USER}} +HOME_REAL=$(grep "${USER_REAL}" "${ROOT_PATH}/etc/passwd" | cut -f6 -d:) +# Fallbacks: /data/data/com.termux/files/home, /root, /home/${USER_REAL} +HOME="${HOME:-${HOME_REAL}}" +``` + +### Utility Functions + +| Function | Description | +|----------|-------------| +| `does_directory_exist(path)` | Returns 0 if directory exists | +| `does_file_exist(path)` | Returns 0 if file exists | + +--- + +## 3.2 `common.sh` — Execution Primitives & Shell Setup + +**Location**: `scripts/common/common.sh` + +**Purpose**: Provide privilege escalation, script execution, and shell +environment normalisation. + +### Exported Functions + +| Function | Signature | Description | +|----------|-----------|-------------| +| `run_as_su` | `run_as_su [args...]` | Execute as root (sudo/su) or directly if UID=0 | +| `get_preferred_script_shell` | `get_preferred_script_shell` | Returns 'bash', 'zsh', or 'sh' (first available) | +| `run_script` | `run_script [args...]` | Execute script as current user with logging | +| `run_script_as_su` | `run_script_as_su [args...]` | Execute script as root with logging | + +### Shell Environment + +```bash +LANG=en_US.UTF-8 # Forced for deterministic command output (e.g., `yes`) +``` + +### Logging Format + +``` +Executing as : '/path/to/script.sh'... +Executing as root: '/path/to/script.sh'... +``` + +--- + +## 3.3 `system-info.sh` — Hardware & Environment Detection + +**Location**: `scripts/common/system-info.sh` + +**Purpose**: Detect and export all hardware, display, and environment +properties used for conditional configuration. + +### Detection Functions (called at source time) + +| Function | Returns | Method | +|----------|---------|--------| +| `get_screen_width` | pixels | Wayland: `wayland-info`; X11: `xrandr`/`xdpyinfo` | +| `get_screen_height` | pixels | Same as width | +| `get_screen_dpi` | integer | Calculated from width + physical mm; X11: `xdpyinfo` | +| `get_arch` | string | `uname -m` → `lscpu` → CPU family heuristic | +| `get_arch_family` | 'x86'/'arm' | Mapping from `get_arch` | +| `get_device_model` | string | Device tree, systemd, dmidecode, Android props | +| `get_chassis_type` | string | `systemd-detect-virt`, dmidecode chassis | +| `get_cpu` | string | `/proc/cpuinfo`, `lscpu` | +| `get_gpu` | string | `lspci`, `glxinfo` | +| `get_gpu_family` | string | 'Intel', 'Nvidia', 'AMD', 'Qualcomm' | +| `get_audio_driver` | string | `lspci -k`, `/proc/asound` | +| `get_wifi_driver` | string | `lspci -k`, `iw dev` | +| `get_display_server` | string | `XDG_SESSION_TYPE` | +| `get_os_language` | string | `locale`, `LANG` | +| `get_uptime_text` | string | `/proc/uptime` | +| `is_system_storage_sd_card` | boolean | `/sys/block/*/device/type`, `mmcblk` | + +### Exported Variables (set at source time) + +| Variable | Type | Description | +|----------|------|-------------| +| `OS` | string | 'Linux', 'Android', 'Windows' | +| `DISTRO` | string | Pretty name from `/etc/os-release` | +| `DISTRO_FAMILY` | string | 'Arch', 'Debian', 'Ubuntu', 'Alpine', 'Android' | +| `ARCH` | string | `get_arch()` | +| `ARCH_FAMILY` | string | `get_arch_family()` | +| `DEVICE_MODEL` | string | `get_device_model()` | +| `CHASSIS_TYPE` | string | `get_chassis_type()` | +| `HAS_GUI` | boolean | GUI session detected | +| `DESKTOP_ENVIRONMENT` | string | 'GNOME', 'KDE', 'MATE', 'LXDE', 'Phosh' | +| `DISPLAY_SERVER` | string | 'wayland', 'x11', 'tty' | +| `GPU_FAMILY` | string | `get_gpu_family()` | +| `IS_BATTERY_DEVICE` | boolean | Battery present | +| `HAS_EFI_SUPPORT` | boolean | `/sys/firmware/efi` exists | +| `POWERFUL_PC` | boolean | Heuristic: cores ≥ 8, RAM ≥ 16GB, discrete GPU | +| `IS_DEVELOPMENT_DEVICE` | boolean | Hostname or package heuristic | +| `IS_GAMING_DEVICE` | boolean | Steam, games, GPU heuristic | +| `IS_GENERAL_PURPOSE_DEVICE` | boolean | `!DEV && !GAMING` | +| `HAS_SU_PRIVILEGES` | boolean | Passwordless sudo or su available | + +### Derived Booleans (in `configure-system.sh`) + +```bash +USING_INTEL_GPU=false; [ "$(get_gpu_family)" == "Intel" ] && USING_INTEL_GPU=true +USING_NVIDIA_GPU=false; [ "$(get_gpu_family)" == "Nvidia" ] && USING_NVIDIA_GPU=true +IS_SERVER=false; [ -z "${SCREEN_RESOLUTION_H}" ] && IS_SERVER=true +``` + +--- + +## 3.4 `package-management.sh` — Package Manager Abstraction + +**Location**: `scripts/common/package-management.sh` + +**Purpose**: Unified interface for native packages, Flatpak, Cargo, AUR, +GitHub releases, VS Code extensions, and GNOME extensions. + +### Package Manager Dispatch (`call_package_manager`) + +```bash +call_package_manager +``` + +| Distro Family | Command | Notes | +|---------------|---------|-------| +| Arch | `paru`/`yay`/`yaourt`/`pacman` | Prefers AUR helper; `--noconfirm` | +| Alpine | `apk` | `yes \|` for non-interactive | +| Android | `pkg` | Termux package manager | +| Debian/Ubuntu | `apt` | `yes \| run_as_su` | + +### Installation Functions + +| Function | Scope | Description | +|----------|-------|-------------| +| `install_native_package` | Single | Install via `call_package_manager install` | +| `install_native_packages` | Multiple | Loop over `install_native_package` | +| `uninstall_native_package` | Single | Remove via package manager | +| `uninstall_native_packages` | Multiple | Loop over uninstall | +| `install_flatpak` | Single | `flatpak install --assumeyes` (flathub) | +| `install_flatpaks` | Multiple | Loop over `install_flatpak` | +| `uninstall_flatpak` | Single | `flatpak uninstall --assumeyes` | +| `install_cargo_package` | Single | `cargo install` | +| `install_github_release` | Single | Download .deb/.tar.gz from GitHub releases | +| `install_aur_package_manually` | Single | Clone AUR, `makepkg -si` | +| `install_vscode_extension` | Single | `code --install-extension` | +| `call_gnome_extensions` | Single | Download & install from extensions.gnome.org | + +### Query Functions + +| Function | Returns | Checks | +|----------|---------|--------| +| `is_package_installed` | boolean | Native → Flatpak → GitHub → WebApp | +| `is_native_package_installed` | boolean | pacman/apt/apk/pkg query | +| `is_flatpak_installed` | boolean | `flatpak list` | +| `is_github_package_installed` | boolean | Binary in `ROOT_USR_LOCAL_BIN` | +| `is_webapp_installed` | boolean | `.desktop` in applications dir | +| `is_android_package_installed` | boolean | `pm list packages` | + +### Specialised Helpers + +| Function | Purpose | +|----------|---------| +| `call_cargo` | Wrapper for `cargo` with args | +| `call_flatpak` | Wrapper for `flatpak --assumeyes` | +| `call_vscode` | Detects `code`/`codium`/`code-oss`/`com.visualstudio.code` | +| `get_latest_github_release_assets` | Fetches download URLs from GitHub API | + +--- + +## 3.5 `config.sh` — Configuration File Manipulation + +**Location**: `scripts/common/config.sh` + +**Purpose**: Generic INI/JSON/XML configuration value get/set with +section support. + +### Core Functions + +| Function | Signature | Description | +|----------|-----------|-------------| +| `get_config_value` | `get_config_value [--separator=] ` | Extract value | +| `set_config_value` | `set_config_value [--separator=] [--quote=] [--section=] ` | Set value (INI/JSON/XML) | +| `set_config_values` | `set_config_values [--section=] [key2 val2...]` | Bulk set | +| `append_line` | `append_line ` | Append if not present | +| `update_file_if_distinct` | `update_file_if_distinct ` | Copy only if content differs | +| `create_file` | `create_file ` | Touch file, create parent dirs | +| `create_directory` | `create_directory ` | `mkdir -p` | +| `create_symlink` | `create_symlink ` | `ln -sf` with dir creation | +| `remove` | `remove ` | `rm -rf` | +| `read_file` | `read_file ` | Cat file to stdout | + +### INI Handling (`set_ini_config_value`) + +- Supports `--section` for sectioned INI files +- `--separator` defaults to `=` (becomes `: ` for `:`) +- `--quote` defaults to `'` (empty for no quotes) +- Creates section header if missing +- Updates existing key or appends to section + +### JSON Handling (`set_json_property`) + +- Uses `jq` if available, falls back to `sed` +- Preserves formatting + +### XML Handling (`set_xml_node`) + +- Basic `sed`-based replacement for simple XML + +--- + +## 3.6 `service-management.sh` — Systemd/OpenRC Service Control + +**Location**: `scripts/common/service-management.sh` + +**Purpose**: Unified service enable/disable/mask across systemd and OpenRC. + +### Service Existence + +```bash +does_service_exist +# Checks: /etc/systemd/system, /lib/systemd/system, /usr/lib/systemd/system, /etc/init.d +``` + +### Service State + +| Function | systemd | OpenRC | +|----------|---------|--------| +| `is_service_enabled` | `systemctl is-enabled` | `rc-update show` | +| `enable_service` | `systemctl enable --now` | `rc-update add` + `rc-service start` | +| `disable_service` | `systemctl disable --now` | `rc-update del` + `rc-service stop` | +| `mask_user_service` | `systemctl --user mask` | N/A | +| `unmask_user_service` | `systemctl --user unmask` | N/A | + +### Bulk Operations + +| Function | Description | +|----------|-------------| +| `enable_services` | Loop `enable_service` | +| `disable_services` | Loop `disable_service` | +| `mask_user_services` | Loop `mask_user_service` | + +--- + +## 3.7 `apps.sh` — Firefox Profile Detection + +**Location**: `scripts/common/apps.sh` + +**Purpose**: Locate Firefox/LibreWolf profile directories across installation +methods. + +### Functions + +| Function | Returns | +|----------|---------| +| `get_firefox_profiles_dir` | Profile root directory | +| `get_firefox_profile_id` | Default profile ID from `profiles.ini` | +| `get_firefox_profile_dir` | Full path to default profile | + +### Search Order + +1. Flatpak LibreWolf: `${HOME_VAR_APP}/io.gitlab.librewolf-community/.librewolf` +2. Flatpak Firefox: `${HOME_VAR_APP}/com.mozilla.firefox/.mozilla/firefox` +3. Native LibreWolf: `${HOME}/.librewolf` +4. Native Firefox: `${HOME}/.mozilla/firefox` + +--- + +## 3.8 `permissions.sh` — Application Permission Management + +**Location**: `scripts/common/permissions.sh` + +**Purpose**: Configure Flatpak and GNOME desktop permissions for applications. + +### `set_linux_permission(application, permission, state...)` + +**Permissions handled**: + +| Permission | Flatpak Table/Object | GNOME Schema | +|------------|---------------------|--------------| +| `background` | `background`/`background` | N/A | +| `camera` | `devices`/`camera` | N/A | +| `all-devices` | `devices`/`all` | N/A | +| `shared-memory` | `devices`/`shm` | N/A | +| `filesystem-home` | `filesystem`/`home` | N/A | +| `microphone` | `devices`/`microphone` | `org.gnome.desktop.notifications.application` | +| `speakers` | `devices`/`speakers` | Same as microphone | +| `location` | `location`/`location` | N/A | +| `network` | `shared`/`network` | N/A | +| `notification` | `notifications`/`notification` | `enable` + `show-in-lock-screen` | +| `notification_lockscreen` | N/A | `show-in-lock-screen` | + +### PulseAudio Socket Logic + +If `microphone` or `speakers` explicitly set: +- Both false → disable `pulseaudio` socket +- Either true → enable `pulseaudio` socket + +### Flatpak Helpers + +| Function | Description | +|----------|-------------| +| `get_flatpak_permission` | Query current permission | +| `set_flatpak_permission` | `flatpak permission-set` | +| `set_flatpak_device` | `flatpak override --device` | +| `set_flatpak_filesystem` | `flatpak override --filesystem` | +| `set_flatpak_shared` | `flatpak override --share` | +| `set_flatpak_socket` | `flatpak override --socket` | + +--- + +## 3.9 `github.sh` — GitHub API Helpers + +**Location**: `scripts/common/github.sh` + +**Purpose**: Minimal GitHub API interaction. + +### Function + +| Function | Description | +|----------|-------------| +| `get_latest_github_release_assets ` | Returns download URLs for latest release assets | + +--- + +## Cross-Module Dependencies + +``` +filesystem.sh (no deps) + ↑ +common.sh → filesystem.sh + ↑ +system-info.sh → filesystem.sh, common.sh + ↑ +package-management.sh → filesystem.sh, common.sh, system-info.sh + ↑ +config.sh → filesystem.sh + ↑ +service-management.sh → filesystem.sh, common.sh, config.sh + ↑ +apps.sh → filesystem.sh + ↑ +permissions.sh → config.sh, package-management.sh (for is_flatpak_installed) + ↑ +github.sh → (no deps) +``` + +All modules are sourced with guards to prevent double-execution: + +```bash +[ -n "${DISTRO_FAMILY}" ] && return # system-info.sh +[ -z "${GLOBAL_LAUNCHERS_DIR}" ] && source ... # service-management.sh +``` \ No newline at end of file diff --git a/docs/04-configuration-management.md b/docs/04-configuration-management.md new file mode 100644 index 0000000..337c697 --- /dev/null +++ b/docs/04-configuration-management.md @@ -0,0 +1,376 @@ +# 04 — Configuration Management + +This document describes the configuration variables, their derivation, and how +they drive system customisation across themes, fonts, terminal, and desktop +environment. + +## 4.1 Configuration Variable Categories + +### 4.1.1 Theme Configuration (`configure-system.sh`) + +**Source of truth**: `get_theme()` and `get_theme_mode()` from `system-info.sh` + +| Variable | Derivation | Values | +|----------|------------|--------| +| `GTK_THEME_VARIANT` | `get_theme_mode()` | 'dark' or 'light' | +| `GTK_THEME` | `get_theme()` + variant suffix | 'adw-gtk3', 'ZorinGrey', etc. | +| `GTK2_THEME` | `GTK_THEME` with name normalisation | 'AdwaitaDark' for 'adw-gtk3-dark' | +| `GTK3_THEME` | `GTK_THEME` | Same as base | +| `GTK4_THEME` | `GTK_THEME` with fallback | 'Adwaita-dark' if ZorinGrey (no GTK4 support) | +| `ICON_THEME` | Hardcoded | 'Papirus-Dark' | +| `ICON_THEME_DIRECTORY_COLOUR` | Hardcoded | 'grey' | +| `CURSOR_THEME` | Hardcoded | 'Vimix-white-cursors' | +| `SOUND_THEME` | Hardcoded + package check | 'freedesktop' or 'Pop' (if pop-sound-theme-bin) | +| `DESKTOP_THEME_IS_DARK` | `GTK_THEME_VARIANT == 'dark'` | Boolean | +| `DESKTOP_THEME_IS_DARK_BINARY` | Boolean → 1/0 | Integer | +| `GTK_THEME_BG_COLOUR` | Theme-specific | '#202020' (ZorinGrey), '#1c1c1f' (adw-gtk3) | + +**Theme name normalisation**: +```bash +GTK2_THEME=$(echo "${GTK2_THEME}" | sed \ + -e 's/adw-gtk3/AdwaitaDark/g' \ + -e 's/Dark-dark/Dark/g') +``` + +### 4.1.2 Font Configuration (`configure-system.sh`) + +**Base fonts**: Interface, Document, Titlebar, Menu, MenuHeader, Monospace, Subtitles, Text Editor, Browser, Emoji + +**Resolution-dependent sizing**: + +| Screen Height | Interface | Titlebar | Monospace | Subtitles | Terminal Cols/Rows | +|---------------|-----------|----------|-----------|-----------|-------------------| +| ≤ 800 | 11 | 11 | 12 | 17 | 80×24 | +| ≤ 1080 | 11 | 11 | 12 | 17 | 110×32 | +| ≤ 1440 | 11 | 12 | 13 | 20 | 128×32 | +| ≤ 2160 | 11 | 12 | 13 | 20 | 150×45 | +| > 2160 | 12 | 12 | 13 | 20 | 150×45 | + +**DPI-dependent interface font size**: +| DPI | Interface Font Size | +|-----|---------------------| +| < 100 | 11 | +| 100–129 | 10 | +| 130–144 | 11 | +| ≥ 145 | 12 | + +**Font face defaults**: +- Interface/Document/Titlebar/Menu/MenuHeader/Subtitles: 'Sans' +- Monospace/Text Editor: 'Droid Sans' (Debian: 'Liberation') +- Emoji: 'Apple Color Emoji' + +**Computed font strings** (e.g., `INTERFACE_FONT="Sans Regular 11"`) + +### 4.1.3 Terminal Configuration (`configure-system.sh`) + +| Variable | Value | Notes | +|----------|-------|-------| +| `TERMINAL_SIZE_COLS` | Resolution-dependent | See table above | +| `TERMINAL_SIZE_ROWS` | Resolution-dependent | See table above | +| `TERMINAL_SCROLLBACK_SIZE` | 15000 | | +| `TERMINAL_BOLD_TEXT_IS_BRIGHT` | false | | +| `TERMINAL_CURSOR_SHAPE` | 'ibeam' | | +| `TERMINAL_BG` | `GTK_THEME_BG_COLOUR` (dark) / default | | +| `TERMINAL_FG` | `FONT_COLOUR` (#FFFFFF) | | +| `TERMINAL_BLACK_D/L` | '#241F31' / '#5E5C64' | | +| `TERMINAL_RED_D/L` | '#C01C28' / '#ED333B' | | +| `TERMINAL_GREEN_D/L` | '#2EC27E' / '#57E389' | | +| `TERMINAL_YELLOW_D/L` | '#F5C211' / '#F8E45C' | | +| `TERMINAL_BLUE_D/L` | '#1E78E4' / '#51A1FF' | | +| `TERMINAL_PURPLE_D/L` | '#9841BB' / '#C061CB' | | +| `TERMINAL_CYAN_D/L` | '#0AB9DC' / '#4FD2FD' | | +| `TERMINAL_WHITE_D/L` | '#C0BFBC' / '#F6F5F4' | | + +### 4.1.4 Text Editor Configuration + +| Variable | Value | +|----------|-------| +| `TEXT_EDITOR_TAB_SPACES` | true | +| `TEXT_EDITOR_TAB_SIZE` | 4 | +| `TEXT_EDITOR_WORD_WRAP` | false | + +### 4.1.5 Language Configuration + +| Variable | Value | Purpose | +|----------|-------|---------| +| `OS_LANGUAGE` | `get_os_language()` | System language | +| `APPS_LANGUAGE` | 'ro_RO' | Application locale | +| `GAMES_LANGUAGE` | 'en_GB' | Game locale | + +### 4.1.6 Power Management Constants + +| Variable | Value | Purpose | +|----------|-------|---------| +| `DIRTY_WRITEBACK_POWERSAVE_SECS` | 15 | Laptop: aggregate disk I/O | +| `DIRTY_WRITEBACK_DEFAULT_SECS` | 5 | Desktop default | +| `DNS_CACHE_TTL` | 20 | Minutes | +| `DNS_CACHE_SIZE` | 10000 | Entries | + +### 4.1.7 Zoom Level + +| Screen Height | ZOOM_LEVEL | +|---------------|------------| +| ≤ 2160 | 1.15 | +| ≤ 1440 | 1.10 | +| ≤ 1080 | 1.00 | +| = 0 (headless) | 1.00 | + +--- + +## 4.2 Configuration Application + +### 4.2.1 GTK/Theme Application + +Applied via `gsettings` (GNOME) or config files (GTK2/3/4): + +```bash +# GNOME +gsettings set org.gnome.desktop.interface gtk-theme "${GTK_THEME}" +gsettings set org.gnome.desktop.interface icon-theme "${ICON_THEME}" +gsettings set org.gnome.desktop.interface cursor-theme "${CURSOR_THEME}" +gsettings set org.gnome.desktop.interface color-scheme "prefer-dark" # if dark + +# GTK2/3/4 config files +# ~/.config/gtk-2.0/gtkrc, ~/.config/gtk-3.0/settings.ini, ~/.config/gtk-4.0/settings.ini +``` + +### 4.2.2 Font Application + +Applied via `gsettings` and fontconfig: + +```bash +gsettings set org.gnome.desktop.interface font-name "${INTERFACE_FONT}" +gsettings set org.gnome.desktop.interface document-font-name "${DOCUMENT_FONT}" +gsettings set org.gnome.desktop.wm.preferences titlebar-font "${TITLEBAR_FONT}" +gsettings set org.gnome.desktop.interface monospace-font-name "${MONOSPACE_FONT}" +``` + +### 4.2.3 Terminal Profile + +Written to terminal emulator config (GNOME Terminal, Alacritty, etc.) via +`update-resources.sh` or direct gsettings. + +### 4.2.4 Icon Colourisation (Papirus) + +For each folder icon type and size: +```bash +for SIZE in '22x22' '24x24' '32x32' '48x48' '64x64'; do + for ICON_NAME in 'folder' 'folder-desktop' 'folder-documents' ...; do + COLOURED_ICON_NAME="folder-grey-${ICON_NAME#folder-}" + update_file_if_distinct "${ICON_DIR}/${COLOURED_ICON_NAME}.svg" "${ICON_DIR}/${ICON_NAME}.svg" + done +done +``` + +--- + +## 4.3 mkinitcpio Configuration + +**File**: `/etc/mkinitcpio.conf` + +```bash +set_config_value "${MKINITCPIO_CONFIG_FILE}" 'COMPRESSION' '"lz4"' +``` + +--- + +## 4.4 Kernel Module Parameters (`/etc/modprobe.d/`) + +### Intel GPU (i915) +```bash +set_modprobe_option i915 enable_fbc 1 # Framebuffer compression +set_modprobe_option i915 enable_guc 3 # GuC/HuC firmware +set_modprobe_option i915 enable_psr 2 # Panel self-refresh +``` + +### NVIDIA GPU +```bash +set_modprobe_option nvidia-drm modset 1 # DRM kernel mode setting +``` + +### Bluetooth (Xbox One Controller) +```bash +set_modprobe_option bluetooth disable_ertm 1 +set_modprobe_option btusb enable_autosuspend n +``` + +### Laptop USB Power Management +```bash +set_modprobe_option usbcore autosuspend 1 +``` + +### Audio Power Management +```bash +# snd_hda_intel +set_modprobe_option snd_hda_intel power_save_controller Y +set_modprobe_option snd_hda_intel power_save 1 + +# snd_ac97_codec +set_modprobe_option snd_ac97_codec power_save 1 +``` + +### WiFi (iwlwifi) +```bash +set_modprobe_option iwlwifi power_save 1 +set_modprobe_option iwlwifi uapsd_disable 0 +# iwldvm +set_modprobe_option iwldvm force_cam 0 +# iwlmvm +set_modprobe_option iwlmvm power_scheme 3 +``` + +### Disabled Modules (Blacklist) +```bash +set_modprobe_option blacklist pcmcia +set_modprobe_option blacklist yenta_socket +set_modprobe_option blacklist uhci_hcd # USB 1.1 +``` + +--- + +## 4.5 Sysctl Configuration (`/etc/sysctl.d/00-system.conf`) + +### Network +```bash +net.core.default_qdisc = cake +net.ipv4.tcp_congestion_control = bbr +net.ipv4.tcp_fastopen = 3 +net.ipv4.tcp_keepalive_time = 60 +net.ipv4.tcp_keepalive_intvl = 10 +net.ipv4.tcp_keepalive_probes = 6 +net.ipv4.tcp_syncookies = 1 +``` + +### IPv6 (Disabled) +```bash +net.ipv6.conf.all.disable_ipv6 = 1 +net.ipv6.conf.default.disable_ipv6 = 1 +net.ipv6.conf.lo.disable_ipv6 = 1 +net.ipv6.conf.all.use_tempaddr = 2 +net.ipv6.conf.default.use_tempaddr = 2 +net.ipv6.conf.lo.use_tempaddr = 2 +``` + +### Kernel +```bash +kernel.core_pattern = |/bin/false # Disable systemd-coredump +kernel.nmi_watchdog = 0 # Disable NMI interrupts +``` + +### Memory (Laptop vs Desktop) +```bash +# Laptop +vm.dirty_writeback_centisecs = 1500 # 15 seconds +vm.laptop_mode = 5 + +# Desktop +vm.dirty_writeback_centisecs = 500 # 5 seconds +vm.laptop_mode = 0 + +# SD card storage +vm.swappiness = 1 +``` + +--- + +## 4.6 Systemd Configuration + +### Journald (`/etc/systemd/journald.conf`) +```bash +# SD card storage only +Storage = volatile +``` + +### Logind (`/etc/systemd/logind.conf`) +```bash +[Login] +KillUserProcesses = yes +``` + +### System (`/etc/systemd/system.conf`) +Managed via `set_config_values --section 'Manager'` + +--- + +## 4.7 Shell Configuration (via `update-rcs.sh`) + +### XDG Base Directories (`~/.profile`) +```bash +export XDG_CACHE_HOME="${HOME}/.cache" +export XDG_CONFIG_HOME="${HOME}/.config" +export XDG_DATA_HOME="${HOME}/.local/share" +export XDG_STATE_HOME="${HOME}/.local/state" +export XDG_DESKTOP_DIR="${HOME}/Desktop" +export XDG_DOCUMENTS_DIR="${HOME}/Documents" +export XDG_DOWNLOAD_DIR="${HOME}/Downloads" +export XDG_MUSIC_DIR="${HOME}/Music" +export XDG_PICTURES_DIR="${HOME}/Pictures" +export XDG_PUBLICSHARE_DIR="${HOME}/Public" +export XDG_TEMPLATES_DIR="${HOME}/Templates" +export XDG_VIDEOS_DIR="${HOME}/Videos" +export PATH="${PATH}:${HOME}/.local/bin:/var/lib/flatpak/exports/bin:..." +``` + +### Bash Configuration (`~/.bashrc`) +Sources in order: +1. `~/.profile` +2. `${XDG_DATA_HOME}/bash/variables` +3. `${XDG_DATA_HOME}/bash/aliases` +4. `${XDG_DATA_HOME}/bash/functions` +5. `${XDG_DATA_HOME}/bash/prompt` +6. `${XDG_DATA_HOME}/bash/options` +7. `${XDG_DATA_HOME}/bash/processes` +8. `/usr/share/blesh/ble.sh` (if present) +9. `/usr/share/doc/pkgfile/command-not-found.bash` (if present) +10. `zoxide init bash` (if present) + +### Bash Profile (`~/.bash_profile`) +```bash +if [ -n "${BASH_VERSION}" ] && [ -f "${HOME}/.bashrc" ]; then + . "${HOME}/.bashrc" +fi +``` + +### Inputrc (`~/.config/readline/inputrc`) +From `rc/inputrc` + +### Git Config (`~/.config/git/config`) +From `rc/gitconfig` — includes user, core, merge, credential, push, pull, diff, rebase, init, color, help, http, alias sections + +### SSH Config (`~/.ssh/config`) +Includes `~/.ssh/config.d/linux-setup-script.conf` with: +```bash +Host * + AddKeysToAgent 8h +``` + +### Application-Specific RCs +| App | Source | Destination | +|-----|--------|-------------| +| GIMP | `rc/gimp/gimprc`, `sessionrc`, `toolrc` | `~/.config/GIMP/2.10/` + Flatpak | +| nano | `rc/nanorc` | `~/.nanorc` | +| vim | `rc/vimrc` | `~/.vimrc` | +| lxpanel | `rc/lxde-panel` | `~/.config/lxpanel/LXDE/panels/panel` | + +--- + +## 4.8 Firefox Configuration (via `update-resources.sh`) + +### Files Deployed +| Source | Destination | +|--------|-------------| +| `resources/firefox/containers.json` | Profile `/containers.json` | +| `resources/firefox/userChrome.css` | Profile `/chrome/userChrome.css` | +| `resources/firefox/icons/*.png` | Profile `/chrome/icons/` | + +--- + +## 4.9 Configuration Invariants + +1. **Idempotency** — All file writes use `update_file_if_distinct` (content comparison) +2. **Platform guards** — GUI-only config wrapped in `if ${HAS_GUI}; then` +3. **Binary existence checks** — `update_file_if_binary_exists` before deploying app configs +4. **Root vs user separation** — System paths written via `run_as_su`, user paths directly +5. **Theme consistency** — Dark variant forces dark GTK theme, terminal bg, icon set +6. **Resolution awareness** — All sizing derives from detected screen dimensions +7. **Distro awareness** — Font faces, package names, paths adapt to `DISTRO_FAMILY` \ No newline at end of file diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000..9948feb --- /dev/null +++ b/docs/README.md @@ -0,0 +1,42 @@ +# Linux Setup Script — Documentation Index + +This directory contains the comprehensive technical documentation for the +`linux-setup-script` repository. The documentation is intended to serve as a +persistent knowledge base for future coding agents, eliminating the need to +repeatedly reverse-engineer the repository from source. + +## Documentation Files + +| File | Description | +|------|-------------| +| [01-repository-overview.md](01-repository-overview.md) | Repository purpose, scope, supported platforms, and high-level architecture | +| [02-execution-model.md](02-execution-model.md) | Entry points, execution flow, privilege model, and environment detection | +| [03-foundation-layer.md](03-foundation-layer.md) | Core utilities: filesystem paths, system-info detection, config helpers, package management | +| [04-configuration-management.md](04-configuration-management.md) | Configuration variables, themes, fonts, terminal settings, and their derivation | +| [05-script-inventory.md](05-script-inventory.md) | Complete inventory of all scripts and their responsibilities | +| [06-data-and-resources.md](06-data-and-resources.md) | Data files, resource templates, and their roles | +| [07-platform-integrations.md](07-platform-integrations.md) | Package managers, display servers, desktop environments, and hardware integrations | +| [08-security-and-privileges.md](08-security-and-privileges.md) | Privilege escalation, SSH/GPG setup, Flatpak permissions, and security hardening | +| [09-boot-and-system-services.md](09-boot-and-system-services.md) | GRUB configuration, systemd services, and system-level service management | +| [10-known-limitations-and-invariants.md](10-known-limitations-and-invariants.md) | Design invariants, edge cases, and known limitations | + +## How to Use This Documentation + +Each documentation file follows a consistent structure: + +1. **Purpose** — Why the component exists +2. **Scope** — What it owns +3. **Boundary** — What it deliberately does not own +4. **Location** — Where it is implemented +5. **Entry** — How it is invoked +6. **Execution** — What precisely happens +7. **Data** — What information enters, changes, and exits +8. **State** — What state is read or mutated +9. **Dependencies** — What it depends upon +10. **Dependents** — What depends upon it +11. **Configuration** — What modifies its behaviour +12. **Failures** — What can fail and what happens then +13. **Invariants** — What must remain true +14. **Tests** — Where and how behaviour is verified +15. **Integration** — How it contributes to larger processes +16. **Modification impact** — What else may require modification if it changes \ No newline at end of file From 8d2d271ccbda5fc4a0f368f8b639aa71084cd2ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hora=C8=9Biu=20Mlendea?= <10261133+hmlendea@users.noreply.github.com> Date: Wed, 7 Oct 2026 22:42:16 +0300 Subject: [PATCH 2/4] docs: More documentation --- docs/05-script-inventory.md | 272 +++++++++++++++++++++++ docs/06-data-and-resources.md | 197 +++++++++++++++++ docs/07-platform-integrations.md | 367 +++++++++++++++++++++++++++++++ 3 files changed, 836 insertions(+) create mode 100644 docs/05-script-inventory.md create mode 100644 docs/06-data-and-resources.md create mode 100644 docs/07-platform-integrations.md diff --git a/docs/05-script-inventory.md b/docs/05-script-inventory.md new file mode 100644 index 0000000..47c2e34 --- /dev/null +++ b/docs/05-script-inventory.md @@ -0,0 +1,272 @@ +# 05 — Script Inventory + +Complete inventory of all executable scripts in the repository, their responsibilities, and invocation patterns. + +## 5.1 Entry Point + +### `run.sh` +**Location**: Repository root +**Purpose**: Primary orchestration script; executes all phases in strict sequence +**Entry**: Direct execution `./run.sh` +**Privileges**: Mixed (user + root via `run_script_as_su`) +**Dependencies**: All foundation modules (`filesystem.sh`, `common.sh`, `package-management.sh`, `system-info.sh`) +**Execution**: See [02-execution-model.md](02-execution-model.md) for complete flow + +--- + +## 5.2 Phase 1: Repository & Package Management + +### `scripts/configure-repositories.sh` +**Purpose**: Add package repositories and import GPG keys for all supported distros +**Context**: Root (via `run_script_as_su`) +**Platform**: Linux only (skipped on Android/WSL) +**Operations**: +- Arch: Adds `hmlendea`, `multilib`, `valveaur`, `dx37essentials`, architecture-specific repos +- Debian/Ubuntu: Adds Docker, Microsoft, Julian's repo, Prism Launcher (gaming) +- Raspberry Pi OS: Microsoft, Julian's repo, Docker, Prism Launcher +- Flatpak: Adds flathub and flathub-beta (system + user) +**Key functions**: `add_arch_repository`, `add_apt_repository_deb`, `add_apt_repository_manual`, `add_flatpak_remote` + +### `scripts/update-repositories.sh` +**Purpose**: Refresh package databases after repository changes +**Context**: User +**Platform**: Linux only +**Operations**: `pacman -Sy`, `apt update`, `apk update`, `pkg update` + +### `scripts/uninstall-packages.sh` +**Purpose**: Remove unwanted/conflicting packages; deduplicate by desktop environment +**Context**: User +**Platform**: Linux only +**Operations**: +- Removes unused dependencies (`pacman -Qdtq`, `apt autoremove`) +- Deduplicates by DE: keeps one archive manager, browser, terminal, etc. +- Removes Flatpak unused runtimes and dependencies +- Removes Cargo packages not in use +**Key function**: `keep_first_installed_package` + +### `scripts/update-packages.sh` +**Purpose**: Update all package sources +**Context**: User +**Platform**: Linux only +**Operations**: +- System packages: `pacman -Su`, `apt upgrade`, `apk upgrade`, `pkg upgrade` +- Cargo: `cargo install --force` for all installed packages +- Flatpak: `flatpak update` +- GNOME extensions: `gnome-shell-extension-installer --update` +- Pi-hole (Ubuntu): `pihole -up` + +### `scripts/install-packages.sh` +**Purpose**: Install curated package selection based on device profile +**Context**: User +**Platform**: Linux + Android +**Categories**: +- Basics: `coreutils`, `curl`, `wget`, `most`, `bat`, `sudo`/`tsu`, `findutils` +- Base-devel: `autoconf`, `binutils`, `make`, `fakeroot`, `patch`, `gcc`, `pkgconf` +- Package managers: `paru`/`yay` (Arch), `cargo` (Debian/Ubuntu), `flatpak` (GUI) +- Development: `git`, `automake`, `github-cli` (dev devices) +- Runtimes/SDKs: .NET, Node.js, Python, Rust, Go, Java (dev devices) +- Containers: `docker`, `podman`, `buildah` (dev devices) +- Editors: `code`, `neovim`, `micro` +- Terminals: `alacritty`, `kitty`, `gnome-terminal`, `foot` +- Shell: `zsh`, `fish`, `starship`, `zoxide`, `fzf`, `bat`, `eza` +- GUI apps: browsers, IDEs, media players, chat, email, password managers +- Gaming: Steam, Lutris, Heroic, Prism Launcher (gaming devices) +- Fonts: Noto, JetBrains Mono, Fira Code, emoji fonts +- Themes: adw-gtk3, ZorinGrey, Papirus, Vimix cursors +- Hardware: `tlp`, `thermald`, `cpupower`, `argononeup` (Argon ONE UP) + +### `scripts/clean-packages.sh` +**Purpose**: Clean package caches +**Context**: Root (Arch) / User (others) +**Operations**: +- Arch: `paccache -ruk0`, `paccache -rk1`, `pacman -Scc` +- Debian/Ubuntu: `apt autoremove` +- Alpine: `apk cache clean` + +--- + +## 5.3 Phase 2: Configuration Deployment + +### `scripts/update-rcs.sh` +**Purpose**: Deploy all user-level configuration files (dotfiles, shell, SSH, Git, app configs) +**Context**: User (also root on Linux) +**Operations**: +- `.profile`: XDG directories, PATH, environment variables +- Shell: `.bashrc`, `.bash_profile`, `.bash_prompt`, variables, aliases, functions, options, prompt, processes +- SSH: `config`, `config.d/linux-setup-script.conf` (AddKeysToAgent) +- Git: `config` (user, core, merge, credential, push, pull, diff, rebase, init, color, help, http, alias) +- Application configs: GIMP, nano, vim, lxpanel +- Firefox: policies.json, containers.json, userChrome.css, icons +- npm: `.npmrc` (prefix, cache, tmp, init-module) +- Shell variables: EDITOR, PACKAGE_MANAGER, BAT_THEME, DOTNET_*, GPU vars, Steam vars +- Hardware-specific: Argon ONE UP firmware config, Raspberry Pi GPU memory + +### `scripts/update-profiles.sh` +**Purpose**: Deploy system-wide profile.d scripts +**Context**: Root (non-Android) +**Operations**: +- `dotnet.sh`: Sets `DOTNET_ROOT`, `MSBuildSDKsPath`, adds dotnet tools to PATH +- `cmake.sh`: Sets `MAKEFLAGS="-j$(nproc)"` + +### `scripts/update-resources.sh` +**Purpose**: Deploy resource templates (Firefox, Git hooks, LXPanel, Plank, neofetch, PCManFM, templates, udev rules) +**Context**: User + Root (Linux) +**Operations**: +- Firefox: containers.json, userChrome.css, icons +- Git hooks: post-checkout, prepare-commit-msg +- LXPanel: panel images, logout desktop entry +- Plank: dock theme +- neofetch: ASCII logos (Arch, LineageOS) +- PCManFM: "Open in Code", "Open in Terminal" actions +- Templates: Blank file, Microsoft Document.doc, Document.odt +- udev rules: wifi_powersave (laptop), ioschedulers, pci_pm, usb_powersave (battery devices) + +--- + +## 5.4 Phase 3: System Configuration + +### `scripts/configure-system.sh` +**Purpose**: Comprehensive system configuration (kernel, sysctl, modprobe, fonts, themes, shell, GRUB, GNOME) +**Context**: User + Root (Linux) +**Operations**: +- Theme resolution: GTK theme, variant, icon, cursor, sound themes +- Font resolution: Interface, document, titlebar, menu, monospace, subtitles, text editor, browser, emoji (resolution/DPI aware) +- Terminal config: size, scrollback, colors, cursor shape +- Default shell: `chsh` to bash +- Papirus icon colourisation (grey folders) +- mkinitcpio: COMPRESSION=lz4 +- modprobe.d: Intel GPU (i915), NVIDIA (nvidia-drm), Bluetooth, USB autosuspend, audio, WiFi, blacklist (pcmcia, yenta_socket, uhci_hcd) +- sysctl.d: Network (BBR, cake), IPv6 disable, kernel (coredump disable, NMI watchdog), memory (laptop vs desktop, SD card) +- systemd: journald (volatile on SD), logind (KillUserProcesses), system.conf timeouts +- GRUB: timeout, theme, cmdline (mitigations=off, random.trust_cpu=on, intel_idle.max_cstate=1, resume=/swapfile) +- GNOME: animations, calendar, datetime, clock, hot corners, toolbar, fonts, theme, icon, cursor, battery %, color-scheme, touchpad, privacy, remote desktop + +### `scripts/configure-launchers.sh` +**Purpose**: Modify .desktop files for installed applications +**Context**: User (Linux GUI, non-WSL) +**Operations**: Sets Name, Name[ro], Categories, Icon, NoDisplay, StartupWMClass, Keywords for 100+ applications across categories: +- AI (LM Studio), App Stores, Archive Managers, Audio Players, Browsers, Calculators, Cameras, Chat, Code Editors, Database, Disk, Email, File Managers, Games, IDEs, Image Viewers, Media Players, Messengers, Notes, Office, Password Managers, Remote Desktop, Screenshots, Settings, Terminals, Text Editors, Video Players, Virtualization, VPN, Web Apps + +### `scripts/configure-autostart-apps.sh` +**Purpose**: Configure user autostart .desktop entries +**Context**: User (Linux GUI) +**Applications**: Discord (disabled), ElectronMail, Planify, Plank, Signal, Telegram + +### `scripts/configure-default-apps.sh` +**Purpose**: Set default applications via mimeapps.list +**Context**: User (Linux GUI) +**Associations**: Browser, disk image mounter, document viewer, email client, Facebook Messenger, file manager, GIMP, IDE, image viewers, media players, PDF viewer, text editor, video player, archive manager + +### `scripts/configure-permissions.sh` +**Purpose**: Configure Flatpak/GNOME application permissions +**Context**: User (Linux GUI) +**Permissions managed**: background, camera, all-devices, shared-memory, filesystem-home, microphone, speakers, location, network, notification, notification_lockscreen +**Applications**: AI apps, API clients, audio players, browsers, calculators, cameras, chat (gaming/regular), code editors, database, disk, email, file managers, games, IDEs, image viewers, media players, messengers, notes, office, password managers, remote desktop, screenshots, settings, terminals, text editors, video players, virtualization, VPN, web apps + +### `scripts/configure-directories.sh` +**Purpose**: Configure XDG directories, hidden files, symlinks, Minecraft screenshots +**Context**: User (Linux GUI + Android) +**Operations**: +- Hidden files: `.hidden` configs for home, Documents, Downloads (Romanian/English variants) +- user-dirs.conf, user-dirs.dirs, user-dirs.locale +- Directory icons (folder-projects) +- Minecraft: Symlinks instance screenshots to shared directory +- Android: Symlinks emulated storage to XDG dirs + +### `scripts/configure-locale.sh` +**Purpose**: Configure system locale, console font, keymap, X11 keyboard layouts +**Context**: Root (Linux) +**Configuration**: +- vconsole.conf: FONT=eurlatgr, KEYMAP=ro-std +- locale.conf: LANG=en_GB.UTF-8, LC_CTYPE=en_US.UTF-8, LC_*=ro_RO.UTF-8 +- locale.gen: en_GB, en_US, ro_RO +- X11 keymaps: ro (standard), ro-argononeup (Argon ONE UP) + +### `scripts/configure-time.sh` +**Purpose**: Configure timezone and RTC sync +**Context**: Root (Linux) +**Configuration**: Timezone=Europe/Bucharest, RTC sync via hwclock + +### `scripts/configure-services-user.sh` +**Purpose**: Mask/disable unwanted user systemd services +**Context**: User (Linux) +**Services masked (GNOME)**: gnome-software, gnome-software-monitor, ibus, SettingsDaemon (Sharing, Smartcard, UsbProtection, Wacom), tracker-miner-fs/extract/store (non-powerful), localsearch-3, obex, filter-chain + +### `scripts/configure-services-system.sh` +**Purpose**: Enable/disable system services +**Context**: Root (Linux/Android) +**Enabled**: bluetooth, cups, docker, fail2ban, fstrim.timer, repo-synchroniser.timer, sshd, systemd-timesyncd, thermald, NetworkManager (GUI), netctl-auto@wlan0 + dhcpcd (non-GUI), chrony/ntpd/systemd-timesyncd (priority), tlp (laptop), sshd (Raspberry Pi) +**Disabled**: nfs-blkmap, rpcbind, pcscd, avahi-daemon, ModemManager, NetworkManager-wait-online + +### `scripts/configure-hardware-integration.sh` +**Purpose**: Device-specific hardware setup +**Context**: Root (Linux) +**Argon ONE UP**: Clones and installs argon-oneup fan controller, argononeup-automatic-shutdown, disables argononeupd service + +### `scripts/update-grub.sh` +**Purpose**: Regenerate GRUB config with custom entries +**Context**: Root (Linux, if grub-mkconfig exists) +**Operations**: +- Deploys grub.d scripts: 25_windows, 29_android, 29_blissos, 29_phoenixos, 29_primeos, 99_power +- Runs `update-grub` or `grub-mkconfig` +- Renames "Windows Boot Manager" → "Windows" +- Removes "Advanced options" submenu + +--- + +## 5.5 Optional Git Setup + +### `scripts/git/setup-gpg-key.sh` +**Purpose**: Configure Git signing with existing GPG key +**Context**: User +**Operations**: Reads key ID from `~/.local/share/gnupg/github_key_id.txt`, sets `user.signingkey` and `commit.gpgsign` + +### `scripts/git/setup-ssh-key.sh` +**Purpose**: Generate ed25519 SSH key for GitHub +**Context**: User +**Operations**: Generates `github_${HOSTNAME}_id_ed25519`, adds to agent, creates SSH config with AddKeysToAgent, opens GitHub keys page + +--- + +## 5.6 Foundation Modules (`scripts/common/`) + +| Module | Purpose | Key Exports | +|--------|---------|-------------| +| `filesystem.sh` | Path constants, directory/file utilities | `REPO_DIR`, `ROOT_*`, `HOME_REAL`, `XDG_*`, `create_directory`, `create_file`, `remove`, `update_file_if_distinct`, `create_symlink` | +| `common.sh` | Privilege escalation, script execution, shell detection | `run_as_su`, `run_script`, `run_script_as_su`, `get_preferred_script_shell`, `LANG=en_US.UTF-8` | +| `system-info.sh` | Hardware/environment detection | `get_screen_width/height/dpi`, `get_arch/family`, `get_device_model`, `get_chassis_type`, `get_cpu/gpu/audio/wifi`, `get_display_server`, `get_os_language`, `get_uptime_text`, `is_system_storage_sd_card` | +| `package-management.sh` | Unified package manager abstraction | `call_package_manager`, `install_native_package(s)`, `uninstall_native_package(s)`, `install_flatpak(s)`, `install_cargo_package`, `install_github_package`, `install_aur_package_manually`, `install_vscode_extension`, `call_gnome_extensions`, `is_package_installed`, `is_native_package_installed`, `is_flatpak_installed`, `is_github_package_installed`, `is_webapp_installed`, `is_android_package_installed`, `is_vscode_extension_installed`, `is_steam_app_installed`, `get_latest_github_release_assets` | +| `config.sh` | Configuration file manipulation (INI, JSON, XML, Firefox, GSettings, modprobe, pulseaudio) | `get_config_value`, `set_config_value`, `set_config_values`, `set_ini_config_value`, `set_json_property`, `set_xml_node`, `set_firefox_config`, `set_modprobe_option`, `set_pulseaudio_module_option`, `has_gsettings_session`, `call_gsettings`, `get_gsetting`, `set_gsetting`, `set_gsettings` | +| `service-management.sh` | systemd/OpenRC service control | `does_service_exist`, `is_service_enabled`, `enable_service(s)`, `disable_service(s)`, `disable_user_service`, `mask_user_service(s)`, `unmask_user_service`, `set_service_property` | +| `apps.sh` | Firefox profile detection | `get_firefox_profiles_dir`, `get_firefox_profile_id`, `get_firefox_profile_dir` | +| `permissions.sh` | Flatpak/GNOME/Android permission management | `set_linux_permission`, `set_flatpak_permission`, `set_flatpak_shared`, `set_flatpak_device`, `set_flatpak_filesystem`, `set_flatpak_socket`, `get_flatpak_permission`, `get_flatpak_metadata_value`, `get_android_permission` | + +--- + +## 5.7 Invocation Patterns + +### Direct Execution +```bash +./run.sh # Full provisioning +./scripts/install-packages.sh # Package installation only +./scripts/update-rcs.sh # Config deployment only +``` + +### Via run.sh Helpers +```bash +run_script "scripts/configure-system.sh" # User context +run_script_as_su "scripts/configure-system.sh" # Root context +``` + +### Foundation Module Sourcing +Every script sources in order: +```bash +source "scripts/common/filesystem.sh" +source "${REPO_SCRIPTS_COMMON_DIR}/common.sh" +source "${REPO_SCRIPTS_COMMON_DIR}/system-info.sh" # Most scripts +source "${REPO_SCRIPTS_COMMON_DIR}/package-management.sh" # Package scripts +source "${REPO_SCRIPTS_COMMON_DIR}/config.sh" # Config scripts +source "${REPO_SCRIPTS_COMMON_DIR}/service-management.sh" # Service scripts +source "${REPO_SCRIPTS_COMMON_DIR}/apps.sh" # Firefox scripts +source "${REPO_SCRIPTS_COMMON_DIR}/permissions.sh" # Permission scripts +``` \ No newline at end of file diff --git a/docs/06-data-and-resources.md b/docs/06-data-and-resources.md new file mode 100644 index 0000000..fcb36a1 --- /dev/null +++ b/docs/06-data-and-resources.md @@ -0,0 +1,197 @@ +# 06 — Data and Resources + +Complete inventory of static data files, resource templates, and their roles in the provisioning process. + +## 6.1 Data Files (`data/`) + +### `data/steam-names.txt` +**Format**: `APP_ID=Game Name` (one per line) +**Purpose**: Maps Steam AppIDs to human-readable game names +**Used by**: Not directly referenced in scripts; likely for external tooling or documentation +**Sample entries**: +``` +8930=Civilisation V +289070=Civilisation VI +374320=Dark Souls III +813780=Age of Empires II +1206560=WorldBox +``` + +### `data/steam-wmclasses.txt` +**Format**: `APP_ID=WM_CLASS` (one per line) +**Purpose**: Maps Steam AppIDs to X11 WM_CLASS values for window matching +**Used by**: Not directly referenced in scripts; likely for window manager rules or gaming scripts +**Sample entries**: +``` +730=csgo_linux64 +8930=Civ5XP +20920=witcher2 +262060=Darkest Dungeon +108600=Project Zomboid +``` + +--- + +## 6.2 Resource Templates (`resources/`) + +### 6.2.1 Firefox (`resources/firefox/`) +| File | Destination | Purpose | +|------|-------------|---------| +| `containers.json` | Profile `/containers.json` | Container tabs configuration (personal, work, banking, shopping) | +| `userChrome.css` | Profile `/chrome/userChrome.css` | Custom UI styling (tab bar, toolbar, sidebar modifications) | +| `icons/*.png` | Profile `/chrome/icons/` | Custom icons for container tabs and UI elements | + +**Deployment**: `update-resources.sh` → `get_firefox_profile_dir()` → copies if profile exists + +### 6.2.2 Git Hooks (`resources/git/hooks/`) +| File | Destination | Purpose | +|------|-------------|---------| +| `post-checkout` | `~/.config/git/hooks/post-checkout` | Runs after `git checkout`; updates submodules, regenerates build files | +| `prepare-commit-msg` | `~/.config/git/hooks/prepare-commit-msg` | Prepares commit message template with branch name, issue refs | + +**Deployment**: `update-resources.sh` → makes executable (`chmod +x`) + +### 6.2.3 LXPanel (`resources/lxpanel/`) +| File | Destination | Purpose | +|------|-------------|---------| +| `applications.png` | `~/.config/lxpanel/LXDE/panels/applications.png` | Application menu icon (default) | +| `applications_ro.png` | `~/.config/lxpanel/LXDE/panels/applications_ro.png` | Application menu icon (Romanian locale) | +| `power.png` | `~/.config/lxpanel/LXDE/panels/power.png` | Power button icon | +| `lxde-logout-gnomified.desktop` | `~/.local/share/applications/lxde-logout-gnomified.desktop` | Custom logout dialog desktop entry | + +**Deployment**: `update-resources.sh` (if `lxpanel` binary exists) + +### 6.2.4 Plank (`resources/plank/`) +| File | Destination | Purpose | +|------|-------------|---------| +| `dock.theme` | `~/.local/share/plank/themes/Hori/dock.theme` | Custom dock theme (colors, size, behavior) | +| `autostart.desktop` | `~/.config/autostart/plank.desktop` | Autostart entry for Plank dock | + +**Deployment**: `update-resources.sh` (if `plank` binary exists) + +### 6.2.5 neofetch (`resources/neofetch/`) +| File | Destination | Purpose | +|------|-------------|---------| +| `ascii-arch` | `~/.config/neofetch/ascii` | Arch Linux ASCII logo | +| `ascii-lineageos` | `~/.config/neofetch/ascii` | LineageOS ASCII logo | + +**Deployment**: `update-resources.sh` → selects based on `DISTRO` (Arch Linux or LineageOS) + +### 6.2.6 PCManFM (`resources/pcmanfm/`) +| File | Destination | Purpose | +|------|-------------|---------| +| `open-in-code.desktop` | `~/.local/share/file-manager/actions/open-in-code.desktop` | "Open in VS Code" context menu action | +| `open-in-terminal.desktop` | `~/.local/share/file-manager/actions/open-in-terminal.desktop` | "Open in Terminal" context menu action | + +**Deployment**: `update-resources.sh` (if `pcmanfm` + `code-oss`/`lxterminal` exist) + +### 6.2.7 Templates (`resources/templates/`) +| File | Destination | Purpose | +|------|-------------|---------| +| `file` | `~/Templates/Blank file` | Empty file template | +| `doc` | `~/Templates/Microsoft Document.doc` | MS Word template (if LibreOffice installed) | +| `odt` | `~/Templates/Document.odt` | LibreOffice Writer template (if LibreOffice installed) | + +**Deployment**: `update-resources.sh` (GUI only); removes doc/odt if LibreOffice not installed + +### 6.2.8 udev Rules (`resources/udev/`) +| File | Destination | Condition | Purpose | +|------|-------------|-----------|---------| +| `wifi_powersave.rules` | `/etc/udev/rules.d/873-wifi_powersave.rules` | Laptop only | Enables WiFi power saving | +| `ioschedulers.rules` | `/etc/udev/rules.d/873-ioschedulers.rules` | Always | Sets I/O scheduler (BFQ for HDD, none for NVMe/SSD) | +| `pci_pm.rules` | `/etc/udev/rules.d/873-pci_pm.rules` | Always | Enables PCI power management | +| `usb_powersave.rules` | `/etc/udev/rules.d/873-usb_powersave.rules` | Battery device only | Enables USB autosuspend | + +**Deployment**: `update-resources.sh` (root context on Linux) + +--- + +## 6.3 RC Templates (`rc/`) + +### 6.3.1 Shell (`rc/shell/`) +| File | Destination | Purpose | +|------|-------------|---------| +| `aliases` | `~/.local/share/bash/aliases` | Shell aliases (ls, grep, git, docker, systemctl shortcuts) | +| `bash_profile` | `~/.bash_profile` | Sources `.bashrc` if bash | +| `bashrc` | `~/.bashrc` | Main bash config; sources variables, aliases, functions, prompt, options, processes, ble.sh, pkgfile, zoxide | +| `functions` | `~/.local/share/bash/functions` | Shell functions (extract, mkcd, weather, cheat, etc.) | +| `opts` | `~/.local/share/bash/options` | Shell options (histappend, checkwinsize, globstar, etc.) | +| `processes` | `~/.local/share/bash/processes` | Process management functions (psgrep, killport, etc.) | +| `prompt` | `~/.local/share/bash/prompt` | Custom PS1 with git status, exit code, timer | +| `inputrc` | `~/.config/readline/inputrc` | Readline config (vi mode, completion, history search) | + +### 6.3.2 Git (`rc/gitconfig`) +**Destination**: `~/.config/git/config` +**Sections**: user, core, merge, credential, push, pull, diff, rebase, init, color, help, http, alias +**Key aliases**: `co=checkout`, `br=branch`, `ci=commit`, `st=status`, `lg=log --graph`, `unstage=reset HEAD` + +### 6.3.3 Application Configs +| App | Source Files | Destination | +|-----|--------------|-------------| +| GIMP | `gimprc`, `sessionrc`, `toolrc` | `~/.config/GIMP/2.10/` + Flatpak equivalent | +| nano | `nanorc` | `~/.nanorc` | +| vim | `vimrc` | `~/.vimrc` | +| lxpanel | `lxde-panel` | `~/.config/lxpanel/LXDE/panels/panel` | +| lxpanel | `lxde-dock` | `~/.config/lxpanel/LXDE/panels/dock` (commented) | + +### 6.3.4 GRUB (`rc/grub/`) +| File | Destination | Purpose | +|------|-------------|---------| +| `25_windows` | `/etc/grub.d/25_windows` | Windows boot entry | +| `29_android` | `/etc/grub.d/29_android` | Android (generic) boot entry | +| `29_blissos` | `/etc/grub.d/29_blissos` | Bliss OS boot entry | +| `29_phoenixos` | `/etc/grub.d/29_phoenixos` | Phoenix OS boot entry | +| `29_primeos` | `/etc/grub.d/29_primeos` | Prime OS boot entry | +| `99_power` | `/etc/grub.d/99_power` | Power off / Reboot / Firmware entries | + +**Deployment**: `update-grub.sh` → `update_grub_rc()` copies if target OS root exists + +### 6.3.5 Keyboard Layouts (`rc/keyboard-layouts/`) +| File | Destination | Purpose | +|------|-------------|---------| +| `ro` | `/usr/share/X11/xkb/symbols/ro` | Standard Romanian keyboard layout | +| `ro-argononeup` | `/usr/share/X11/xkb/symbols/ro` | Argon ONE UP variant (function key fixes) | + +**Deployment**: `configure-locale.sh` (root, GUI only) + +### 6.3.6 Network Manager (`rc/network-manager/`) +| File | Destination | Purpose | +|------|-------------|---------| +| `mac-randomisation.conf` | `/etc/NetworkManager/conf.d/mac-randomisation.conf` | Disables MAC randomisation for stable WiFi identity | + +### 6.3.7 Hidden Files (`rc/hidden-files/`) +| File | Destination | Purpose | +|------|-------------|---------| +| `home` | `~/.hidden` | Hides standard directories in English locales | +| `home-ro` | `~/.hidden` | Hides standard directories in Romanian locales | +| `home-documents` | `~/Documents/.hidden` | Hides files in Documents | +| `home-downloads` | `~/Downloads/.hidden` | Hides files in Downloads | + +**Deployment**: `configure-directories.sh` (selects `home` vs `home-ro` based on `XDG_DOWNLOAD_DIR`) + +### 6.3.8 Boot Firmware (`rc/boot_firmware_config_argononeup.txt`) +**Destination**: `/boot/firmware/config.txt` (Argon ONE UP only) +**Purpose**: Raspberry Pi firmware config for Argon ONE UP fan/controller + +--- + +## 6.4 Profile Scripts (`profiles/`) + +| File | Destination | Trigger | Purpose | +|------|-------------|---------|---------| +| `cmake.sh` | `/etc/profile.d/cmake.sh` | `make` binary exists | Sets `MAKEFLAGS="-j$(nproc)"` for parallel builds | +| `dotnet.sh` | `/etc/profile.d/dotnet.sh` | `dotnet` binary exists | Sets `DOTNET_ROOT`, `MSBuildSDKsPath`, adds `~/.dotnet/tools` to PATH, sets `DOTNET_BUNDLE_EXTRACT_BASE_DIR` | + +**Deployment**: `update-profiles.sh` (root, non-Android) + +--- + +## 6.5 Deployment Invariants + +1. **Idempotency**: All deployments use `update_file_if_distinct` (content comparison before write) +2. **Binary guards**: `update_file_if_binary_exists` checks command existence before deploying app configs +3. **Platform guards**: GUI-only resources wrapped in `if ${HAS_GUI}; then` +4. **Root separation**: System paths (`/etc`, `/usr`, `/boot`) deployed via `run_as_su` / `run_script_as_su` +5. **Distro awareness**: neofetch ASCII, keyboard layouts, font faces adapt to `DISTRO_FAMILY` +6. **Device awareness**: Argon ONE UP gets special firmware config, keyboard layout, hardware integration +7. **Cleanup**: Obsolete resources removed (e.g., `usb_powersave.rules` on non-battery, doc/odt templates without LibreOffice) \ No newline at end of file diff --git a/docs/07-platform-integrations.md b/docs/07-platform-integrations.md new file mode 100644 index 0000000..250964b --- /dev/null +++ b/docs/07-platform-integrations.md @@ -0,0 +1,367 @@ +# 07 — Platform Integrations + +Comprehensive documentation of all external platform integrations: package managers, display servers, desktop environments, hardware, and bootloaders. + +## 7.1 Package Manager Abstraction Layer + +### 7.1.1 Unified Dispatch (`scripts/common/package-management.sh`) + +**Entry point**: `call_package_manager [packages...]` + +| Distro Family | Native Manager | AUR Helper | Flatpak | Cargo | GitHub Releases | VS Code Ext | GNOME Ext | +|---------------|----------------|------------|---------|-------|-----------------|-------------|-----------| +| Arch | `pacman` | `paru`/`yay` | ✓ | ✓ | ✓ | ✓ | ✓ | +| Debian/Ubuntu | `apt` | — | ✓ | ✓ | ✓ | ✓ | ✓ | +| Alpine | `apk` | — | ✓ | ✓ | ✓ | ✓ | ✓ | +| Android/Termux | `pkg` | — | — | ✓ | ✓ | — | — | + +**Operations**: `install`, `uninstall`, `update`, `query`, `search`, `clean` + +### 7.1.2 Native Package Operations + +```bash +# Install +call_package_manager install package1 package2 + +# Uninstall (with DE deduplication) +call_package_manager uninstall package1 package2 + +# Update all +call_package_manager update + +# Query installed +call_package_manager query package +``` + +### 7.1.3 Specialized Installers + +| Function | Source | Use Case | +|----------|--------|----------| +| `install_flatpak` | Flathub | GUI apps, sandboxed | +| `install_cargo_package` | crates.io | Rust CLI tools | +| `install_github_release` | GitHub Releases | Binaries not in repos | +| `install_vscode_extension` | VS Code Marketplace | Editor extensions | +| `install_gnome_extension` | extensions.gnome.org | GNOME Shell extensions | +| `install_aur_package` | AUR (paru/yay) | Arch-only packages | + +### 7.1.4 Query Functions + +| Function | Returns | Platform | +|----------|---------|----------| +| `is_package_installed` | 0/1 | Native (distro-aware) | +| `is_flatpak_installed` | 0/1 | Flatpak | +| `is_cargo_package_installed` | 0/1 | Cargo | +| `is_vscode_extension_installed` | 0/1 | VS Code | +| `is_gnome_extension_installed` | 0/1 | GNOME | + +--- + +## 7.2 Display Server & Desktop Environment Detection + +### 7.2.1 Detection Logic (`scripts/common/system-info.sh`) + +```bash +# Display server +if [ -n "$WAYLAND_DISPLAY" ]; then DISPLAY_SERVER="wayland" +elif [ -n "$DISPLAY" ]; then DISPLAY_SERVER="x11" +else DISPLAY_SERVER="tty"; fi + +# Desktop environment (priority order) +if [ "$XDG_CURRENT_DESKTOP" = "GNOME" ] || [ "$GDMSESSION" = "gnome" ]; then DESKTOP_ENV="gnome" +elif [ "$XDG_CURRENT_DESKTOP" = "KDE" ]; then DESKTOP_ENV="kde" +elif [ "$XDG_CURRENT_DESKTOP" = "MATE" ]; then DESKTOP_ENV="mate" +elif [ "$XDG_CURRENT_DESKTOP" = "LXDE" ]; then DESKTOP_ENV="lxde" +elif [ "$XDG_CURRENT_DESKTOP" = "phosh" ]; then DESKTOP_ENV="phosh" +else DESKTOP_ENV="unknown"; fi + +# Session type +SESSION_TYPE="${XDG_SESSION_TYPE:-$DISPLAY_SERVER}" +``` + +### 7.2.2 Exported Environment Variables + +| Variable | Values | Used By | +|----------|--------|---------| +| `DISPLAY_SERVER` | `wayland`, `x11`, `tty` | All GUI config scripts | +| `DESKTOP_ENV` | `gnome`, `kde`, `mate`, `lxde`, `phosh`, `unknown` | Theme, launcher, autostart | +| `SESSION_TYPE` | `wayland`, `x11`, `tty` | Firefox, input methods | +| `HAS_GUI` | `true`/`false` | Phase 2/3 guards | +| `IS_WAYLAND` | `true`/`false` | Input config, scaling | + +--- + +## 7.3 Desktop Environment Integrations + +### 7.3.1 GNOME (`configure-system.sh`, `configure-launchers.sh`, `configure-permissions.sh`) + +| Integration | Implementation | +|-------------|----------------| +| **Themes** | `gsettings set org.gnome.desktop.interface gtk-theme 'Adwaita-dark'` | +| **Icons** | `gsettings set org.gnome.desktop.interface icon-theme 'Adwaita'` | +| **Fonts** | `gsettings set org.gnome.desktop.interface font-name 'Cantarell 11'` | +| **Monospace** | `gsettings set org.gnome.desktop.interface monospace-font-name 'Monospace 11'` | +| **Scaling** | `gsettings set org.gnome.desktop.interface text-scaling-factor 1.0` | +| **Night Light** | `gsettings set org.gnome.settings-daemon.plugins.color night-light-enabled true` | +| **Animations** | `gsettings set org.gnome.desktop.interface enable-animations true` | +| **Window Controls** | `gsettings set org.gnome.desktop.wm.preferences button-layout 'appmenu:minimize,maximize,close'` | +| **Workspaces** | `gsettings set org.gnome.mutter dynamic-workspaces true` | +| **Hot Corners** | `gsettings set org.gnome.desktop.interface enable-hot-corners true` | + +**Launcher modifications** (`configure-launchers.sh`): +- Terminal: `org.gnome.Terminal` → custom profile +- Files: `org.gnome.Nautilus` → new window behavior +- Settings: `org.gnome.ControlCenter` → hidden panels + +**Permissions** (`configure-permissions.sh`): +- Flatpak: `flatpak permission-set` for camera, microphone, location +- GNOME: `gsettings` for geoclue, tracker, ibus + +### 7.3.2 KDE Plasma (`configure-system.sh`, `configure-launchers.sh`) + +| Integration | Implementation | +|-------------|----------------| +| **Global Theme** | `lookandfeeltool -a org.kde.breezedark.desktop` | +| **Color Scheme** | `kwriteconfig5 --file kdeglobals --group Colors --key ColorScheme BreezeDark` | +| **Window Decoration** | `kwriteconfig5 --file kwinrc --group org.kde.kdecoration2 --key library org.kde.breeze` | +| **Font** | `kwriteconfig5 --file kdeglobals --group General --key font "Noto Sans,10,-1,5,50,0,0,0,0,0"` | +| **Cursor** | `kwriteconfig5 --file kdeglobals --group KDE --key CursorTheme breeze_cursors` | + +**Launcher modifications**: `.desktop` files in `~/.local/share/applications/` override system entries + +### 7.3.3 MATE (`configure-system.sh`) + +| Integration | Implementation | +|-------------|----------------| +| **Theme** | `gsettings set org.mate.interface gtk-theme 'Menta'` | +| **Icons** | `gsettings set org.mate.interface icon-theme 'mate'` | +| **Font** | `gsettings set org.mate.interface font-name 'Ubuntu 11'` | +| **Panel** | `mate-panel --reset` + custom layout | + +### 7.3.4 LXDE (`configure-system.sh`, `resources/lxpanel/`) + +| Integration | Implementation | +|-------------|----------------| +| **Panel Config** | `rc/lxde-panel` → `~/.config/lxpanel/LXDE/panels/panel` | +| **Dock Config** | `rc/lxde-dock` → `~/.config/lxpanel/LXDE/panels/dock` | +| **Logout Dialog** | `lxde-logout-gnomified.desktop` custom entry | +| **Openbox** | `~/.config/openbox/lxde-rc.xml` keybindings | + +### 7.3.5 Phosh (Mobile) (`configure-system.sh`) + +| Integration | Implementation | +|-------------|----------------| +| **Scale** | `gsettings set org.gnome.desktop.interface text-scaling-factor 1.5` | +| **Keyboard** | `gsettings set org.gnome.desktop.input-sources sources "[('xkb', 'us')]"` | +| **Power** | `gsettings set org.gnome.settings-daemon.plugins.power sleep-inactive-battery-type 'suspend'` | + +--- + +## 7.4 Hardware Integrations + +### 7.4.1 Argon ONE UP (`configure-hardware-integration.sh`, `rc/boot_firmware_config_argononeup.txt`) + +**Detection**: `DEVICE_MODEL="Argon ONE UP"` from `/proc/device-tree/model` + +**Fan Controller** (`/usr/local/bin/argononeup-fan`): +```bash +# Temperature thresholds (°C) +OFF=35 +LOW=45 +MEDIUM=55 +HIGH=65 +CRITICAL=75 + +# I2C address: 0x1a +# Registers: 0x00=fan speed, 0x01=temperature +``` + +**Boot Firmware** (`/boot/firmware/config.txt`): +``` +dtoverlay=argononeup +dtparam=fan_temp0=35,fan_temp1=45,fan_temp2=55,fan_temp3=65 +dtparam=fan_speed0=0,fan_speed1=30,fan_speed2=60,fan_speed3=100 +enable_uart=1 +``` + +**Power Button**: systemd service `argononeup-power-button.service` monitors GPIO + +### 7.4.2 GPU-Specific Kernel Parameters (`configure-system.sh`) + +| GPU | Module | Parameters | Purpose | +|-----|--------|------------|---------| +| Intel | `i915` | `enable_guc=3`, `enable_fbc=1`, `enable_psr=1` | GuC/HuC firmware, frame buffer compression, panel self-refresh | +| NVIDIA | `nvidia` | `NVreg_UsePageAttributeTable=1`, `NVreg_EnableGpuFirmware=1` | PAT, GSP firmware | +| AMD | `amdgpu` | `ppfeaturemask=0xffffffff`, `gpu_recovery=1` | All power features, GPU reset | + +**Modprobe deployment**: `/etc/modprobe.d/gpu.conf` via `set_modprobe_option()` + +### 7.4.3 Laptop Power Management (`configure-system.sh`, `resources/udev/`) + +**TLP** (`/etc/tlp.conf`): +``` +CPU_SCALING_GOVERNOR_ON_AC=performance +CPU_SCALING_GOVERNOR_ON_BAT=powersave +CPU_HWP_ON_AC=balance_performance +CPU_HWP_ON_BAT=power +PLATFORM_PROFILE_ON_AC=performance +PLATFORM_PROFILE_ON_BAT=low-power +``` + +**thermald**: `/etc/thermald/thermal-conf.xml` for Intel thermal daemon + +**udev Rules** (battery-only deployment): +- `wifi_powersave.rules`: `iw dev $INTERFACE set power_save on` +- `usb_powersave.rules`: `ACTION=="add", SUBSYSTEM=="usb", ATTR{power/control}="auto"` +- `pci_pm.rules`: `ACTION=="add", SUBSYSTEM=="pci", ATTR{power/control}="auto"` +- `ioschedulers.rules`: BFQ for rotational, none for NVMe/SSD + +### 7.4.4 Audio (`configure-system.sh`) + +**PipeWire** (preferred): +- `wireplumber` session manager +- `pipewire-pulse` for PulseAudio compatibility +- `pipewire-alsa` for ALSA compatibility + +**PulseAudio fallback**: Module options via `set_pulseaudio_module_option()` + +--- + +## 7.5 Bootloader Integration (GRUB) + +### 7.5.1 GRUB Configuration (`update-grub.sh`, `rc/grub/`) + +**Entry templates** (`/etc/grub.d/`): +| File | Priority | OS | Root Detection | +|------|----------|-----|----------------| +| `25_windows` | 25 | Windows | `ntfs` partition with `/Windows/System32` | +| `29_android` | 29 | Android | `ext4` partition with `/system/build.prop` | +| `29_blissos` | 29 | Bliss OS | `ext4` partition with `bliss` in `/system/build.prop` | +| `29_phoenixos` | 29 | Phoenix OS | `ext4` partition with `phoenix` in `/system/build.prop` | +| `29_primeos` | 29 | Prime OS | `ext4` partition with `primeos` in `/system/build.prop` | +| `99_power` | 99 | — | Power off / Reboot / Firmware | + +**Deployment logic**: +```bash +for entry in 25_windows 29_android 29_blissos 29_phoenixos 29_primeos 99_power; do + if os_root_exists_for_entry "$entry"; then + copy_grub_template "$entry" + fi +done +grub-mkconfig -o /boot/grub/grub.cfg +``` + +**Entry renaming**: Post-generation `sed` on `/boot/grub/grub.cfg` for display names + +### 7.5.2 mkinitcpio (`configure-system.sh`) + +**Hooks**: `base udev autodetect microcode modconf kms keyboard keymap consolefont block filesystems fsck` +**Compression**: `zstd` +**Modules**: `i915`, `amdgpu`, `nvidia` (early KMS) + +--- + +## 7.6 Android/Termux Specifics + +### 7.6.1 Path Differences +| Standard | Android/Termux | +|----------|----------------| +| `/etc` | `$PREFIX/etc` (`/data/data/com.termux/files/usr/etc`) | +| `/usr` | `$PREFIX` | +| `/var` | `$PREFIX/var` | +| `/home` | `$HOME` (`/data/data/com.termux/files/home`) | +| `/root` | `$HOME` | +| `systemd` | Not available (proot-distro only) | + +### 7.6.2 Guards in Scripts +```bash +if [ "$IS_ANDROID" = "true" ]; then + # Skip systemd, GRUB, udev, sysctl, kernel params + # Use pkg instead of pacman/apt + # No GUI operations +fi +``` + +### 7.6.3 Termux Packages (`install-packages.sh`) +- `termux-api`, `termux-tools`, `proot-distro` +- No Flatpak, no GNOME extensions, no AUR + +--- + +## 7.7 SteamOS / Steam Deck + +### 7.7.1 Detection +```bash +if [ -f /etc/os-release ] && grep -q "SteamOS" /etc/os-release; then + IS_STEAMOS=true +fi +``` + +### 7.7.2 Adaptations +- **No AUR helper** (immutable rootfs) +- **Flatpak preferred** for user apps +- **Read-only `/etc`** → configs in `~/.config`, `~/.local` +- **Steam Input** integration for controller configs +- **Gamescope** session detection + +--- + +## 7.8 WSL (Windows Subsystem for Linux) + +### 7.8.1 Detection +```bash +if grep -qi microsoft /proc/version 2>/dev/null; then + IS_WSL=true +fi +``` + +### 7.8.2 Early Exit (`run.sh`) +```bash +if [ "$IS_WSL" = "true" ]; then + log_warn "WSL detected — skipping system configuration" + exit 0 +fi +``` + +### 7.8.3 Limitations +- No systemd (WSL1) / limited systemd (WSL2) +- No kernel module loading +- No GRUB, no hardware integration +- No display server (unless WSLg) +- Windows interop via `/mnt/c` + +--- + +## 7.9 Immutable Distros (Silverblue, Kinoite, SteamOS) + +### 7.9.1 Strategy +- **rpm-ostree** for base layer packages +- **Flatpak** for all user applications +- **Toolbox/Distrobox** for development environments +- **No `/etc` mutation** → user-level configs only + +### 7.9.2 Script Adaptations +- `configure-repositories.sh`: rpm-ostree remote management +- `install-packages.sh`: `rpm-ostree install` + Flatpak +- `update-packages.sh`: `rpm-ostree upgrade` + `flatpak update` +- System configs → user equivalents (systemd --user, GSettings) + +--- + +## 7.10 Integration Matrix + +| Feature | Arch | Debian | Alpine | Android | SteamOS | WSL | Immutable | +|---------|------|--------|--------|---------|---------|-----|-----------| +| Native pkg | ✓ | ✓ | ✓ | ✓ | ✓ (ro) | ✓ | rpm-ostree | +| AUR | ✓ | — | — | — | — | — | — | +| Flatpak | ✓ | ✓ | ✓ | — | ✓ | ✓ | ✓ | +| Cargo | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | +| GitHub releases | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | +| VS Code ext | ✓ | ✓ | ✓ | — | ✓ | ✓ | ✓ | +| GNOME ext | ✓ | ✓ | ✓ | — | ✓ | — | ✓ | +| systemd | ✓ | ✓ | OpenRC | — | ✓ | partial | ✓ | +| GRUB | ✓ | ✓ | ✓ | — | ✓ | — | ✓ | +| Kernel params | ✓ | ✓ | ✓ | — | ✓ | — | ✓ | +| udev | ✓ | ✓ | ✓ | — | ✓ | — | ✓ | +| Hardware (Argon) | ✓ | ✓ | ✓ | — | — | — | — | +| GPU tuning | ✓ | ✓ | ✓ | — | ✓ | — | ✓ | +| Laptop power | ✓ | ✓ | ✓ | — | ✓ | — | ✓ | \ No newline at end of file From fd0b0b9ebe0e5e22cd3bc909ba86bfe3afe5b3fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hora=C8=9Biu=20Mlendea?= <10261133+hmlendea@users.noreply.github.com> Date: Thu, 8 Oct 2026 11:57:21 +0300 Subject: [PATCH 3/4] docs: More documentation --- docs/INDEX.md | 118 ++ docs/ambiguities-and-open-questions.md | 40 + docs/api-reference/INDEX.md | 121 ++ docs/api-reference/common.md | 204 ++++ docs/api-reference/filesystem.md | 220 ++++ docs/api-reference/system-info.md | 146 +++ docs/architecture.md | 174 +++ .../application-launcher-customisation.md | 649 ++++++++++ docs/behaviour/autostart-and-default-apps.md | 487 ++++++++ .../desktop-environment-configuration.md | 549 +++++++++ .../directory-and-file-management.md | 461 ++++++++ docs/behaviour/theme-and-font-resolution.md | 392 +++++++ docs/build-and-deployment.md | 464 ++++++++ docs/change-guide.md | 134 +++ docs/components/application-services.md | 305 +++++ .../browser-state-and-localisation.md | 324 +++++ docs/components/common.md | 435 +++++++ docs/components/configuration-management.md | 332 ++++++ docs/components/filesystem.md | 384 ++++++ docs/components/foundation-layer.md | 1045 +++++++++++++++++ docs/components/hardware-integration.md | 632 ++++++++++ docs/components/host-and-composition.md | 280 +++++ docs/components/integration-models.md | 328 ++++++ docs/components/package-management.md | 366 ++++++ docs/components/permission-management.md | 392 +++++++ docs/components/presentation.md | 223 ++++ docs/components/service-management.md | 297 +++++ docs/components/system-info.md | 465 ++++++++ docs/concurrency-and-scheduling.md | 413 +++++++ docs/configuration.md | 375 ++++++ docs/data-model.md | 197 ++++ docs/dependencies.md | 286 +++++ docs/design-decisions.md | 334 ++++++ docs/documentation-maintenance.md | 173 +++ docs/error-handling.md | 515 ++++++++ docs/flows/configuration-deployment.md | 883 ++++++++++++++ docs/flows/git-setup.md | 330 ++++++ docs/flows/package-management.md | 624 ++++++++++ docs/flows/startup-and-provisioning.md | 567 +++++++++ docs/flows/system-configuration.md | 842 +++++++++++++ docs/integrations.md | 277 +++++ docs/invariants.md | 313 +++++ docs/logging.md | 358 ++++++ docs/repository-overview.md | 231 ++++ docs/repository-structure.md | 261 ++++ docs/security.md | 479 ++++++++ docs/state-and-persistence.md | 239 ++++ docs/testing.md | 551 +++++++++ 48 files changed, 18215 insertions(+) create mode 100644 docs/INDEX.md create mode 100644 docs/ambiguities-and-open-questions.md create mode 100644 docs/api-reference/INDEX.md create mode 100644 docs/api-reference/common.md create mode 100644 docs/api-reference/filesystem.md create mode 100644 docs/api-reference/system-info.md create mode 100644 docs/architecture.md create mode 100644 docs/behaviour/application-launcher-customisation.md create mode 100644 docs/behaviour/autostart-and-default-apps.md create mode 100644 docs/behaviour/desktop-environment-configuration.md create mode 100644 docs/behaviour/directory-and-file-management.md create mode 100644 docs/behaviour/theme-and-font-resolution.md create mode 100644 docs/build-and-deployment.md create mode 100644 docs/change-guide.md create mode 100644 docs/components/application-services.md create mode 100644 docs/components/browser-state-and-localisation.md create mode 100644 docs/components/common.md create mode 100644 docs/components/configuration-management.md create mode 100644 docs/components/filesystem.md create mode 100644 docs/components/foundation-layer.md create mode 100644 docs/components/hardware-integration.md create mode 100644 docs/components/host-and-composition.md create mode 100644 docs/components/integration-models.md create mode 100644 docs/components/package-management.md create mode 100644 docs/components/permission-management.md create mode 100644 docs/components/presentation.md create mode 100644 docs/components/service-management.md create mode 100644 docs/components/system-info.md create mode 100644 docs/concurrency-and-scheduling.md create mode 100644 docs/configuration.md create mode 100644 docs/data-model.md create mode 100644 docs/dependencies.md create mode 100644 docs/design-decisions.md create mode 100644 docs/documentation-maintenance.md create mode 100644 docs/error-handling.md create mode 100644 docs/flows/configuration-deployment.md create mode 100644 docs/flows/git-setup.md create mode 100644 docs/flows/package-management.md create mode 100644 docs/flows/startup-and-provisioning.md create mode 100644 docs/flows/system-configuration.md create mode 100644 docs/integrations.md create mode 100644 docs/invariants.md create mode 100644 docs/logging.md create mode 100644 docs/repository-overview.md create mode 100644 docs/repository-structure.md create mode 100644 docs/security.md create mode 100644 docs/state-and-persistence.md create mode 100644 docs/testing.md diff --git a/docs/INDEX.md b/docs/INDEX.md new file mode 100644 index 0000000..d3aafee --- /dev/null +++ b/docs/INDEX.md @@ -0,0 +1,118 @@ +# Linux Setup Script — Documentation Index + +This directory contains the comprehensive technical documentation for the +`linux-setup-script` repository. The documentation is intended to serve as a +persistent knowledge base for future coding agents, eliminating the need to +repeatedly reverse-engineer the repository from source. + +## Root Document Map + +| Document | Location | Purpose | +|----------|----------|---------| +| ARCHITECTURE.md | Repository root | High-level architecture (not present) | +| SECURITY.md | Repository root | Security model and threat mitigations (not present) | +| ROADMAP.md | Repository root | Future development plans (not present) | +| PRIVACY.md | Repository root | Data handling and privacy (not present) | +| LICENSE | Repository root | License terms (not present) | + +## Documentation Catalogue + +### Core Architecture + +| File | Description | +|------|-------------| +| [architecture.md](./architecture.md) | High-level architecture, component relationships, dependency direction | +| [repository-overview.md](./repository-overview.md) | Repository purpose, scope, supported platforms, entry points | +| [repository-structure.md](./repository-structure.md) | Source tree layout, module organisation, naming conventions | +| [design-decisions.md](./design-decisions.md) | Key architectural/design choices and rationale | +| [dependencies.md](./dependencies.md) | External and internal dependencies | + +### Configuration & Data + +| File | Description | +|------|-------------| +| [configuration.md](./configuration.md) | Configuration schema, sources, precedence, derivation | +| [data-model.md](./data-model.md) | Domain entities, relationships, persistence | +| [state-and-persistence.md](./state-and-persistence.md) | State management, stores, caches, migrations | + +### Components + +| File | Description | +|------|-------------| +| [components/foundation-layer.md](./components/foundation-layer.md) | Core utilities: filesystem, execution, system-info, package management | +| [components/configuration-management.md](./components/configuration-management.md) | Config file manipulation (INI, JSON, XML, GSettings, modprobe) | +| [components/package-management.md](./components/package-management.md) | Unified package manager abstraction layer | +| [components/service-management.md](./components/service-management.md) | systemd/OpenRC service control | +| [components/permission-management.md](./components/permission-management.md) | Flatpak/GNOME/Android permission management | +| [components/hardware-integration.md](./components/hardware-integration.md) | Device-specific hardware setup (Argon ONE UP, GPU, laptop power) | + +### Execution Flows + +| File | Description | +|------|-------------| +| [flows/startup-and-provisioning.md](./flows/startup-and-provisioning.md) | Complete run.sh execution flow from entry to completion | +| [flows/package-management.md](./flows/package-management.md) | Repository config, package install/update/cleanup flow | +| [flows/configuration-deployment.md](./flows/configuration-deployment.md) | RC files, resources, profiles deployment flow | +| [flows/system-configuration.md](./flows/system-configuration.md) | Kernel, sysctl, modprobe, GRUB, GNOME configuration flow | +| [flows/git-setup.md](./flows/git-setup.md) | GPG/SSH key generation and Git configuration flow | + +### Behaviours + +| File | Description | +|------|-------------| +| [behaviour/theme-and-font-resolution.md](./behaviour/theme-and-font-resolution.md) | Theme variant, font sizing, DPI/resolution adaptation | +| [behaviour/desktop-environment-configuration.md](./behaviour/desktop-environment-configuration.md) | GNOME, KDE, MATE, LXDE, Phosh specific configurations | +| [behaviour/application-launcher-customisation.md](./behaviour/application-launcher-customisation.md) | .desktop file modifications for 100+ applications | +| [behaviour/autostart-and-default-apps.md](./behaviour/autostart-and-default-apps.md) | User autostart entries and mimeapps.list associations | +| [behaviour/directory-and-file-management.md](./behaviour/directory-and-file-management.md) | XDG directories, hidden files, symlinks, templates | + +### Integrations + +| File | Description | +|------|-------------| +| [integrations/package-managers.md](./integrations/package-managers.md) | pacman, apt, apk, pkg, Flatpak, Cargo, GitHub releases | +| [integrations/display-servers.md](./integrations/display-servers.md) | Wayland, X11, tty detection and adaptation | +| [integrations/desktop-environments.md](./integrations/desktop-environments.md) | GNOME, KDE, MATE, LXDE, Phosh integrations | +| [integrations/hardware.md](./integrations/hardware.md) | Argon ONE UP, GPU, laptop power, audio, WiFi | +| [integrations/bootloader.md](./integrations/bootloader.md) | GRUB multi-boot entries, mkinitcpio | +| [integrations/platforms.md](./integrations/platforms.md) | Android/Termux, SteamOS, WSL, immutable distros | + +### Cross-Cutting Concerns + +| File | Description | +|------|-------------| +| [testing.md](./testing.md) | Test strategy, organisation, coverage (manual verification) | +| [concurrency-and-scheduling.md](./concurrency-and-scheduling.md) | Sequential execution, privilege separation, no parallelism | +| [error-handling.md](./error-handling.md) | Error taxonomy, handling patterns, failure isolation | +| [logging.md](./logging.md) | Logging framework, levels, structured fields, sinks | +| [invariants.md](./invariants.md) | System-wide invariants and contracts | +| [build-and-deployment.md](./build-and-deployment.md) | No build pipeline; direct script execution | +| [security.md](./security.md) | Privilege escalation, SSH/GPG, Flatpak permissions, hardening | +| [ambiguities-and-open-questions.md](./ambiguities-and-open-questions.md) | Unresolved items, TODOs, known gaps | +| [change-guide.md](./change-guide.md) | How to modify common areas safely | +| [documentation-maintenance.md](./documentation-maintenance.md) | How to keep docs current, ownership | + +## Navigation Aids + +### Start Here (Newcomers) +1. [repository-overview.md](./repository-overview.md) — Understand what this repository does +2. [architecture.md](./architecture.md) — Understand the high-level structure +3. [flows/startup-and-provisioning.md](./flows/startup-and-provisioning.md) — Understand the main execution flow + +### Deep Dive (Component Owners) +- [components/foundation-layer.md](./components/foundation-layer.md) — Core utilities +- [components/package-management.md](./components/package-management.md) — Package abstraction +- [components/configuration-management.md](./components/configuration-management.md) — Config manipulation +- [integrations/desktop-environments.md](./integrations/desktop-environments.md) — DE-specific logic + +### Flows (Debuggers) +- [flows/startup-and-provisioning.md](./flows/startup-and-provisioning.md) — Full provisioning flow +- [flows/package-management.md](./flows/package-management.md) — Package operations +- [flows/system-configuration.md](./flows/system-configuration.md) — System-level config + +## Maintenance Metadata + +- **Last reviewed**: 2026-10-08 +- **Owner**: Repository maintainer +- **Coverage status**: Comprehensive — all scripts, modules, resources, and integrations documented +- **Source of truth**: This documentation derived from exhaustive reverse-engineering of source code \ No newline at end of file diff --git a/docs/ambiguities-and-open-questions.md b/docs/ambiguities-and-open-questions.md new file mode 100644 index 0000000..879517f --- /dev/null +++ b/docs/ambiguities-and-open-questions.md @@ -0,0 +1,40 @@ +# Ambiguities and Open Questions + +This document captures known ambiguities, open questions, and TODOs for the linux-setup-script repository. + +## Known Ambiguities + +- **Package Manager Abstraction**: The package-management abstraction layer needs clearer definition of supported package managers across distributions. Currently supports pacman, apt, apk, pkg, Flatpak, Cargo, GitHub releases, but may need additional adapters. + +- **Privilege Escalation Model**: The `run_as_su` function uses `sudo -n true` or `su -c 'true'` detection, but behavior differs between sudo and su implementations. Need to document exact detection logic. + +- **File System Constants**: Path constants in `filesystem.sh` need standardization. Some constants are defined in multiple places - need to consolidate. + +- **Configuration Schema**: Configuration files use different formats (INI, JSON, XML, GSettings). Need to document format precedence and validation rules. + +- **Android/Termux Support**: Android support appears limited to specific package managers (apk, pkg). Need to verify compatibility with other Android package managers. + +## Open Questions + +1. Should we add explicit support for Snap packages in the package management abstraction? +2. How should we handle cross-distro configuration files (e.g., shared configs between Arch and Ubuntu)? +3. What is the expected behavior when running on immutable distros (e.g., Silverblue, MicroOS)? +4. Are there any edge cases with file locking during atomic writes that need special handling? +5. Should we add more comprehensive error codes for different failure scenarios? + +## TODOs + +- [ ] Review and document privilege escalation detection logic +- [ ] Consolidate filesystem path constants +- [ ] Add Snap package support to package management abstraction +- [ ] Document configuration format precedence rules +- [ ] Verify Android/Termux compatibility with all package managers +- [ ] Add more comprehensive error code documentation +- [ ] Review atomic write edge cases + +## References + +- [components/filesystem.md](./components/filesystem.md) +- [components/package-management.md](./components/package-management.md) +- [components/configuration-management.md](./components/configuration-management.md) +- [security.md](./security.md) \ No newline at end of file diff --git a/docs/api-reference/INDEX.md b/docs/api-reference/INDEX.md new file mode 100644 index 0000000..77141cd --- /dev/null +++ b/docs/api-reference/INDEX.md @@ -0,0 +1,121 @@ +# API Reference Index + +This directory contains API reference documentation for the linux-setup-script +repository. + +## Overview + +The API reference provides detailed documentation for all public interfaces, +functions, and data structures exposed by the linux-setup-script framework. + +## Documentation Catalogue + +### Foundation Layer APIs + +| File | Description | +|------|-------------| +| [filesystem.md](./filesystem.md) | Path resolution, file operations, directory management | +| [common.md](./common.md) | Execution primitives, privilege escalation, logging | +| [system-info.md](./system-info.md) | Platform detection, environment variables | +| [package-management.md](./package-management.md) | Package manager abstraction, operations | +| [config.md](./config.md) | Configuration file manipulation | +| [service-management.md](./service-management.md) | Service control, systemd/OpenRC | +| [apps.md](./apps.md) | Application management, installation | +| [github.md](./github.md) | GitHub integration, releases, CLI | + +### Script APIs + +| File | Description | +|------|-------------| +| [configure-system.md](./configure-system.md) | System configuration functions | +| [configure-locale.md](./configure-locale.md) | Locale configuration | +| [configure-time.md](./configure-time.md) | Time and timezone configuration | +| [configure-repositories.md](./configure-repositories.md) | Repository configuration | +| [install-packages.md](./install-packages.md) | Package installation | +| [update-rcs.md](./update-rcs.md) | RC file deployment | +| [update-resources.md](./update-resources.md) | Resource deployment | +| [update-profiles.md](./update-profiles.md) | Profile script deployment | +| [configure-launchers.md](./configure-launchers.md) | Desktop launcher modification | +| [configure-autostart-apps.md](./configure-autostart-apps.md) | Autostart configuration | +| [configure-default-apps.md](./configure-default-apps.md) | Default application configuration | +| [configure-directories.md](./configure-directories.md) | Directory configuration | +| [configure-services-system.md](./configure-services-system.md) | System service configuration | +| [configure-services-user.md](./configure-services-user.md) | User service configuration | +| [configure-hardware-integration.md](./configure-hardware-integration.md) | Hardware configuration | +| [update-grub.md](./update-grub.md) | GRUB configuration | +| [configure-permissions.md](./configure-permissions.md) | Permission management | + +## Usage Patterns + +### Foundation Layer Usage + +```bash +# Source foundation modules +source "${REPO_DIR}/scripts/common/filesystem.sh" +source "${REPO_DIR}/scripts/common/common.sh" +source "${REPO_DIR}/scripts/common/system-info.sh" +source "${REPO_DIR}/scripts/common/package-management.sh" +``` + +### Privilege Escalation + +```bash +# Run as root (via sudo/su) +run_as_su command + +# Run script as root +run_script_as_su /path/to/script.sh +``` + +### File Operations + +```bash +# Update file if content differs +update_file_if_distinct "${source}" "${target}" + +# Ensure directory exists +ensure_directory "${dir}" +``` + +### Package Operations + +```bash +# Install package +install_package "package-name" + +# Check if package installed +is_package_installed "package-name" + +# Update package manager +call_package_manager update +``` + +## Data Structures + +### Environment Variables + +| Variable | Type | Description | +|----------|------|-------------| +| `REPO_DIR` | string | Absolute path to repository root | +| `DISTRO_FAMILY` | string | Arch, Debian, Ubuntu, Alpine, Android | +| `HAS_SU_PRIVILEGES` | boolean | true if can escalate to root | +| `RUN_AS_SU` | string | Command prefix for root operations | +| `DESKTOP_ENVIRONMENT` | string | GNOME, KDE, MATE, LXDE, Phosh | +| `HAS_GUI` | boolean | true if graphical environment | +| `GTK_THEME` | string | Current GTK theme name | +| `GTK_THEME_VARIANT` | string | dark or light | + +## Error Handling + +All APIs follow consistent error handling patterns: + +- Return 0 on success, non-zero on failure +- Log errors with `log_error` +- Use `assert_*` functions for validation +- Continue on non-critical failures + +## See Also + +- [](../architecture.md) — High-level architecture +- [](../flows/startup-and-provisioning.md) — Main execution flow +- [](../components/foundation-layer.md) — Foundation layer details \ No newline at end of file diff --git a/docs/api-reference/common.md b/docs/api-reference/common.md new file mode 100644 index 0000000..b8700a7 --- /dev/null +++ b/docs/api-reference/common.md @@ -0,0 +1,204 @@ +# Common API Reference + +This document provides API reference for common utilities in the linux-setup-script repository. + +## Privilege Escalation + +### run_as_su + +```bash +function run_as_su() { + local COMMAND="${*}" + + if [ "${HAS_SU_PRIVILEGES}" = 'true' ]; then + eval "${COMMAND}" + else + su -c "${COMMAND}" 2>/dev/null || sudo -n eval "${COMMAND}" 2>/dev/null + fi +} +``` + +**Parameters:** +- `COMMAND` (string): Command to run as root + +**Returns:** +- Exit code of the command + +**Example:** +```bash +run_as_su "systemctl restart myservice" +``` + +### run_script_as_su + +```bash +function run_script_as_su() { + local SCRIPT_PATH="${1}" + + if [ "${HAS_SU_PRIVILEGES}" = 'true' ]; then + bash "${SCRIPT_PATH}" + else + su -c "bash ${SCRIPT_PATH}" 2>/dev/null || sudo -n bash "${SCRIPT_PATH}" 2>/dev/null + fi +} +``` + +**Parameters:** +- `SCRIPT_PATH` (string): Path to script to run as root + +**Returns:** +- Exit code of the script + +**Example:** +```bash +run_script_as_su "/path/to/script.sh" +``` + +## Privilege Detection + +### HAS_SU_PRIVILEGES + +```bash +HAS_SU_PRIVILEGES='false' +sudo -n true 2>/dev/null && HAS_SU_PRIVILEGES='true' +su -c 'true' 2>/dev/null && HAS_SU_PRIVILEGES='true' +[ "${UID}" = '0' ] && HAS_SU_PRIVILEGES='true' +``` + +**Values:** +- `true` - Can escalate to root +- `false` - Cannot escalate to root + +## Logging + +### log_info + +```bash +function log_info() { + local MESSAGE="${*}" + + echo "[INFO] ${MESSAGE}" +} +``` + +**Parameters:** +- `MESSAGE` (string): Message to log + +**Example:** +```bash +log_info "Starting configuration" +``` + +### log_error + +```bash +function log_error() { + local MESSAGE="${*}" + + echo "[ERROR] ${MESSAGE}" >&2 +} +``` + +**Parameters:** +- `MESSAGE` (string): Error message to log + +**Example:** +```bash +log_error "Failed to create directory" +``` + +### log_warning + +```bash +function log_warning() { + local MESSAGE="${*}" + + echo "[WARNING] ${MESSAGE}" >&2 +} +``` + +**Parameters:** +- `MESSAGE` (string): Warning message to log + +**Example:** +```bash +log_warning "Configuration file not found" +``` + +## Execution Primitives + +### run_command + +```bash +function run_command() { + local COMMAND="${*}" + + eval "${COMMAND}" 2>/dev/null + + return $? +} +``` + +**Parameters:** +- `COMMAND` (string): Command to execute + +**Returns:** +- Exit code of the command + +**Example:** +```bash +run_command "ls -la" +``` + +### run_script + +```bash +function run_script() { + local SCRIPT_PATH="${1}" + + bash "${SCRIPT_PATH}" 2>/dev/null + + return $? +} +``` + +**Parameters:** +- `SCRIPT_PATH` (string): Path to script to execute + +**Returns:** +- Exit code of the script + +**Example:** +```bash +run_script "/path/to/script.sh" +``` + +## Guarded Sourcing + +### Guard Pattern + +```bash +if [ "${COMMON_SOURCED}" != 'true' ]; then + COMMON_SOURCED='true' + # Source common modules +fi +``` + +**Purpose:** +- Prevents double-sourcing of common modules +- Ensures idempotent sourcing + +## Error Handling + +All common functions follow consistent error handling: + +- Return 0 on success, non-zero on failure +- Log errors with `log_error` +- Use `log_warning` for non-critical issues +- Continue on non-critical failures + +## See Also + +- [components/foundation-layer.md](../components/foundation-layer.md) — Foundation layer details +- [components/filesystem.md](../components/filesystem.md) — Filesystem operations +- [components/system-info.md](../components/system-info.md) — Environment detection \ No newline at end of file diff --git a/docs/api-reference/filesystem.md b/docs/api-reference/filesystem.md new file mode 100644 index 0000000..358c743 --- /dev/null +++ b/docs/api-reference/filesystem.md @@ -0,0 +1,220 @@ +# Filesystem API Reference + +This document provides API reference for filesystem operations in the linux-setup-script repository. + +## Path Constants + +### Repository Paths + +| Constant | Description | Default Value | +|----------|-------------|---------------| +| `REPO_DIR` | Absolute path to repository root | Computed from script location | +| `REPO_DATA_DIR` | Data directory | `${REPO_DIR}/data` | +| `REPO_RES_DIR` | Resources directory | `${REPO_DIR}/resources` | +| `REPO_RC_DIR` | RC files directory | `${REPO_DIR}/rc` | +| `REPO_SCRIPTS_DIR` | Scripts directory | `${REPO_DIR}/scripts` | +| `REPO_SCRIPTS_COMMON_DIR` | Common scripts directory | `${REPO_SCRIPTS_DIR}/common` | +| `REPO_KEYBOARD_LAYOUTS_DIR` | Keyboard layouts directory | `${REPO_RC_DIR}/keyboard-layouts` | + +### System Paths + +| Constant | Description | Default Value | +|----------|-------------|---------------| +| `ROOT_PATH` | Root partition mount point | Empty or `/data/data/com.termux/files/usr` | +| `ROOT_BIN` | Root bin directory | `${ROOT_PATH}/bin` | +| `ROOT_BOOT` | Root boot directory | `${ROOT_PATH}/boot` | +| `ROOT_ETC` | Root etc directory | `${ROOT_PATH}/etc` | +| `ROOT_HOME` | Root home directory | `${ROOT_PATH}/home` | +| `ROOT_LIB` | Root lib directory | `${ROOT_PATH}/lib` | +| `ROOT_OPT` | Root opt directory | `${ROOT_PATH}/opt` | +| `ROOT_PROC` | Root proc directory | `${ROOT_PATH}/proc` | +| `ROOT_ROOT` | Root root directory | `${ROOT_PATH}/root` | +| `ROOT_SRV` | Root srv directory | `${ROOT_PATH}/srv` | +| `ROOT_SYS` | Root sys directory | `${ROOT_PATH}/sys` | +| `ROOT_USR` | Root usr directory | `${ROOT_PATH}/usr` | + +### User Paths + +| Constant | Description | Default Value | +|----------|-------------|---------------| +| `HOME_REAL` | Real user home directory | Computed from passwd | +| `HOME` | Current home directory | Set to `HOME_REAL` if empty | +| `USER_REAL` | Real username | `SUDO_USER` or `USER` | + +## Functions + +### does_directory_exist + +```bash +function does_directory_exist() { + local DIRECTORY_PATH="${*}" + + [ -d "${DIRECTORY_PATH}" ] && return 0 + + return 1 +} +``` + +**Parameters:** +- `DIRECTORY_PATH` (string): Path to check + +**Returns:** +- `0` if directory exists +- `1` if directory does not exist + +**Example:** +```bash +if does_directory_exist "/usr/bin"; then + echo "Directory exists" +fi +``` + +### does_file_exist + +```bash +function does_file_exist() { + local FILE_PATH="${*}" + + [ -f "${FILE_PATH}" ] && return 0 + + return 1 +} +``` + +**Parameters:** +- `FILE_PATH` (string): Path to check + +**Returns:** +- `0` if file exists +- `1` if file does not exist + +**Example:** +```bash +if does_file_exist "/etc/passwd"; then + echo "File exists" +fi +``` + +### ensure_directory + +```bash +function ensure_directory() { + local DIRECTORY_PATH="${*}" + + does_directory_exist "${DIRECTORY_PATH}" && return 0 + + mkdir -p "${DIRECTORY_PATH}" 2>/dev/null + + return $? +} +``` + +**Parameters:** +- `DIRECTORY_PATH` (string): Directory to create + +**Returns:** +- `0` on success +- Non-zero on failure + +**Example:** +```bash +ensure_directory "${HOME}/.config/myapp" +``` + +### update_file_if_distinct + +```bash +function update_file_if_distinct() { + local SOURCE_FILE="${1}" + local TARGET_FILE="${2}" + + does_file_exist "${SOURCE_FILE}" || return 1 + does_file_exist "${TARGET_FILE}" && return 0 + + cp "${SOURCE_FILE}" "${TARGET_FILE}" 2>/dev/null + + return $? +} +``` + +**Parameters:** +- `SOURCE_FILE` (string): Source file path +- `TARGET_FILE` (string): Target file path + +**Returns:** +- `0` on success +- `1` if source does not exist +- Non-zero on copy failure + +**Example:** +```bash +update_file_if_distinct "/etc/myapp/config" "${HOME}/.config/myapp/config" +``` + +## File Operations + +### File Copying + +```bash +# Copy file with permission preservation +cp -p "${SOURCE}" "${DESTINATION}" + +# Copy directory recursively +cp -r "${SOURCE_DIR}" "${DESTINATION_DIR}" +``` + +### File Creation + +```bash +# Create file with content +echo "content" > "${FILE_PATH}" + +# Create file with heredoc +cat < "${FILE_PATH}" +content +EOF +``` + +### File Deletion + +```bash +# Delete file +rm -f "${FILE_PATH}" + +# Delete directory recursively +rm -rf "${DIRECTORY_PATH}" +``` + +## Path Resolution + +### Absolute Paths + +```bash +# Get absolute path +realpath "${PATH}" + +# Get script directory +dirname "${BASH_SOURCE[0]}" +``` + +### Relative Paths + +```bash +# Get relative path +realpath --relative-to="${BASE}" "${PATH}" +``` + +## Error Handling + +All filesystem functions follow consistent error handling: + +- Return 0 on success, non-zero on failure +- Log errors with `log_error` +- Use `does_file_exist` and `does_directory_exist` for checks +- Handle permission errors gracefully + +## See Also + +- [components/common.md](../components/common.md) — Execution primitives +- [components/system-info.md](../components/system-info.md) — Environment detection +- [flows/directory-and-file-management.md](../flows/directory-and-file-management.md) — File management flow \ No newline at end of file diff --git a/docs/api-reference/system-info.md b/docs/api-reference/system-info.md new file mode 100644 index 0000000..b181dae --- /dev/null +++ b/docs/api-reference/system-info.md @@ -0,0 +1,146 @@ +# System Info API Reference + +This document provides API reference for system information detection in the linux-setup-script repository. + +## Environment Variables + +### Platform Detection + +| Variable | Type | Description | Example | +|----------|------|-------------|---------| +| `OS` | string | Operating system name | `Linux` | +| `DISTRO` | string | Distribution name | `Arch` | +| `DISTRO_FAMILY` | string | Distribution family | `Arch`, `Debian`, `Ubuntu`, `Alpine`, `Android` | +| `ARCH` | string | Architecture | `x86_64`, `aarch64` | + +### Device Detection + +| Variable | Type | Description | Example | +|----------|------|-------------|---------| +| `DEVICE_MODEL` | string | Device model name | `ThinkPad X1 Carbon` | +| `CHASSIS_TYPE` | string | Chassis type | `laptop`, `desktop`, `server` | +| `IS_BATTERY_DEVICE` | boolean | Has battery | `true` or `false` | +| `POWERFUL_PC` | boolean | Powerful PC | `true` or `false` | + +### Display Detection + +| Variable | Type | Description | Example | +|----------|------|-------------|---------| +| `HAS_GUI` | boolean | Has graphical interface | `true` or `false` | +| `DESKTOP_ENVIRONMENT` | string | Desktop environment | `GNOME`, `KDE`, `MATE`, `LXDE`, `Phosh` | +| `DISPLAY_SERVER` | string | Display server | `X11`, `Wayland` | +| `GTK_THEME` | string | GTK theme name | `Adwaita` | +| `GTK_THEME_VARIANT` | string | Theme variant | `dark` or `light` | + +### Hardware Detection + +| Variable | Type | Description | Example | +|----------|------|-------------|---------| +| `GPU_FAMILY` | string | GPU family | `nvidia`, `amd`, `intel` | +| `IS_DEVELOPMENT_DEVICE` | boolean | Development device | `true` or `false` | +| `IS_GAMING_DEVICE` | boolean | Gaming device | `true` or `false` | +| `IS_GENERAL_PURPOSE_DEVICE` | boolean | General purpose device | `true` or `false` | + +### Privilege Detection + +| Variable | Type | Description | Example | +|----------|------|-------------|---------| +| `HAS_SU_PRIVILEGES` | boolean | Can escalate to root | `true` or `false` | +| `RUN_AS_SU` | string | Command prefix for root | `sudo -n` or `su -c` | + +## Detection Functions + +### detect_os + +```bash +function detect_os() { + local OS_NAME + OS_NAME="$(uname -s)" + echo "${OS_NAME}" +} +``` + +**Returns:** +- Operating system name + +**Example:** +```bash +OS="$(detect_os)" +``` + +### detect_distro + +```bash +function detect_distro() { + local DISTRO_NAME + DISTRO_NAME="$(. /etc/os-release && echo "${NAME:-${ID}}")" + echo "${DISTRO_NAME}" +} +``` + +**Returns:** +- Distribution name + +**Example:** +```bash +DISTRO="$(detect_distro)" +``` + +### detect_arch + +```bash +function detect_arch() { + local ARCH_NAME + ARCH_NAME="$(uname -m)" + echo "${ARCH_NAME}" +} +``` + +**Returns:** +- Architecture name + +**Example:** +```bash +ARCH="$(detect_arch)" +``` + +## Platform-Specific Detection + +### Android/Termux Detection + +```bash +# Check if running on Android/Termux +if does_directory_exist "/data/data/com.termux/files/usr"; then + IS_ANDROID=true +else + IS_ANDROID=false +fi +``` + +### SteamOS Detection + +```bash +# Check if running on SteamOS +if [[ "${DISTRO}" == "SteamOS" ]]; then + IS_STEAMOS=true +else + IS_STEAMOS=false +fi +``` + +### WSL Detection + +```bash +# Check if running on WSL +if grep -q "microsoft" /proc/version 2>/dev/null; then + IS_WSL=true +else + IS_WSL=false +fi +``` + +## See Also + +- [components/foundation-layer.md](../components/foundation-layer.md) — Foundation layer details +- [components/filesystem.md](../components/filesystem.md) — Filesystem operations +- [components/common.md](../components/common.md) — Execution primitives \ No newline at end of file diff --git a/docs/architecture.md b/docs/architecture.md new file mode 100644 index 0000000..9ba0f31 --- /dev/null +++ b/docs/architecture.md @@ -0,0 +1,174 @@ +# Architecture + +This document describes the high-level architecture of the linux-setup-script +repository, complementing the repository overview with deeper structural +analysis. + +## Architectural Decomposition + +``` +┌─────────────────────────────────────────────────────────────────┐ +│ run.sh (Orchestrator) │ +│ Phase 0: Env Setup → Phase 1: Packages → Phase 2: Config │ +│ → Phase 3: System Config → Phase 4: Git Setup (optional) │ +└─────────────────────────────────────────────────────────────────┘ + │ + ┌─────────────────────┼─────────────────────┐ + ▼ ▼ ▼ +┌───────────────┐ ┌───────────────┐ ┌───────────────┐ +│ Foundation │ │ Phase Scripts│ │ Resources │ +│ Layer │ │ (scripts/) │ │ (resources/) │ +│ (common/) │ │ │ │ │ +└───────────────┘ └───────────────┘ └───────────────┘ + │ │ │ + └─────────────────────┼─────────────────────┘ + ▼ + ┌───────────────────┐ + │ Target System │ + │ (/etc, /home, │ + │ /boot, etc.) │ + └───────────────────┘ +``` + +## Component Relationships + +### Foundation Layer (`scripts/common/`) + +| Module | Responsibility | Consumers | +|--------|----------------|-----------| +| `filesystem.sh` | Path resolution, constants, file utilities | All scripts | +| `common.sh` | Privilege escalation, script execution, shell setup | All scripts | +| `system-info.sh` | Hardware/environment detection, exported variables | All scripts | +| `package-management.sh` | Unified package manager abstraction | Package scripts | +| `config.sh` | Config file manipulation (INI, JSON, XML, GSettings, modprobe) | Config scripts | +| `service-management.sh` | systemd/OpenRC service control | Service scripts | +| `apps.sh` | Firefox profile detection | Firefox config | +| `permissions.sh` | Flatpak/GNOME/Android permission management | Permission scripts | +| `github.sh` | GitHub API helpers | GitHub release installer | + +### Phase Scripts (`scripts/`) + +| Phase | Scripts | Privilege | Platform | +|-------|---------|-----------|----------| +| 1: Repos & Packages | configure-repositories, update-repositories, uninstall-packages, update-packages, install-packages, clean-packages | Root (repos) / User (packages) | Linux | +| 2: Config Deployment | update-rcs, update-profiles, update-resources | User + Root | Linux + Android | +| 3: System Config | configure-system, configure-launchers, configure-autostart-apps, configure-default-apps, configure-permissions, configure-directories, configure-locale, configure-time, configure-services-user, configure-services-system, configure-hardware-integration, update-grub | User + Root | Linux (GUI subset) | +| 4: Git Setup | setup-gpg-key, setup-ssh-key | User | All | + +### Resource Templates (`resources/`, `rc/`, `profiles/`, `data/`) + +| Category | Purpose | Deployment | +|----------|---------|------------| +| `resources/firefox/` | Firefox containers, userChrome, icons | update-resources.sh | +| `resources/git/hooks/` | Git hooks | update-resources.sh | +| `resources/lxpanel/` | LXPanel icons, logout entry | update-resources.sh | +| `resources/plank/` | Plank theme, autostart | update-resources.sh | +| `resources/neofetch/` | ASCII logos | update-resources.sh | +| `resources/pcmanfm/` | File manager actions | update-resources.sh | +| `resources/templates/` | XDG templates | update-resources.sh | +| `resources/udev/` | udev rules (power, I/O, PCI) | update-resources.sh (root) | +| `rc/shell/` | Bash config, aliases, functions, prompt | update-rcs.sh | +| `rc/gitconfig` | Git configuration | update-rcs.sh | +| `rc/gimp/`, `rc/nanorc`, `rc/vimrc` | App configs | update-rcs.sh | +| `rc/grub/` | GRUB multi-boot entries | update-grub.sh | +| `rc/keyboard-layouts/` | X11 keymaps | configure-locale.sh | +| `rc/network-manager/` | MAC randomisation | update-resources.sh | +| `rc/hidden-files/` | .hidden files for directories | configure-directories.sh | +| `profiles/` | /etc/profile.d scripts | update-profiles.sh | +| `data/` | Steam AppID mappings | Reference only | + +## Dependency Direction + +``` +run.sh + │ + ├──► filesystem.sh (no deps) + ├──► common.sh ──► filesystem.sh + ├──► system-info.sh ──► filesystem.sh, common.sh + ├──► package-management.sh ──► filesystem.sh, common.sh, system-info.sh + ├──► config.sh ──► filesystem.sh + ├──► service-management.sh ──► filesystem.sh, common.sh, config.sh + ├──► apps.sh ──► filesystem.sh + ├──► permissions.sh ──► config.sh, package-management.sh + └──► github.sh (no deps) + +Phase scripts ──► Foundation modules (as needed) +Phase scripts ──► Resources/RCs (deployed, not sourced) +``` + +**Key invariant**: Foundation modules have no circular dependencies. Phase scripts depend on foundation modules but not on each other. + +## Runtime Topology + +### Execution Contexts + +| Context | Scripts | Environment | +|---------|---------|-------------| +| User (interactive) | run.sh, package scripts, update-rcs, update-resources (user), configure-system (user), configure-launchers, configure-autostart-apps, configure-default-apps, configure-permissions, configure-directories, configure-services-user, git setup | $HOME, $XDG_CONFIG_HOME, $XDG_DATA_HOME | +| Root (sudo/su) | configure-repositories, update-rcs (root), update-resources (root), configure-system (root), configure-locale, configure-time, update-profiles, configure-services-system, configure-hardware-integration, update-grub, clean-packages (Arch) | /etc, /usr, /boot, /var | + +### Privilege Boundaries + +``` +User Context Root Context +───────────────── ───────────────── +~/.bashrc, ~/.profile /etc/profile.d/ +~/.config/ /etc/udev/rules.d/ +~/.local/share/ /etc/modprobe.d/ +~/.ssh/ /etc/sysctl.d/ +~/.gnupg/ /etc/systemd/ +Flatpak user installs Flatpak system installs +systemd --user services systemd system services +cargo install pacman/apt/apk install (system) +``` + +## Major State + +### Exported Environment Variables (from `system-info.sh`) + +| Variable | Scope | Mutability | +|----------|-------|------------| +| `OS`, `DISTRO`, `DISTRO_FAMILY` | Global | Read-only after detection | +| `ARCH`, `ARCH_FAMILY` | Global | Read-only | +| `DEVICE_MODEL`, `CHASSIS_TYPE` | Global | Read-only | +| `HAS_GUI`, `DESKTOP_ENVIRONMENT`, `DISPLAY_SERVER` | Global | Read-only | +| `GPU_FAMILY`, `IS_BATTERY_DEVICE` | Global | Read-only | +| `POWERFUL_PC`, `IS_DEVELOPMENT_DEVICE`, `IS_GAMING_DEVICE` | Global | Read-only | +| `HAS_SU_PRIVILEGES` | Global | Read-only | +| `REPO_DIR`, `ROOT_*`, `HOME_REAL`, `XDG_*` | Global | Read-only | + +### Derived State (in `configure-system.sh`) + +| Variable | Derived From | Purpose | +|----------|--------------|---------| +| `GTK_THEME`, `GTK_THEME_VARIANT` | `get_theme()`, `get_theme_mode()` | Theme selection | +| `INTERFACE_FONT`, `MONOSPACE_FONT`, etc. | Screen height, DPI | Font sizing | +| `TERMINAL_SIZE_COLS/ROWS` | Screen resolution | Terminal geometry | +| `ZOOM_LEVEL` | Screen height | UI scaling | +| `USING_INTEL_GPU`, `USING_NVIDIA_GPU` | `GPU_FAMILY` | GPU-specific config | +| `IS_SERVER` | Screen resolution | Headless detection | + +## Major Integrations + +| Integration | Layer | Configuration | +|-------------|-------|---------------| +| Package managers | Foundation | `package-management.sh` dispatch | +| Display servers | Detection | `system-info.sh` → `DISPLAY_SERVER` | +| Desktop environments | Detection + Config | `DESKTOP_ENVIRONMENT` → gsettings/kwriteconfig | +| GPU drivers | Kernel params | `configure-system.sh` → modprobe.d | +| Bootloader | Config | `update-grub.sh` → /etc/grub.d/ | +| Hardware (Argon) | Detection + Config | `configure-hardware-integration.sh` | +| Android/Termux | Platform guard | `IS_ANDROID` → skip system config | + +## System-Wide Invariants + +1. **Idempotency** — All file operations use `update_file_if_distinct` (content comparison) +2. **Privilege separation** — Explicit `run_script` vs `run_script_as_su`; no ambient authority +3. **Platform guards** — GUI config wrapped in `if ${HAS_GUI}`; Android guarded by `IS_ANDROID` +4. **Binary existence checks** — `update_file_if_binary_exists` before deploying app configs +5. **Ordering** — `run.sh` enforces strict phase sequence; dependencies flow forward +6. **Failure isolation** — No `set -e` at top level; individual script failures don't halt orchestration +7. **Environment consistency** — `LANG=en_US.UTF-8` forced for deterministic command output +8. **Distro awareness** — All package operations dispatch via `DISTRO_FAMILY` +9. **Resolution awareness** — All sizing derives from detected screen dimensions +10. **Device awareness** — Special handling for Argon ONE UP, Steam Deck, Raspberry Pi \ No newline at end of file diff --git a/docs/behaviour/application-launcher-customisation.md b/docs/behaviour/application-launcher-customisation.md new file mode 100644 index 0000000..31a5a8e --- /dev/null +++ b/docs/behaviour/application-launcher-customisation.md @@ -0,0 +1,649 @@ +# Application Launcher Customisation + +This document describes how application launchers are configured, modified, +and managed across the system. + +## Overview + +The application launcher customisation system modifies `.desktop` files for +installed applications, setting appropriate names, categories, icons, and +window class names. + +## Flow Diagram + +``` +┌─────────────────────────────────────────────────────────────────┐ +│ Application Launcher Customisation Flow │ +└─────────────────────────────────────────────────────────────────┘ + │ + ▼ +┌─────────────────────────────────────────────────────────────────┐ +│ Launcher Discovery │ +│ • Scan /usr/share/applications │ +│ • Scan ~/.local/share/applications │ +│ • Scan ~/.config/autostart │ +└─────────────────────────────────────────────────────────────────┘ + │ + ▼ +┌─────────────────────────────────────────────────────────────────┐ +│ Launcher Modification │ +│ • Set Name and localized names │ +│ • Set Categories │ +│ • Set Icon │ +│ • Set NoDisplay │ +│ • Set StartupWMClass │ +│ • Set Keywords │ +└─────────────────────────────────────────────────────────────────┘ + │ + ▼ +┌─────────────────────────────────────────────────────────────────┐ +│ Launcher Deployment │ +│ • Deploy custom launchers │ +│ • Create desktop entries │ +│ • Update desktop database │ +└─────────────────────────────────────────────────────────────────┘ +``` + +## Launcher Discovery + +### Script: `scripts/configure-launchers.sh` + +```bash +#!/bin/bash +set -euo pipefail + +# Load foundation +source "${REPO_DIR}/scripts/common/filesystem.sh" +source "${REPO_DIR}/scripts/common/common.sh" + +# Launcher categories +declare -a LAUNCHER_CATEGORIES=( + "ai" + "app-stores" + "archive-managers" + "audio-players" + "browsers" + "calculators" + "cameras" + "chat" + "code-editors" + "databases" + "disk" + "email" + "file-managers" + "games" + "ides" + "image-viewers" + "media-players" + "messengers" + "notes" + "office" + "password-managers" + "remote-desktop" + "screenshots" + "settings" + "terminals" + "text-editors" + "video-players" + "virtualization" + "vpn" + "web-apps" +) + +configure_launchers() { + log_section "Application Launcher Customisation" + + # Discover launchers + discover_launchers + + # Modify launchers + modify_launchers + + # Deploy custom launchers + deploy_custom_launchers + + log_success "Application launchers customised" +} + +discover_launchers() { + log_subsection "Discovering Launchers" + + local launcher_dirs=( + "/usr/share/applications" + "${HOME}/.local/share/applications" + "${HOME}/.config/autostart" + ) + + for dir in "${launcher_dirs[@]}"; do + if [ -d "${dir}" ]; then + log_info "Scanning: ${dir}" + find "${dir}" -name "*.desktop" -type f + fi + done +} +``` + +## Launcher Modification + +### Modification Function + +```bash +modify_launchers() { + log_subsection "Modifying Launchers" + + local launcher_files=() + + # Collect launcher files + for dir in /usr/share/applications "${HOME}/.local/share/applications"; do + if [ -d "${dir}" ]; then + while IFS= read -r -d '' file; do + launcher_files+=("${file}") + done < <(find "${dir}" -name "*.desktop" -type f -print0) + fi + done + + # Modify each launcher + for launcher in "${launcher_files[@]}"; do + modify_launcher "${launcher}" + done + + log_info "Launchers modified: ${#launcher_files[@]}" +} + +modify_launcher() { + local launcher="$1" + + # Read launcher content + local content=$(cat "${launcher}") + + # Modify launcher based on application + modify_launcher_by_app "${launcher}" "${content}" + + # Write back if changed + if [ "${content}" != "$(cat "${launcher}")" ]; then + log_info "Modified launcher: ${launcher}" + fi +} + +modify_launcher_by_app() { + local launcher="$1" + local content="$2" + + # Extract application name + local app_name=$(grep -oP '(?<=^Name=).+' "${launcher}" | head -1) + + # Modify based on application + case "${app_name}" in + "Visual Studio Code") + modify_vscode "${launcher}" + ;; + "Discord") + modify_discord "${launcher}" + ;; + "Telegram") + modify_telegram "${launcher}" + ;; + "Signal Desktop") + modify_signal "${launcher}" + ;; + "Firefox") + modify_firefox "${launcher}" + ;; + "Chromium") + modify_chromium "${launcher}" + ;; + "Google Chrome") + modify_chrome "${launcher}" + ;; + "LibreOffice Writer") + modify_libreoffice "${launcher}" + ;; + "GIMP") + modify_gimp "${launcher}" + ;; + "VLC media player") + modify_vlc "${launcher}" + ;; + *) + # Generic modification + modify_generic "${launcher}" + ;; + esac +} +``` + +### Generic Launcher Modification + +```bash +modify_generic() { + local launcher="$1" + + # Set Name (if not already set) + if ! grep -q "^Name=" "${launcher}"; then + local app_name=$(grep -oP '(?<=^Exec=).+' "${launcher}" | sed 's/.*\///' | sed 's/^[^/]*\///') + sed -i "1i Name=${app_name}" "${launcher}" + fi + + # Set Name[ro] (Romanian localization) + if grep -q "^Name=" "${launcher}"; then + local name=$(grep -oP '(?<=^Name=).+' "${launcher}" | head -1) + sed -i "s/^Name=.*/Name=${name}\nName[ro]=${name}/" "${launcher}" + fi + + # Set Categories + if ! grep -q "^Categories=" "${launcher}"; then + sed -i "s/^Exec=.*/&\nCategories=Application;" "${launcher}" + fi + + # Set Icon + if ! grep -q "^Icon=" "${launcher}"; then + local icon=$(grep -oP '(?<=^Exec=).+' "${launcher}" | sed 's/.*\///' | sed 's/^[^/]*\///') + sed -i "s/^Exec=.*/&\nIcon=${icon}/" "${launcher}" + fi + + # Set NoDisplay + if ! grep -q "^NoDisplay=" "${launcher}"; then + sed -i "s/^Exec=.*/&\nNoDisplay=false/" "${launcher}" + fi + + # Set StartupWMClass + if ! grep -q "^StartupWMClass=" "${launcher}"; then + local wm_class=$(grep -oP '(?<=^Exec=).+' "${launcher}" | sed 's/.*\///' | sed 's/^[^/]*\///') + sed -i "s/^Exec=.*/&\nStartupWMClass=${wm_class}/" "${launcher}" + fi + + # Set Keywords + if ! grep -q "^Keywords=" "${launcher}"; then + sed -i "s/^Exec=.*/&\nKeywords=Application;" "${launcher}" + fi +} +``` + +### Application-Specific Modifications + +#### Visual Studio Code + +```bash +modify_vscode() { + local launcher="$1" + + # Set Name + sed -i 's/^Name=.*/Name=Visual Studio Code/' "${launcher}" + + # Set Name[ro] + sed -i 's/^Name=.*/Name=Visual Studio Code\nName[ro]=Visual Studio Code/' "${launcher}" + + # Set Categories + sed -i 's/^Exec=.*/&\nCategories=Development;IDE;' "${launcher}" + + # Set Icon + sed -i 's/^Exec=.*/&\nIcon=code/' "${launcher}" + + # Set StartupWMClass + sed -i 's/^Exec=.*/&\nStartupWMClass=Code/' "${launcher}" + + # Set Keywords + sed -i 's/^Exec=.*/&\nKeywords=Development;IDE;Code;Editor;' "${launcher}" +} +``` + +#### Discord + +```bash +modify_discord() { + local launcher="$1" + + # Set Name + sed -i 's/^Name=.*/Name=Discord/' "${launcher}" + + # Set Name[ro] + sed -i 's/^Name=.*/Name=Discord\nName[ro]=Discord/' "${launcher}" + + # Set Categories + sed -i 's/^Exec=.*/&\nCategories=Network;Chat;InstantMessaging;' "${launcher}" + + # Set Icon + sed -i 's/^Exec=.*/&\nIcon=discord/' "${launcher}" + + # Set StartupWMClass + sed -i 's/^Exec=.*/&\nStartupWMClass=discord/' "${launcher}" + + # Set Keywords + sed -i 's/^Exec=.*/&\nKeywords=Network;Chat;InstantMessaging;Discord;' "${launcher}" +} +``` + +#### Telegram + +```bash +modify_telegram() { + local launcher="$1" + + # Set Name + sed -i 's/^Name=.*/Name=Telegram/' "${launcher}" + + # Set Name[ro] + sed -i 's/^Name=.*/Name=Telegram\nName[ro]=Telegram/' "${launcher}" + + # Set Categories + sed -i 's/^Exec=.*/&\nCategories=Network;Chat;InstantMessaging;' "${launcher}" + + # Set Icon + sed -i 's/^Exec=.*/&\nIcon=telegram-desktop/' "${launcher}" + + # Set StartupWMClass + sed -i 's/^Exec=.*/&\nStartupWMClass=Telegram/' "${launcher}" + + # Set Keywords + sed -i 's/^Exec=.*/&\nKeywords=Network;Chat;InstantMessaging;Telegram;' "${launcher}" +} +``` + +#### Signal Desktop + +```bash +modify_signal() { + local launcher="$1" + + # Set Name + sed -i 's/^Name=.*/Name=Signal/' "${launcher}" + + # Set Name[ro] + sed -i 's/^Name=.*/Name=Signal\nName[ro]=Signal/' "${launcher}" + + # Set Categories + sed -i 's/^Exec=.*/&\nCategories=Network;Chat;InstantMessaging;' "${launcher}" + + # Set Icon + sed -i 's/^Exec=.*/&\nIcon=signal/' "${launcher}" + + # Set StartupWMClass + sed -i 's/^Exec=.*/&\nStartupWMClass=Signal/' "${launcher}" + + # Set Keywords + sed -i 's/^Exec=.*/&\nKeywords=Network;Chat;InstantMessaging;Signal;' "${launcher}" +} +``` + +#### Firefox + +```bash +modify_firefox() { + local launcher="$1" + + # Set Name + sed -i 's/^Name=.*/Name=Firefox Web Browser/' "${launcher}" + + # Set Name[ro] + sed -i 's/^Name=.*/Name=Firefox Web Browser\nName[ro]=Firefox Web Browser/' "${launcher}" + + # Set Categories + sed -i 's/^Exec=.*/&\nCategories=Network;WebBrowser;' "${launcher}" + + # Set Icon + sed -i 's/^Exec=.*/&\nIcon=firefox/' "${launcher}" + + # Set StartupWMClass + sed -i 's/^Exec=.*/&\nStartupWMClass=firefox/' "${launcher}" + + # Set Keywords + sed -i 's/^Exec=.*/&\nKeywords=Network;WebBrowser;Firefox;' "${launcher}" +} +``` + +#### Chromium + +```bash +modify_chromium() { + local launcher="$1" + + # Set Name + sed -i 's/^Name=.*/Name=Chromium Web Browser/' "${launcher}" + + # Set Name[ro] + sed -i 's/^Name=.*/Name=Chromium Web Browser\nName[ro]=Chromium Web Browser/' "${launcher}" + + # Set Categories + sed -i 's/^Exec=.*/&\nCategories=Network;WebBrowser;' "${launcher}" + + # Set Icon + sed -i 's/^Exec=.*/&\nIcon=chromium/' "${launcher}" + + # Set StartupWMClass + sed -i 's/^Exec=.*/&\nStartupWMClass=chromium/' "${launcher}" + + # Set Keywords + sed -i 's/^Exec=.*/&\nKeywords=Network;WebBrowser;Chromium;' "${launcher}" +} +``` + +#### Google Chrome + +```bash +modify_chrome() { + local launcher="$1" + + # Set Name + sed -i 's/^Name=.*/Name=Google Chrome/' "${launcher}" + + # Set Name[ro] + sed -i 's/^Name=.*/Name=Google Chrome\nName[ro]=Google Chrome/' "${launcher}" + + # Set Categories + sed -i 's/^Exec=.*/&\nCategories=Network;WebBrowser;' "${launcher}" + + # Set Icon + sed -i 's/^Exec=.*/&\nIcon=google-chrome/' "${launcher}" + + # Set StartupWMClass + sed -i 's/^Exec=.*/&\nStartupWMClass=google-chrome/' "${launcher}" + + # Set Keywords + sed -i 's/^Exec=.*/&\nKeywords=Network;WebBrowser;Chrome;' "${launcher}" +} +``` + +#### LibreOffice Writer + +```bash +modify_libreoffice() { + local launcher="$1" + + # Set Name + sed -i 's/^Name=.*/Name=LibreOffice Writer/' "${launcher}" + + # Set Name[ro] + sed -i 's/^Name=.*/Name=LibreOffice Writer\nName[ro]=LibreOffice Writer/' "${launcher}" + + # Set Categories + sed -i 's/^Exec=.*/&\nCategories=Office;WordProcessor;TextEditor;' "${launcher}" + + # Set Icon + sed -i 's/^Exec=.*/&\nIcon=libreoffice-writer/' "${launcher}" + + # Set StartupWMClass + sed -i 's/^Exec=.*/&\nStartupWMClass=writer/' "${launcher}" + + # Set Keywords + sed -i 's/^Exec=.*/&\nKeywords=Office;WordProcessor;TextEditor;LibreOffice;' "${launcher}" +} +``` + +#### GIMP + +```bash +modify_gimp() { + local launcher="$1" + + # Set Name + sed -i 's/^Name=.*/Name=GIMP/' "${launcher}" + + # Set Name[ro] + sed -i 's/^Name=.*/Name=GIMP\nName[ro]=GIMP/' "${launcher}" + + # Set Categories + sed -i 's/^Exec=.*/&\nCategories=Graphics;2DGraphics;RasterGraphics;' "${launcher}" + + # Set Icon + sed -i 's/^Exec=.*/&\nIcon=gimp/' "${launcher}" + + # Set StartupWMClass + sed -i 's/^Exec=.*/&\nStartupWMClass=gimp/' "${launcher}" + + # Set Keywords + sed -i 's/^Exec=.*/&\nKeywords=Graphics;2DGraphics;RasterGraphics;GIMP;' "${launcher}" +} +``` + +#### VLC media player + +```bash +modify_vlc() { + local launcher="$1" + + # Set Name + sed -i 's/^Name=.*/Name=VLC media player/' "${launcher}" + + # Set Name[ro] + sed -i 's/^Name=.*/Name=VLC media player\nName[ro]=VLC media player/' "${launcher}" + + # Set Categories + sed -i 's/^Exec=.*/&\nCategories=AudioVideo;Player;Video;' "${launcher}" + + # Set Icon + sed -i 's/^Exec=.*/&\nIcon=vlc/' "${launcher}" + + # Set StartupWMClass + sed -i 's/^Exec=.*/&\nStartupWMClass=vlc/' "${launcher}" + + # Set Keywords + sed -i 's/^Exec=.*/&\nKeywords=AudioVideo;Player;Video;VLC;' "${launcher}" +} +``` + +## Launcher Deployment + +### Deploy Custom Launchers + +```bash +deploy_custom_launchers() { + log_subsection "Deploying Custom Launchers" + + # Deploy custom launchers from resources + if [ -d "${REPO_RES_DIR}/pcmanfm" ]; then + for launcher in "${REPO_RES_DIR}/pcmanfm"/*.desktop; do + if [ -f "${launcher}" ]; then + local basename=$(basename "${launcher}") + update_file_if_distinct "${launcher}" "${HOME}/.local/share/applications/${basename}" + fi + done + fi + + # Deploy custom launchers from rc + if [ -d "${REPO_RC_DIR}/launchers" ]; then + for launcher in "${REPO_RC_DIR}/launchers"/*.desktop; do + if [ -f "${launcher}" ]; then + local basename=$(basename "${launcher}") + update_file_if_distinct "${launcher}" "${HOME}/.local/share/applications/${basename}" + fi + done + fi + + log_info "Custom launchers deployed" +} +``` + +### Update Desktop Database + +```bash +update_desktop_database() { + log_subsection "Updating Desktop Database" + + # Update desktop database + if command_exists update-desktop-database; then + update-desktop-database "${HOME}/.local/share/applications" + update-desktop-database "/usr/share/applications" + log_info "Desktop database updated" + else + log_warn "update-desktop-database not found, skipping" + fi +} +``` + +## Launcher Categories + +### Category Mapping + +| Application | Categories | +|-------------|------------| +| AI apps | AI;Development; | +| App Stores | System;PackageManager; | +| Archive Managers | System;FileManager; | +| Audio Players | AudioVideo;Player;Audio; | +| Browsers | Network;WebBrowser; | +| Calculators | Education;Calculator; | +| Cameras | Graphics;Camera; | +| Chat | Network;Chat;InstantMessaging; | +| Code Editors | Development;TextEditor; | +| Databases | Development;Database; | +| Disk | System;FileManager; | +| Email | Network;Email; | +| File Managers | System;FileManager; | +| Games | Game; | +| IDEs | Development;IDE; | +| Image Viewers | Graphics;Viewer; | +| Media Players | AudioVideo;Player;Video; | +| Messengers | Network;Chat;InstantMessaging; | +| Notes | Office;Note; | +| Office | Office; | +| Password Managers | Security;Password; | +| Remote Desktop | Network;RemoteAccess; | +| Screenshots | Graphics;Screenshot; | +| Settings | System;Settings; | +| Terminals | System;TerminalEmulator; | +| Text Editors | Development;TextEditor; | +| Video Players | AudioVideo;Player;Video; | +| Virtualization | System;Virtualization; | +| VPN | Network;VPN; | +| Web Apps | Network;WebBrowser; | + +## Logging + +### Launcher Customisation Log + +``` +=== Application Launcher Customisation === +[INFO] Scanning: /usr/share/applications +[INFO] Scanning: /home/user/.local/share/applications +[INFO] Scanning: /home/user/.config/autostart +[INFO] Modified launcher: /usr/share/applications/code.desktop +[INFO] Modified launcher: /usr/share/applications/discord.desktop +[INFO] Modified launcher: /usr/share/applications/telegram-desktop.desktop +[INFO] Modified launcher: /usr/share/applications/firefox.desktop +[INFO] Modified launcher: /usr/share/applications/libreoffice-writer.desktop +[INFO] Modified launcher: /usr/share/applications/gimp.desktop +[INFO] Modified launcher: /usr/share/applications/vlc.desktop +[INFO] Launchers modified: 100 +[INFO] Custom launchers deployed +[INFO] Desktop database updated +[SUCCESS] Application launchers customised +``` + +## Performance + +### Typical Execution Times + +| Operation | Time | +|-----------|------| +| Launcher discovery | 1-3 seconds | +| Launcher modification | 5-15 seconds | +| Launcher deployment | 1-3 seconds | +| Desktop database update | 1-3 seconds | +| **Total** | **8-24 seconds** | + +### Optimisation + +- Skip already-modified launchers +- Batch launcher modifications +- Parallel launcher processing +- Cache launcher metadata \ No newline at end of file diff --git a/docs/behaviour/autostart-and-default-apps.md b/docs/behaviour/autostart-and-default-apps.md new file mode 100644 index 0000000..ca66010 --- /dev/null +++ b/docs/behaviour/autostart-and-default-apps.md @@ -0,0 +1,487 @@ +# Autostart and Default Applications + +This document describes how autostart applications and default applications +are configured across the system. + +## Overview + +The autostart and default applications system manages user autostart entries +and sets default applications for MIME types. + +## Flow Diagram + +``` +┌─────────────────────────────────────────────────────────────────┐ +│ Autostart and Default Apps Flow │ +└─────────────────────────────────────────────────────────────────┘ + │ + ▼ +┌─────────────────────────────────────────────────────────────────┐ +│ Autostart Configuration │ +│ • Configure user autostart entries │ +│ • Configure system autostart entries │ +│ • Manage autostart conditions │ +└─────────────────────────────────────────────────────────────────┘ + │ + ▼ +┌─────────────────────────────────────────────────────────────────┐ +│ Default Applications │ +│ • Set default applications via mimeapps.list │ +│ • Configure MIME associations │ +│ • Set default browser, editor, etc. │ +└─────────────────────────────────────────────────────────────────┘ +``` + +## Autostart Configuration + +### Script: `scripts/configure-autostart-apps.sh` + +```bash +#!/bin/bash +set -euo pipefail + +# Load foundation +source "${REPO_DIR}/scripts/common/filesystem.sh" +source "${REPO_DIR}/scripts/common/common.sh" + +configure_autostart_apps() { + log_section "Autostart Applications Configuration" + + # Configure user autostart + configure_user_autostart + + # Configure system autostart (if root) + if [ "${HAS_SU_PRIVILEGES}" = "true" ]; then + run_as_su configure_system_autostart + fi + + log_success "Autostart applications configured" +} + +configure_user_autostart() { + log_subsection "User Autostart" + + local autostart_dir="${HOME}/.config/autostart" + ensure_directory "${autostart_dir}" + + # Applications to autostart + local autostart_apps=( + "plank" + "signal-desktop" + "telegram-desktop" + "discord" + "electron-mail" + "planify" + ) + + # Applications to disable + local disabled_apps=( + "discord" + ) + + # Enable autostart for applications + for app in "${autostart_apps[@]}"; do + enable_autostart "${app}" "${autostart_dir}" + done + + # Disable autostart for applications + for app in "${disabled_apps[@]}"; do + disable_autostart "${app}" "${autostart_dir}" + done + + log_info "User autostart configured" +} + +enable_autostart() { + local app="$1" + local autostart_dir="$2" + + # Find the .desktop file + local desktop_file=$(find /usr/share/applications "${HOME}/.local/share/applications" -name "${app}.desktop" 2>/dev/null | head -1) + + if [ -z "${desktop_file}" ]; then + log_warn "Desktop file not found for: ${app}" + return 0 + fi + + # Copy to autostart directory + local target="${autostart_dir}/${app}.desktop" + cp "${desktop_file}" "${target}" + + # Ensure it's enabled + sed -i 's/^Hidden=.*/Hidden=false/' "${target}" + sed -i 's/^NoDisplay=.*/NoDisplay=false/' "${target}" + + log_info "Enabled autostart: ${app}" +} + +disable_autostart() { + local app="$1" + local autostart_dir="$2" + + local target="${autostart_dir}/${app}.desktop" + + if [ -f "${target}" ]; then + # Disable by setting Hidden=true + sed -i 's/^Hidden=.*/Hidden=true/' "${target}" + log_info "Disabled autostart: ${app}" + else + # Create a disabled entry + cat > "${target}" </dev/null | head -1) + + if [ -n "${desktop_file}" ]; then + cp "${desktop_file}" "${autostart_dir}/" + log_info "Enabled system autostart: ${app}" + fi + done + + log_info "System autostart configured" +} +``` + +### Autostart Conditions + +```bash +# Conditional autostart based on environment +configure_conditional_autostart() { + log_subsection "Conditional Autostart" + + # Only autostart Plank on GUI + if [ "${HAS_GUI}" = "true" ] && [ "${DESKTOP_ENVIRONMENT}" != "phosh" ]; then + enable_autostart "plank" "${HOME}/.config/autostart" + fi + + # Only autostart Discord on powerful PCs + if [ "${IS_POWERFUL_PC}" = "true" ]; then + enable_autostart "discord" "${HOME}/.config/autostart" + else + disable_autostart "discord" "${HOME}/.config/autostart" + fi + + # Only autostart Signal on battery devices + if [ "${IS_BATTERY_DEVICE}" = "true" ]; then + enable_autostart "signal-desktop" "${HOME}/.config/autostart" + fi + + log_info "Conditional autostart configured" +} +``` + +## Default Applications + +### Script: `scripts/configure-default-apps.sh` + +```bash +#!/bin/bash +set -euo pipefail + +# Load foundation +source "${REPO_DIR}/scripts/common/filesystem.sh" +source "${REPO_DIR}/scripts/common/common.sh" + +configure_default_apps() { + log_section "Default Applications Configuration" + + # Configure MIME associations + configure_mime_associations + + # Configure default browser + configure_default_browser + + # Configure default editor + configure_default_editor + + # Configure default terminal + configure_default_terminal + + # Configure default file manager + configure_default_file_manager + + log_success "Default applications configured" +} + +configure_mime_associations() { + log_subsection "MIME Associations" + + local mimeapps="${HOME}/.config/mimeapps.list" + ensure_directory "$(dirname "${mimeapps}")" + + # Create or update mimeapps.list + cat > "${mimeapps}" </dev/null; then + DESKTOP_ENVIRONMENT="GNOME" + elif pgrep -x "plasma" &>/dev/null; then + DESKTOP_ENVIRONMENT="KDE" + elif pgrep -x "mate-panel" &>/dev/null; then + DESKTOP_ENVIRONMENT="MATE" + elif pgrep -x "lxpanel" &>/dev/null; then + DESKTOP_ENVIRONMENT="LXDE" + elif pgrep -x "phosh" &>/dev/null; then + DESKTOP_ENVIRONMENT="Phosh" + else + DESKTOP_ENVIRONMENT="unknown" + fi +} +``` + +### Detection Priority + +| Priority | Variable | Example | +|----------|----------|---------| +| 1 | XDG_CURRENT_DESKTOP | GNOME, KDE, MATE, LXDE | +| 2 | DESKTOP_SESSION | gnome, kde, mate, lxde | +| 3 | XDG_SESSION_DESKTOP | GNOME, KDE, MATE, LXDE | +| 4 | Process detection | gnome-shell, plasma, mate-panel | + +## GNOME Configuration + +### Configuration Methods + +```bash +# GNOME uses gsettings and dconf +configure_gnome() { + log_subsection "GNOME Configuration" + + # Set GTK theme + gsettings set org.gnome.desktop.interface gtk-theme "${GTK3_THEME}" + + # Set icon theme + gsettings set org.gnome.desktop.interface icon-theme "${ICON_THEME}" + + # Set cursor theme + gsettings set org.gnome.desktop.interface cursor-theme "${CURSOR_THEME}" + + # Set font + gsettings set org.gnome.desktop.interface font-name "${INTERFACE_FONT}" + gsettings set org.gnome.desktop.interface monospace-font-name "${MONOSPACE_FONT}" + + # Set color scheme + if [ "${DESKTOP_THEME_IS_DARK}" = "true" ]; then + gsettings set org.gnome.desktop.interface color-scheme "prefer-dark" + else + gsettings set org.gnome.desktop.interface color-scheme "prefer-light" + fi + + # Set shell theme + gsettings set org.gnome.shell.extensions.user-theme name "${GTK3_THEME}" + + # Set window manager theme + gsettings set org.gnome.desktop.wm.preferences theme "${GTK3_THEME}" + + # Set desktop background + gsettings set org.gnome.desktop.background picture-uri "file:///path/to/wallpaper" + + # Set lock screen background + gsettings set org.gnome.desktop.screensaver picture-uri "file:///path/to/wallpaper" + + # Set show desktop icons + gsettings set org.gnome.desktop.background show-desktop-icons false + + # Set show battery percentage + gsettings set org.gnome.desktop.interface show-battery-percentage true + + # Set clock format + gsettings set org.gnome.desktop.interface clock-format '24h' + + # Set date format + gsettings set org.gnome.desktop.interface clock-format '24h' + + # Set enable animations + gsettings set org.gnome.desktop.interface enable-animations true + + # Set enable hot corners + gsettings set org.gnome.desktop.interface enable-hot-corners false + + # Set enable edge tiling + gsettings set org.gnome.mutter edge-tiling true + + # Set enable attach modal dialogs + gsettings set org.gnome.mutter attach-modal-dialogs true + + # Set enable dynamic workspaces + gsettings set org.gnome.desktop.privacy dynamic-workspaces false + + # Set enable hot corners + gsettings set org.gnome.desktop.interface enable-hot-corners false + + # Set enable show apps at top + gsettings set org.gnome.shell enable-hot-corners false + + # Set enable hot corners + gsettings set org.gnome.shell enable-hot-corners false + + log_info "GNOME configured" +} +``` + +### GNOME Extensions + +```bash +# Install GNOME extensions +install_gnome_extensions() { + log_subsection "GNOME Extensions" + + # Install extensions + local extensions=( + "user-theme@gnome-shell-extensions.gcampax.github.com" + "dash-to-dock@micxgx.gmail.com" + "arc-menu@arcmenu.github.com" + "just-perfection@just-perfection.github.com" + ) + + for extension in "${extensions[@]}"; do + if ! gnome-extensions list | grep -q "${extension}"; then + gnome-extensions install "${extension}" + log_info "Installed extension: ${extension}" + fi + done + + # Enable extensions + for extension in "${extensions[@]}"; do + gnome-extensions enable "${extension}" + log_info "Enabled extension: ${extension}" + done +} +``` + +## KDE Configuration + +### Configuration Methods + +```bash +# KDE uses kwriteconfig5 and kdeglobals +configure_kde() { + log_subsection "KDE Configuration" + + local kde_config="${HOME}/.config/kdeglobals" + + # Set widget style + kwriteconfig5 --file "${kde_config}" --group "General" --key "widgetStyle" "${GTK_THEME}" + + # Set font + kwriteconfig5 --file "${kde_config}" --group "General" --key "font" "${INTERFACE_FONT_FACE},${INTERFACE_FONT_SIZE},-1,5,50,0,0,0,0,0" + + # Set fixed font + kwriteconfig5 --file "${kde_config}" --group "General" --key "fixedFont" "${MONOSPACE_FONT_FACE},${MONOSPACE_FONT_SIZE},-1,5,50,0,0,0,0,0" + + # Set icon theme + kwriteconfig5 --file "${kde_config}" --group "Icons" --key "Theme" "${ICON_THEME}" + + # Set cursor theme + kwriteconfig5 --file "${kde_config}" --group "Mouse" --key "cursorTheme" "${CURSOR_THEME}" + + # Set show desktop icons + kwriteconfig5 --file "${kde_config}" --group "Desktop" --key "ShowDesktopIcons" "true" + + # Set show taskbar + kwriteconfig5 --file "${kde_config}" --group "Taskbar" --key "ShowTaskbar" "true" + + # Set show desktop grid + kwriteconfig5 --file "${kde_config}" --group "Desktop" --key "ShowDesktopGrid" "false" + + log_info "KDE configured" +} +``` + +### KDE Plasma Configuration + +```bash +# Configure Plasma panels +configure_kde_plasma() { + log_subsection "KDE Plasma Configuration" + + # Configure panel + local panel_config="${HOME}/.config/plasma-org.kde.plasma.plasmoidrc" + + # Set panel position + kwriteconfig5 --file "${panel_config}" --group "General" --key "Location" "Bottom" + + # Set panel height + kwriteconfig5 --file "${panel_config}" --group "General" --key "Height" "40" + + # Set panel alignment + kwriteconfig5 --file "${panel_config}" --group "General" --key "Alignment" "Center" + + # Set panel visibility + kwriteconfig5 --file "${panel_config}" --group "General" --key "HideMode" "0" + + log_info "KDE Plasma configured" +} +``` + +## MATE Configuration + +### Configuration Methods + +```bash +# MATE uses gsettings and mateconf +configure_mate() { + log_subsection "MATE Configuration" + + # Set GTK theme + gsettings set org.mate.interface gtk-theme "${GTK3_THEME}" + + # Set icon theme + gsettings set org.mate.interface icon-theme "${ICON_THEME}" + + # Set cursor theme + gsettings set org.mate.interface cursor-theme "${CURSOR_THEME}" + + # Set font + gsettings set org.mate.interface font-name "${INTERFACE_FONT}" + gsettings set org.mate.interface monospace-font-name "${MONOSPACE_FONT}" + + # Set show desktop icons + gsettings set org.mate.caja.desktop show-desktop-icons false + + # Set show panel + gsettings set org.mate.panel general show-panels true + + # Set panel position + gsettings set org.mate.panel.toplevels.panel1 orientation "top" + + # Set panel size + gsettings set org.mate.panel.toplevels.panel1 size "40" + + log_info "MATE configured" +} +``` + +## LXDE Configuration + +### Configuration Methods + +```bash +# LXDE uses lxpanel, pcmanfm, openbox +configure_lxde() { + log_subsection "LXDE Configuration" + + # Configure panel + configure_lxde_panel + + # Configure file manager + configure_pcmanfm + + # Configure window manager + configure_openbox + + log_info "LXDE configured" +} + +configure_lxde_panel() { + log_info "Configuring LXDE panel..." + + # Deploy panel configuration + if [ -f "${REPO_RC_DIR}/lxde-panel" ]; then + update_file_if_distinct \ + "${REPO_RC_DIR}/lxde-panel" \ + "${HOME}/.config/lxpanel/LXDE/panels/panel" + fi + + # Deploy dock configuration + if [ -f "${REPO_RC_DIR}/lxde-dock" ]; then + update_file_if_distinct \ + "${REPO_RC_DIR}/lxde-dock" \ + "${HOME}/.config/lxpanel/LXDE/panels/dock" + fi + + log_info "LXDE panel configured" +} + +configure_pcmanfm() { + log_info "Configuring PCManFM..." + + # Deploy desktop entries + if [ -f "resources/pcmanfm/open-in-code.desktop" ]; then + update_file_if_distinct \ + "resources/pcmanfm/open-in-code.desktop" \ + "${HOME}/.local/share/applications/open-in-code.desktop" + fi + + if [ -f "resources/pcmanfm/open-in-terminal.desktop" ]; then + update_file_if_distinct \ + "resources/pcmanfm/open-in-terminal.desktop" \ + "${HOME}/.local/share/applications/open-in-terminal.desktop" + fi + + log_info "PCManFM configured" +} + +configure_openbox() { + log_info "Configuring Openbox..." + + # Deploy Openbox configuration + if [ -f "${REPO_RC_DIR}/openbox-rc.xml" ]; then + update_file_if_distinct \ + "${REPO_RC_DIR}/openbox-rc.xml" \ + "${HOME}/.config/openbox/rc.xml" + fi + + log_info "Openbox configured" +} +``` + +## Phosh Configuration + +### Configuration Methods + +```bash +# Phosh uses gsettings +configure_phosh() { + log_subsection "Phosh Configuration" + + # Set GTK theme + gsettings set org.gnome.desktop.interface gtk-theme "${GTK3_THEME}" + + # Set icon theme + gsettings set org.gnome.desktop.interface icon-theme "${ICON_THEME}" + + # Set cursor theme + gsettings set org.gnome.desktop.interface cursor-theme "${CURSOR_THEME}" + + # Set font + gsettings set org.gnome.desktop.interface font-name "${INTERFACE_FONT}" + gsettings set org.gnome.desktop.interface monospace-font-name "${MONOSPACE_FONT}" + + # Set color scheme + if [ "${DESKTOP_THEME_IS_DARK}" = "true" ]; then + gsettings set org.gnome.desktop.interface color-scheme "prefer-dark" + else + gsettings set org.gnome.desktop.interface color-scheme "prefer-light" + fi + + log_info "Phosh configured" +} +``` + +## Desktop Environment Switching + +### Switching Between Desktop Environments + +```bash +# Switch desktop environment +switch_desktop_environment() { + local target_de="$1" + + log_info "Switching to ${target_de}..." + + # Stop current desktop environment + stop_desktop_environment + + # Apply new configuration + case "${target_de}" in + gnome) + configure_gnome + ;; + kde) + configure_kde + ;; + mate) + configure_mate + ;; + lxde) + configure_lxde + ;; + phosh) + configure_phosh + ;; + *) + log_error "Unknown desktop environment: ${target_de}" + return 1 + ;; + esac + + # Start new desktop environment + start_desktop_environment + + log_success "Switched to ${target_de}" +} +``` + +## Verification + +### Desktop Environment Verification + +```bash +verify_desktop_environment() { + log_subsection "Verifying Desktop Environment" + + local current_de=$(detect_desktop_environment) + + case "${current_de}" in + gnome) + verify_gnome_settings + ;; + kde) + verify_kde_settings + ;; + mate) + verify_mate_settings + ;; + lxde) + verify_lxde_settings + ;; + phosh) + verify_phosh_settings + ;; + *) + log_warn "Unknown desktop environment: ${current_de}" + ;; + esac +} + +verify_gnome_settings() { + local gtk_theme=$(gsettings get org.gnome.desktop.interface gtk-theme) + local icon_theme=$(gsettings get org.gnome.desktop.interface icon-theme) + + if [ "${gtk_theme}" != "'${GTK3_THEME}'" ]; then + log_warn "GTK theme mismatch: expected ${GTK3_THEME}, got ${gtk_theme}" + fi + + if [ "${icon_theme}" != "'${ICON_THEME}'" ]; then + log_warn "Icon theme mismatch: expected ${ICON_THEME}, got ${icon_theme}" + fi +} +``` + +## Logging + +### Desktop Environment Configuration Log + +``` +=== Desktop Environment Configuration === +[INFO] Detected desktop environment: GNOME +[INFO] Applying GNOME settings +[INFO] Setting GTK theme: adw-gtk3 +[INFO] Setting icon theme: Papirus-Dark +[INFO] Setting cursor theme: Vimix-white-cursors +[INFO] Setting font: Sans Regular 11 +[INFO] Setting monospace font: Droid Sans Regular 12 +[INFO] Setting color scheme: prefer-dark +[INFO] Installing GNOME extensions +[INFO] Installed extension: user-theme@gnome-shell-extensions.gcampax.github.com +[INFO] Enabled extension: user-theme@gnome-shell-extensions.gcampax.github.com +[INFO] Installed extension: dash-to-dock@micxgx.gmail.com +[INFO] Enabled extension: dash-to-dock@micxgx.gmail.com +[SUCCESS] GNOME configured +``` + +## Performance + +### Typical Execution Times + +| Desktop Environment | Time | +|---------------------|------| +| GNOME | 2-5 seconds | +| KDE | 2-5 seconds | +| MATE | 1-3 seconds | +| LXDE | 1-3 seconds | +| Phosh | 1-3 seconds | +| **Total** | **1-5 seconds** | + +### Optimisation + +- Skip already-configured settings +- Batch gsettings calls +- Cache desktop environment detection +- Lazy loading of desktop environment specific code \ No newline at end of file diff --git a/docs/behaviour/directory-and-file-management.md b/docs/behaviour/directory-and-file-management.md new file mode 100644 index 0000000..bb7f445 --- /dev/null +++ b/docs/behaviour/directory-and-file-management.md @@ -0,0 +1,461 @@ +# Directory and File Management + +This document describes how directories and files are managed, including XDG +directories, hidden files, symlinks, and special directory configurations. + +## Overview + +The directory and file management system configures user directories, manages +hidden files, creates symlinks, and handles special directory configurations +for applications like Minecraft and Android. + +## Flow Diagram + +``` +┌─────────────────────────────────────────────────────────────────┐ +│ Directory and File Management Flow │ +└─────────────────────────────────────────────────────────────────┘ + │ + ▼ +┌─────────────────────────────────────────────────────────────────┐ +│ XDG Directory Configuration │ +│ • Configure user-dirs.conf │ +│ • Configure user-dirs.dirs │ +│ • Configure user-dirs.locale │ +└─────────────────────────────────────────────────────────────────┘ + │ + ▼ +┌─────────────────────────────────────────────────────────────────┐ +│ Hidden Files Management │ +│ • Deploy .hidden files │ +│ • Configure hidden files for home, Documents, Downloads │ +│ • Romanian/English variants │ +└─────────────────────────────────────────────────────────────────┘ + │ + ▼ +┌─────────────────────────────────────────────────────────────────┐ +│ Symlink Management │ +│ • Create directory symlinks │ +│ • Minecraft screenshots symlink │ +│ • Android emulated storage symlinks │ +└─────────────────────────────────────────────────────────────────┘ + │ + ▼ +┌─────────────────────────────────────────────────────────────────┐ +│ Directory Icons │ +│ • Set folder icons │ +│ • Configure project folder icons │ +└─────────────────────────────────────────────────────────────────┘ +``` + +## XDG Directory Configuration + +### Script: `scripts/configure-directories.sh` + +```bash +#!/bin/bash +set -euo pipefail + +# Load foundation +source "${REPO_DIR}/scripts/common/filesystem.sh" +source "${REPO_DIR}/scripts/common/common.sh" + +configure_directories() { + log_section "Directory Configuration" + + # Configure XDG directories + configure_xdg_directories + + # Configure hidden files + configure_hidden_files + + # Configure symlinks + configure_symlinks + + # Configure directory icons + configure_directory_icons + + log_success "Directories configured" +} + +configure_xdg_directories() { + log_subsection "XDG Directories" + + # Create user-dirs.conf + local user_dirs_conf="${HOME}/.config/user-dirs.conf" + ensure_directory "$(dirname "${user_dirs_conf}")" + + cat > "${user_dirs_conf}" < "${user_dirs_dirs}" < "${user_dirs_locale}" <