From 3788a7552d14291073eb120444bbec100e746dad Mon Sep 17 00:00:00 2001 From: Garret Patten Date: Wed, 3 Jun 2026 20:17:04 -0400 Subject: [PATCH 1/8] Add language installations --- README.md | 3 +++ scripts/validate-installs.sh | 18 +++++++++++++++++- src/scripts/install/dev/all.sh | 3 +++ src/scripts/install/dev/lsp-deps-apt.sh | 20 ++++++++++++++++++++ src/scripts/install/dev/ruby-gems.sh | 5 +++++ src/scripts/install/dev/rustup.sh | 3 +++ 6 files changed, 51 insertions(+), 1 deletion(-) create mode 100755 src/scripts/install/dev/lsp-deps-apt.sh create mode 100755 src/scripts/install/dev/ruby-gems.sh create mode 100755 src/scripts/install/dev/rustup.sh diff --git a/README.md b/README.md index 48e11aa..2e506a5 100644 --- a/README.md +++ b/README.md @@ -60,6 +60,9 @@ Install scripts prefer, in order: | Node.js | apt (NodeSource) | | nvm | upstream install script | | Python 3, pip, venv, dev headers | apt | +| Mason LSP runtimes (Go, Ruby, PHP, Java, Lua, Julia, C toolchain) | apt | +| Rust / cargo | rustup | +| Solargraph (Ruby gem for `solargraph` LSP) | gem (`--user-install`) | | Vue CLI | npm global | | Docker CE + Compose | apt (Docker vendor repo) | | Neovim | apt (PPA) + Python extras | diff --git a/scripts/validate-installs.sh b/scripts/validate-installs.sh index 0b1e6ee..5b218a2 100755 --- a/scripts/validate-installs.sh +++ b/scripts/validate-installs.sh @@ -4,7 +4,7 @@ set -uo pipefail cd "$(dirname "$0")/.." || exit 1 -export PATH="${HOME}/.local/bin:/usr/local/bin:${PATH}" +export PATH="${HOME}/.cargo/bin:${HOME}/.local/bin:/usr/local/bin:${PATH}" FAILURES=0 @@ -151,6 +151,22 @@ section 'Dev' check_version node node --version check_version npm npm --version check_version python3 python3 --version +check_version go go version +check_version ruby ruby --version +check_version rustc rustc --version +check_version cargo cargo --version +check_version php php --version +check_version composer composer --version +check_version java java --version +check_version julia julia --version +check_version lua lua5.4 -v +check_version luarocks luarocks --version +check_version gcc gcc --version +if command -v gem >/dev/null 2>&1 && gem list solargraph -i >/dev/null 2>&1; then + pass solargraph-gem 'gem: solargraph' +else + fail solargraph-gem 'gem install --user-install solargraph' +fi check_version docker docker --version check_version docker-compose docker compose version if docker info >/dev/null 2>&1; then diff --git a/src/scripts/install/dev/all.sh b/src/scripts/install/dev/all.sh index 9999c53..8478c52 100644 --- a/src/scripts/install/dev/all.sh +++ b/src/scripts/install/dev/all.sh @@ -7,6 +7,9 @@ source "$DIR/../../lib/run.sh" run_script "$DIR/nodesource-nodejs.sh" run_script "$DIR/nvm.sh" run_script "$DIR/python.sh" +run_script "$DIR/lsp-deps-apt.sh" +run_script "$DIR/rustup.sh" +run_script "$DIR/ruby-gems.sh" run_script "$DIR/vue-cli.sh" run_script "$DIR/docker.sh" run_script "$DIR/neovim.sh" diff --git a/src/scripts/install/dev/lsp-deps-apt.sh b/src/scripts/install/dev/lsp-deps-apt.sh new file mode 100755 index 0000000..f019f34 --- /dev/null +++ b/src/scripts/install/dev/lsp-deps-apt.sh @@ -0,0 +1,20 @@ +#!/bin/bash +sudo DEBIAN_FRONTEND=noninteractive apt-get install -y \ + build-essential \ + unzip \ + gzip \ + tar \ + curl \ + golang-go \ + ruby-full \ + ruby-dev \ + default-jdk-headless \ + php-cli \ + php-mbstring \ + php-xml \ + php-zip \ + composer \ + lua5.4 \ + liblua5.4-dev \ + luarocks \ + julia diff --git a/src/scripts/install/dev/ruby-gems.sh b/src/scripts/install/dev/ruby-gems.sh new file mode 100755 index 0000000..fc9ccb5 --- /dev/null +++ b/src/scripts/install/dev/ruby-gems.sh @@ -0,0 +1,5 @@ +#!/bin/bash +if ! command -v gem >/dev/null 2>&1; then + exit 0 +fi +gem install --user-install solargraph || true diff --git a/src/scripts/install/dev/rustup.sh b/src/scripts/install/dev/rustup.sh new file mode 100755 index 0000000..86cc772 --- /dev/null +++ b/src/scripts/install/dev/rustup.sh @@ -0,0 +1,3 @@ +#!/bin/bash +[[ -f "$HOME/.cargo/env" ]] && exit 0 +curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y || true From e81f32cc9938cc3d5ce2521616464ae4564688a4 Mon Sep 17 00:00:00 2001 From: Garret Patten Date: Wed, 3 Jun 2026 20:19:16 -0400 Subject: [PATCH 2/8] Add UFW configuration --- README.md | 6 +++-- src/scripts/config/security/ufw-rules.sh | 23 +++++++++++++++++-- src/scripts/install/post-install/all.sh | 1 - .../install/post-install/ufw-enable.sh | 5 ---- src/scripts/install/security/all.sh | 1 + src/scripts/install/security/ufw-docker.sh | 5 ++++ 6 files changed, 31 insertions(+), 10 deletions(-) delete mode 100644 src/scripts/install/post-install/ufw-enable.sh create mode 100644 src/scripts/install/security/ufw-docker.sh diff --git a/README.md b/README.md index 2e506a5..0daf334 100644 --- a/README.md +++ b/README.md @@ -76,6 +76,7 @@ Install scripts prefer, in order: | Tool | Method | |------|--------| | UFW, OpenVPN | apt | +| ufw-docker | [chaifeng/ufw-docker](https://github.com/chaifeng/ufw-docker) → `/usr/local/bin` | | Proton VPN | apt (vendor `.deb` + packages) | | Proton Pass (desktop) | vendor `.deb` | | pass-cli | GitHub release binary | @@ -99,7 +100,7 @@ Install scripts prefer, in order: - apt update/upgrade, essentials (git, curl, universe enabled) - timezone (Los Angeles) -- Docker service enabled; UFW enabled after rules config +- Docker service enabled; UFW rules applied in config (LocalSend, Docker DNS, ufw-docker) ## Explicitly not installed @@ -119,7 +120,8 @@ These are **not** provisioned by this repo (remove from old notes or other dotfi Symlinks and settings from `src/dotfiles` (submodule): Zsh, tmux, Neovim, btop, fastfetch, Kitty/Alacritty/Ghostty, Git, VS Code `settings.json`, GNOME -gsettings (skipped in CI without a GNOME session), UFW rules, home directory +gsettings (skipped in CI without a GNOME session), UFW defaults and rules (LocalSend, +Docker DNS, ufw-docker), home directory layout. See [AGENTS.md](AGENTS.md) for contributor conventions, ShellCheck, and CI details. diff --git a/src/scripts/config/security/ufw-rules.sh b/src/scripts/config/security/ufw-rules.sh index 160ec6d..aab7150 100755 --- a/src/scripts/config/security/ufw-rules.sh +++ b/src/scripts/config/security/ufw-rules.sh @@ -1,8 +1,27 @@ #!/bin/bash command -v ufw >/dev/null 2>&1 || exit 0 -sudo ufw --force reset || true + +# Allow nothing in, everything out sudo ufw default deny incoming || true sudo ufw default allow outgoing || true -sudo ufw allow ssh || true + +# Allow ports for LocalSend +sudo ufw allow 53317/udp || true +sudo ufw allow 53317/tcp || true + +# Allow Docker containers to use DNS on host +sudo ufw allow in proto udp from 172.16.0.0/12 to 172.17.0.1 port 53 comment 'allow-docker-dns' || true +sudo ufw allow in proto udp from 192.168.0.0/16 to 172.17.0.1 port 53 comment 'allow-docker-dns' || true + +# Turn on the firewall sudo ufw --force enable || true + +# Enable UFW systemd service to start on boot +sudo systemctl enable ufw || true + +# Turn on Docker protections +if command -v ufw-docker >/dev/null 2>&1; then + sudo ufw-docker install || true + sudo ufw reload || true +fi diff --git a/src/scripts/install/post-install/all.sh b/src/scripts/install/post-install/all.sh index 89922b3..7d04b8e 100644 --- a/src/scripts/install/post-install/all.sh +++ b/src/scripts/install/post-install/all.sh @@ -6,5 +6,4 @@ source "$DIR/../../lib/run.sh" run_script "$DIR/apt-maintain.sh" run_script "$DIR/docker-service.sh" -run_script "$DIR/ufw-enable.sh" run_script "$DIR/completion-banner.sh" diff --git a/src/scripts/install/post-install/ufw-enable.sh b/src/scripts/install/post-install/ufw-enable.sh deleted file mode 100644 index 2e16e1b..0000000 --- a/src/scripts/install/post-install/ufw-enable.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/bash - -if command -v ufw >/dev/null 2>&1; then - sudo ufw --force enable || true -fi diff --git a/src/scripts/install/security/all.sh b/src/scripts/install/security/all.sh index 0a89f50..73feea4 100644 --- a/src/scripts/install/security/all.sh +++ b/src/scripts/install/security/all.sh @@ -5,6 +5,7 @@ DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" source "$DIR/../../lib/run.sh" run_script "$DIR/defense-apt.sh" +run_script "$DIR/ufw-docker.sh" run_script "$DIR/protonvpn.sh" run_script "$DIR/proton-pass.sh" run_script "$DIR/signal-desktop.sh" diff --git a/src/scripts/install/security/ufw-docker.sh b/src/scripts/install/security/ufw-docker.sh new file mode 100644 index 0000000..b28857a --- /dev/null +++ b/src/scripts/install/security/ufw-docker.sh @@ -0,0 +1,5 @@ +#!/bin/bash +[[ -x /usr/local/bin/ufw-docker ]] && exit 0 +sudo wget -q -O /usr/local/bin/ufw-docker \ + https://github.com/chaifeng/ufw-docker/raw/master/ufw-docker || true +sudo chmod +x /usr/local/bin/ufw-docker || true From 31093577707bd8a19eac4fe459a44560fef9f9df Mon Sep 17 00:00:00 2001 From: Garret Patten Date: Thu, 4 Jun 2026 10:13:56 -0400 Subject: [PATCH 3/8] fix: test runner issues --- scripts/validate-installs.sh | 2 +- src/scripts/install/dev/lsp-deps-apt.sh | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/scripts/validate-installs.sh b/scripts/validate-installs.sh index 5b218a2..627712a 100755 --- a/scripts/validate-installs.sh +++ b/scripts/validate-installs.sh @@ -159,7 +159,7 @@ check_version php php --version check_version composer composer --version check_version java java --version check_version julia julia --version -check_version lua lua5.4 -v +check_version lua lua5.4 -e 'print(_VERSION)' check_version luarocks luarocks --version check_version gcc gcc --version if command -v gem >/dev/null 2>&1 && gem list solargraph -i >/dev/null 2>&1; then diff --git a/src/scripts/install/dev/lsp-deps-apt.sh b/src/scripts/install/dev/lsp-deps-apt.sh index f019f34..69acce5 100755 --- a/src/scripts/install/dev/lsp-deps-apt.sh +++ b/src/scripts/install/dev/lsp-deps-apt.sh @@ -16,5 +16,7 @@ sudo DEBIAN_FRONTEND=noninteractive apt-get install -y \ composer \ lua5.4 \ liblua5.4-dev \ - luarocks \ - julia + luarocks + +# Julia is not in all Ubuntu releases (e.g. ubuntu-latest); do not fail the batch above. +sudo DEBIAN_FRONTEND=noninteractive apt-get install -y julia || true From 665e5f618f51f5dedc212cc7548c19b14c1d00c6 Mon Sep 17 00:00:00 2001 From: Garret Patten Date: Thu, 4 Jun 2026 14:24:51 -0400 Subject: [PATCH 4/8] Restructure package installations --- README.md | 17 ++++++++++------- src/scripts/install/cli/btop.packages | 3 +++ src/scripts/install/cli/btop.sh | 7 ++++++- src/scripts/install/cli/cli-tools.sh | 11 ++++++++++- src/scripts/install/cli/cli.packages | 16 ++++++++++++++++ src/scripts/install/cli/fastfetch.packages | 3 +++ src/scripts/install/cli/fastfetch.sh | 9 ++++++++- src/scripts/install/cli/flatpak.sh | 2 -- src/scripts/install/cli/yazi.packages | 4 ++++ src/scripts/install/cli/yazi.sh | 7 ++++++- 10 files changed, 66 insertions(+), 13 deletions(-) create mode 100644 src/scripts/install/cli/btop.packages create mode 100644 src/scripts/install/cli/cli.packages create mode 100644 src/scripts/install/cli/fastfetch.packages create mode 100644 src/scripts/install/cli/yazi.packages diff --git a/README.md b/README.md index 0daf334..3228065 100644 --- a/README.md +++ b/README.md @@ -28,13 +28,16 @@ Install scripts prefer, in order: ### CLI (`install/cli/`) -| Tool | Method | -|------|--------| -| bat, curl, eza, fd-find, git, htop, jq, ripgrep, vim, wget | apt (universe) | -| yazi, lazygit | apt ([debian.griffo.io](https://debian.griffo.io/apt)) | -| btop | apt (Ubuntu ≥ 22.04), else GitHub musl binary, else snap | -| fastfetch | apt (PPA) | -| flatpak + Flathub | apt + flatpak remotes | +Apt tools are listed one per line in `*.packages` files (Omarchy-style) and +installed by the matching script (`grep` skips `#` comments and blank lines). + +| File | Tool(s) | Method | +|------|---------|--------| +| `cli.packages` | bat, curl, eza, fd-find, flatpak, git, htop, jq, ripgrep, vim, wget, … | apt (universe) | +| `yazi.packages` | yazi, lazygit | apt ([debian.griffo.io](https://debian.griffo.io/apt)) | +| `btop.packages` | btop | apt (Ubuntu ≥ 22.04), else GitHub musl binary, else snap | +| `fastfetch.packages` | fastfetch | apt (PPA) | +| — | Flathub remotes | `flatpak.sh` (after `flatpak` from `cli.packages`) | ### Media (`install/media/`) diff --git a/src/scripts/install/cli/btop.packages b/src/scripts/install/cli/btop.packages new file mode 100644 index 0000000..784cba6 --- /dev/null +++ b/src/scripts/install/cli/btop.packages @@ -0,0 +1,3 @@ +# Apt when available (Ubuntu >= 22.04); fallbacks in btop.sh + +btop diff --git a/src/scripts/install/cli/btop.sh b/src/scripts/install/cli/btop.sh index 8d4df85..88e902c 100644 --- a/src/scripts/install/cli/btop.sh +++ b/src/scripts/install/cli/btop.sh @@ -1,12 +1,17 @@ #!/bin/bash +DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + if command -v btop >/dev/null 2>&1; then exit 0 fi ubuntu_release="$(lsb_release -rs 2>/dev/null || echo "")" if [[ -n "$ubuntu_release" ]] && dpkg --compare-versions "$ubuntu_release" ge 22.04 2>/dev/null; then - sudo DEBIAN_FRONTEND=noninteractive apt-get install -y btop || true + mapfile -t packages < <(grep -v '^#' "$DIR/btop.packages" | grep -v '^[[:space:]]*$') + if [[ ${#packages[@]} -gt 0 ]]; then + sudo DEBIAN_FRONTEND=noninteractive apt-get install -y "${packages[@]}" || true + fi fi if command -v btop >/dev/null 2>&1; then exit 0 diff --git a/src/scripts/install/cli/cli-tools.sh b/src/scripts/install/cli/cli-tools.sh index 6104691..127eece 100644 --- a/src/scripts/install/cli/cli-tools.sh +++ b/src/scripts/install/cli/cli-tools.sh @@ -1,2 +1,11 @@ #!/bin/bash -sudo DEBIAN_FRONTEND=noninteractive apt-get install -y bat curl eza fd-find git htop jq ripgrep vim wget + +DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +packages_file="$DIR/cli.packages" + +mapfile -t packages < <(grep -v '^#' "$packages_file" | grep -v '^[[:space:]]*$') +if [[ ${#packages[@]} -eq 0 ]]; then + exit 0 +fi + +sudo DEBIAN_FRONTEND=noninteractive apt-get install -y "${packages[@]}" diff --git a/src/scripts/install/cli/cli.packages b/src/scripts/install/cli/cli.packages new file mode 100644 index 0000000..842cad0 --- /dev/null +++ b/src/scripts/install/cli/cli.packages @@ -0,0 +1,16 @@ +# Apt packages for CLI tools (universe / main). One package per line. +# Installed by cli-tools.sh. Add tools here; use a separate *.packages file when +# a tool needs a PPA or third-party repo (see yazi.packages, fastfetch.packages). + +bat +curl +dbus-x11 +eza +fd-find +flatpak +git +htop +jq +ripgrep +vim +wget diff --git a/src/scripts/install/cli/fastfetch.packages b/src/scripts/install/cli/fastfetch.packages new file mode 100644 index 0000000..6c3d4a0 --- /dev/null +++ b/src/scripts/install/cli/fastfetch.packages @@ -0,0 +1,3 @@ +# PPA: zhangsongcui3371/fastfetch (configured in fastfetch.sh) + +fastfetch diff --git a/src/scripts/install/cli/fastfetch.sh b/src/scripts/install/cli/fastfetch.sh index a7ccef5..11c0537 100644 --- a/src/scripts/install/cli/fastfetch.sh +++ b/src/scripts/install/cli/fastfetch.sh @@ -1,4 +1,11 @@ #!/bin/bash + +DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + sudo add-apt-repository -y ppa:zhangsongcui3371/fastfetch || true sudo apt-get update -y || true -sudo DEBIAN_FRONTEND=noninteractive apt-get install -y fastfetch + +mapfile -t packages < <(grep -v '^#' "$DIR/fastfetch.packages" | grep -v '^[[:space:]]*$') +if [[ ${#packages[@]} -gt 0 ]]; then + sudo DEBIAN_FRONTEND=noninteractive apt-get install -y "${packages[@]}" +fi diff --git a/src/scripts/install/cli/flatpak.sh b/src/scripts/install/cli/flatpak.sh index 8e5a7c9..dff48b4 100644 --- a/src/scripts/install/cli/flatpak.sh +++ b/src/scripts/install/cli/flatpak.sh @@ -1,6 +1,4 @@ #!/bin/bash -sudo DEBIAN_FRONTEND=noninteractive apt-get install -y flatpak dbus-x11 - sudo flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo 2>/dev/null || true flatpak remote-add --user --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo >/dev/null 2>&1 || true diff --git a/src/scripts/install/cli/yazi.packages b/src/scripts/install/cli/yazi.packages new file mode 100644 index 0000000..711d1ce --- /dev/null +++ b/src/scripts/install/cli/yazi.packages @@ -0,0 +1,4 @@ +# debian.griffo.io apt repo (configured in yazi.sh) + +yazi +lazygit diff --git a/src/scripts/install/cli/yazi.sh b/src/scripts/install/cli/yazi.sh index e8a8f72..0207c40 100644 --- a/src/scripts/install/cli/yazi.sh +++ b/src/scripts/install/cli/yazi.sh @@ -1,5 +1,7 @@ #!/bin/bash +DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + yazi_key="/etc/apt/trusted.gpg.d/debian.griffo.io.gpg" if [[ ! -f "$yazi_key" ]]; then curl -fsSL https://debian.griffo.io/EA0F721D231FDD3A0A17B9AC7808B4DD62C41256.asc | \ @@ -16,4 +18,7 @@ if [[ -n "$ubuntu_codename" ]]; then fi fi -sudo DEBIAN_FRONTEND=noninteractive apt-get install -y yazi lazygit +mapfile -t packages < <(grep -v '^#' "$DIR/yazi.packages" | grep -v '^[[:space:]]*$') +if [[ ${#packages[@]} -gt 0 ]]; then + sudo DEBIAN_FRONTEND=noninteractive apt-get install -y "${packages[@]}" +fi From fa9fadad8b6727bb077553dc66ff9c6738e21187 Mon Sep 17 00:00:00 2001 From: Garret Patten Date: Thu, 4 Jun 2026 14:49:53 -0400 Subject: [PATCH 5/8] add more CLI tool installations --- README.md | 15 ++++++--- scripts/validate-installs.sh | 31 ++++++++++++++++++- src/scripts/install/all.sh | 1 + src/scripts/install/cli/cli.packages | 10 ++++++ src/scripts/install/cli/yazi.packages | 3 +- src/scripts/install/desktop/all.sh | 7 +++++ src/scripts/install/desktop/gnome-apt.sh | 11 +++++++ src/scripts/install/desktop/gnome.packages | 4 +++ src/scripts/install/dev/dev-tools-apt.sh | 11 ++++++- src/scripts/install/dev/dev-tools.packages | 4 +++ src/scripts/install/dev/lsp-deps-apt.sh | 1 - src/scripts/install/security/all.sh | 3 +- src/scripts/install/security/defense-apt.sh | 3 -- src/scripts/install/security/security-apt.sh | 13 ++++++++ .../install/security/security-tools-apt.sh | 2 -- .../install/security/security.packages | 7 +++++ 16 files changed, 110 insertions(+), 16 deletions(-) create mode 100644 src/scripts/install/desktop/all.sh create mode 100644 src/scripts/install/desktop/gnome-apt.sh create mode 100644 src/scripts/install/desktop/gnome.packages create mode 100644 src/scripts/install/dev/dev-tools.packages delete mode 100644 src/scripts/install/security/defense-apt.sh create mode 100644 src/scripts/install/security/security-apt.sh delete mode 100644 src/scripts/install/security/security-tools-apt.sh create mode 100644 src/scripts/install/security/security.packages diff --git a/README.md b/README.md index 3228065..888c324 100644 --- a/README.md +++ b/README.md @@ -33,8 +33,8 @@ installed by the matching script (`grep` skips `#` comments and blank lines). | File | Tool(s) | Method | |------|---------|--------| -| `cli.packages` | bat, curl, eza, fd-find, flatpak, git, htop, jq, ripgrep, vim, wget, … | apt (universe) | -| `yazi.packages` | yazi, lazygit | apt ([debian.griffo.io](https://debian.griffo.io/apt)) | +| `cli.packages` | bat, curl, eza, fzf, jq, ripgrep, tree-sitter-cli, tealdeer (`tldr`), zoxide, whois, unzip, libsecret, gcc, pkg-config, … | apt (universe) | +| `yazi.packages` | yazi, lazygit, lazydocker | apt ([debian.griffo.io](https://debian.griffo.io/apt)) | | `btop.packages` | btop | apt (Ubuntu ≥ 22.04), else GitHub musl binary, else snap | | `fastfetch.packages` | fastfetch | apt (PPA) | | — | Flathub remotes | `flatpak.sh` (after `flatpak` from `cli.packages`) | @@ -47,6 +47,12 @@ installed by the matching script (`grep` skips `#` comments and blank lines). | VLC | apt | | ffmpeg, ubuntu-restricted-extras | apt | +### Desktop (`install/desktop/`) + +| Tool | Method | +|------|--------| +| GNOME Tweaks, shell extensions | apt (`gnome.packages`) | + ### Productivity (`install/productivity/`) | App | Method | @@ -69,7 +75,7 @@ installed by the matching script (`grep` skips `#` comments and blank lines). | Vue CLI | npm global | | Docker CE + Compose | apt (Docker vendor repo) | | Neovim | apt (PPA) + Python extras | -| gh, shellcheck, git | apt | +| gh, shellcheck | apt (`dev-tools.packages`) | | **Bruno** (API client) | apt ([debian.usebruno.com](http://debian.usebruno.com/)), else Flatpak | | Semgrep | pip (`--user`) | | Cursor Agent CLI | [cursor.com/install](https://cursor.com/install) | @@ -78,13 +84,12 @@ installed by the matching script (`grep` skips `#` comments and blank lines). | Tool | Method | |------|--------| -| UFW, OpenVPN | apt | +| UFW, OpenVPN, nmap, exiftool | apt (`security.packages`) | | ufw-docker | [chaifeng/ufw-docker](https://github.com/chaifeng/ufw-docker) → `/usr/local/bin` | | Proton VPN | apt (vendor `.deb` + packages) | | Proton Pass (desktop) | vendor `.deb` | | pass-cli | GitHub release binary | | Signal Desktop | apt (vendor repo) | -| nmap, exiftool | apt | | OWASP ZAP | Flatpak, else snap (`--classic`) | | PayloadsAllTheThings, SecLists | git clone into `~/Hacking` | diff --git a/scripts/validate-installs.sh b/scripts/validate-installs.sh index 627712a..28903f8 100755 --- a/scripts/validate-installs.sh +++ b/scripts/validate-installs.sh @@ -107,8 +107,18 @@ check_version fd fdfind --version check_version git git --version check_version htop htop --version check_version jq jq --version +check_version fzf fzf --version +check_version zoxide zoxide --version +check_version whois whois --version +check_version tldr tldr --version +check_version tree-sitter tree-sitter --version +check_version pkg-config pkg-config --version +check_dpkg libsecret-1-0 libsecret-1-0 +check_dpkg libsecret-1-dev libsecret-1-dev check_version lazygit lazygit --version +check_version lazydocker lazydocker --version check_version ripgrep rg --version +check_dpkg unzip unzip check_version vim vim --version check_version yazi yazi --version check_version btop btop --version @@ -214,9 +224,16 @@ check_path nvm "$HOME/.nvm/nvm.sh" # --- Security (install/security) --- section 'Security' check_version nmap nmap --version -check_version exiftool exiftool -ver +if command -v exiftool >/dev/null 2>&1; then + check_version exiftool exiftool -ver +elif dpkg -s libimage-exiftool-perl >/dev/null 2>&1; then + pass exiftool "$(dpkg -s libimage-exiftool-perl 2>/dev/null | awk -F': ' '/^Version:/{print $2; exit}')" +else + fail exiftool 'libimage-exiftool-perl (exiftool)' +fi check_version openvpn openvpn --version check_dpkg ufw ufw +check_path ufw-docker /usr/local/bin/ufw-docker check_dpkg signal-desktop signal-desktop if command -v proton-pass >/dev/null 2>&1; then @@ -244,6 +261,18 @@ fi check_path hacking-payloads "$HOME/Hacking/PayloadsAllTheThings" check_path hacking-seclists "$HOME/Hacking/SecLists" +# --- Desktop (install/desktop) --- +section 'Desktop' +check_dpkg gnome-tweaks gnome-tweaks +check_dpkg gnome-shell-extensions gnome-shell-extensions +if command -v gnome-extensions >/dev/null 2>&1; then + pass gnome-extensions "$(command -v gnome-extensions)" +elif dpkg -s gnome-shell-extensions >/dev/null 2>&1; then + pass gnome-extensions 'packages installed (CLI needs gnome-shell on desktop)' +else + fail gnome-extensions 'gnome.packages (gnome-shell-extensions)' +fi + # --- Shell (install/shell) --- section 'Shell' check_version zsh zsh --version diff --git a/src/scripts/install/all.sh b/src/scripts/install/all.sh index 5c9b5e7..ee2945b 100644 --- a/src/scripts/install/all.sh +++ b/src/scripts/install/all.sh @@ -10,6 +10,7 @@ run_script "$DIR/preflight/all.sh" run_script "$DIR/cli/all.sh" run_script "$DIR/media/all.sh" run_script "$DIR/productivity/all.sh" +run_script "$DIR/desktop/all.sh" run_script "$DIR/dev/all.sh" run_script "$DIR/security/all.sh" run_script "$DIR/shell/all.sh" diff --git a/src/scripts/install/cli/cli.packages b/src/scripts/install/cli/cli.packages index 842cad0..145bfb8 100644 --- a/src/scripts/install/cli/cli.packages +++ b/src/scripts/install/cli/cli.packages @@ -8,9 +8,19 @@ dbus-x11 eza fd-find flatpak +fzf +gcc git htop jq +libsecret-1-0 +libsecret-1-dev +pkg-config ripgrep +tealdeer +tree-sitter-cli +unzip vim +whois wget +zoxide diff --git a/src/scripts/install/cli/yazi.packages b/src/scripts/install/cli/yazi.packages index 711d1ce..d29c41a 100644 --- a/src/scripts/install/cli/yazi.packages +++ b/src/scripts/install/cli/yazi.packages @@ -1,4 +1,5 @@ # debian.griffo.io apt repo (configured in yazi.sh) -yazi +lazydocker lazygit +yazi diff --git a/src/scripts/install/desktop/all.sh b/src/scripts/install/desktop/all.sh new file mode 100644 index 0000000..9063b15 --- /dev/null +++ b/src/scripts/install/desktop/all.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +# shellcheck source=../../lib/run.sh +source "$DIR/../../lib/run.sh" + +run_script "$DIR/gnome-apt.sh" diff --git a/src/scripts/install/desktop/gnome-apt.sh b/src/scripts/install/desktop/gnome-apt.sh new file mode 100644 index 0000000..626481c --- /dev/null +++ b/src/scripts/install/desktop/gnome-apt.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +packages_file="$DIR/gnome.packages" + +mapfile -t packages < <(grep -v '^#' "$packages_file" | grep -v '^[[:space:]]*$') +if [[ ${#packages[@]} -eq 0 ]]; then + exit 0 +fi + +sudo DEBIAN_FRONTEND=noninteractive apt-get install -y "${packages[@]}" diff --git a/src/scripts/install/desktop/gnome.packages b/src/scripts/install/desktop/gnome.packages new file mode 100644 index 0000000..62ca14e --- /dev/null +++ b/src/scripts/install/desktop/gnome.packages @@ -0,0 +1,4 @@ +# GNOME desktop tools (gnome-extensions CLI ships with gnome-shell on desktop installs) + +gnome-shell-extensions +gnome-tweaks diff --git a/src/scripts/install/dev/dev-tools-apt.sh b/src/scripts/install/dev/dev-tools-apt.sh index 532bd44..ea6e2f6 100644 --- a/src/scripts/install/dev/dev-tools-apt.sh +++ b/src/scripts/install/dev/dev-tools-apt.sh @@ -1,2 +1,11 @@ #!/bin/bash -sudo DEBIAN_FRONTEND=noninteractive apt-get install -y gh shellcheck git + +DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +packages_file="$DIR/dev-tools.packages" + +mapfile -t packages < <(grep -v '^#' "$packages_file" | grep -v '^[[:space:]]*$') +if [[ ${#packages[@]} -eq 0 ]]; then + exit 0 +fi + +sudo DEBIAN_FRONTEND=noninteractive apt-get install -y "${packages[@]}" diff --git a/src/scripts/install/dev/dev-tools.packages b/src/scripts/install/dev/dev-tools.packages new file mode 100644 index 0000000..d412e23 --- /dev/null +++ b/src/scripts/install/dev/dev-tools.packages @@ -0,0 +1,4 @@ +# Dev CLI tools (apt). One package per line. + +gh +shellcheck diff --git a/src/scripts/install/dev/lsp-deps-apt.sh b/src/scripts/install/dev/lsp-deps-apt.sh index 69acce5..9738cce 100755 --- a/src/scripts/install/dev/lsp-deps-apt.sh +++ b/src/scripts/install/dev/lsp-deps-apt.sh @@ -1,7 +1,6 @@ #!/bin/bash sudo DEBIAN_FRONTEND=noninteractive apt-get install -y \ build-essential \ - unzip \ gzip \ tar \ curl \ diff --git a/src/scripts/install/security/all.sh b/src/scripts/install/security/all.sh index 73feea4..a200964 100644 --- a/src/scripts/install/security/all.sh +++ b/src/scripts/install/security/all.sh @@ -4,11 +4,10 @@ DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" # shellcheck source=../../lib/run.sh source "$DIR/../../lib/run.sh" -run_script "$DIR/defense-apt.sh" +run_script "$DIR/security-apt.sh" run_script "$DIR/ufw-docker.sh" run_script "$DIR/protonvpn.sh" run_script "$DIR/proton-pass.sh" run_script "$DIR/signal-desktop.sh" -run_script "$DIR/security-tools-apt.sh" run_script "$DIR/zaproxy.sh" run_script "$DIR/hacking-repos.sh" diff --git a/src/scripts/install/security/defense-apt.sh b/src/scripts/install/security/defense-apt.sh deleted file mode 100644 index 8eb8629..0000000 --- a/src/scripts/install/security/defense-apt.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash -sudo apt-get update -y || true -sudo DEBIAN_FRONTEND=noninteractive apt-get install -y ufw openvpn diff --git a/src/scripts/install/security/security-apt.sh b/src/scripts/install/security/security-apt.sh new file mode 100644 index 0000000..96fee14 --- /dev/null +++ b/src/scripts/install/security/security-apt.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +packages_file="$DIR/security.packages" + +sudo apt-get update -y || true + +mapfile -t packages < <(grep -v '^#' "$packages_file" | grep -v '^[[:space:]]*$') +if [[ ${#packages[@]} -eq 0 ]]; then + exit 0 +fi + +sudo DEBIAN_FRONTEND=noninteractive apt-get install -y "${packages[@]}" diff --git a/src/scripts/install/security/security-tools-apt.sh b/src/scripts/install/security/security-tools-apt.sh deleted file mode 100644 index 8870f53..0000000 --- a/src/scripts/install/security/security-tools-apt.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/bash -sudo DEBIAN_FRONTEND=noninteractive apt-get install -y nmap exiftool diff --git a/src/scripts/install/security/security.packages b/src/scripts/install/security/security.packages new file mode 100644 index 0000000..7ffa9eb --- /dev/null +++ b/src/scripts/install/security/security.packages @@ -0,0 +1,7 @@ +# Security and network tooling. One package per line. +# libimage-exiftool-perl provides the exiftool command on Ubuntu. + +libimage-exiftool-perl +nmap +openvpn +ufw From 1c9e23c1102411f000b1c059b4bf5e1ac5d4b2a4 Mon Sep 17 00:00:00 2001 From: Garret Patten Date: Thu, 4 Jun 2026 15:02:01 -0400 Subject: [PATCH 6/8] Clean up and simplify scripts further --- .github/ISSUE_TEMPLATE/bug_report.yml | 4 +- .github/workflows/test-runner.yaml | 55 +------- .gitignore | 1 - AGENTS.md | 8 +- README.md | 124 ++++++----------- scripts/lib/validate-common.sh | 93 +++++++++++++ scripts/validate-config.sh | 56 ++++++++ scripts/validate-installs.sh | 127 ++---------------- scripts/validate.sh | 14 ++ setup_errors.log | 81 +++++++++++ src/scripts/install/all.sh | 8 +- src/scripts/install/{security => apps}/all.sh | 9 +- .../install/{media => apps}/brave-browser.sh | 0 src/scripts/install/{dev => apps}/bruno.sh | 0 .../install/{productivity => apps}/etcher.sh | 0 .../{security => apps}/hacking-repos.sh | 0 .../install/{security => apps}/proton-pass.sh | 0 .../install/{security => apps}/protonvpn.sh | 0 .../{security => apps}/signal-desktop.sh | 0 .../install/{security => apps}/ufw-docker.sh | 0 .../install/{security => apps}/zaproxy.sh | 0 .../install/{productivity => apps}/zoom.sh | 0 src/scripts/install/{cli => }/btop.sh | 7 +- src/scripts/install/cli/all.sh | 11 -- src/scripts/install/cli/btop.packages | 3 - src/scripts/install/cli/cli-tools.sh | 11 -- src/scripts/install/cli/cli.packages | 26 ---- src/scripts/install/cli/fastfetch.packages | 3 - src/scripts/install/cli/fastfetch.sh | 11 -- src/scripts/install/cli/yazi.packages | 5 - src/scripts/install/cli/yazi.sh | 24 ---- src/scripts/install/desktop/all.sh | 7 - src/scripts/install/desktop/gnome-apt.sh | 11 -- src/scripts/install/desktop/gnome.packages | 4 - src/scripts/install/dev/all.sh | 13 +- src/scripts/install/dev/dev-tools-apt.sh | 11 -- src/scripts/install/dev/dev-tools.packages | 4 - src/scripts/install/dev/docker.sh | 5 +- src/scripts/install/dev/lsp-deps-apt.sh | 21 --- src/scripts/install/dev/neovim.sh | 2 +- src/scripts/install/dev/nodesource-nodejs.sh | 1 - src/scripts/install/dev/python.sh | 2 - src/scripts/install/fastfetch.sh | 9 ++ src/scripts/install/{cli => }/flatpak.sh | 0 src/scripts/install/griffo.sh | 23 ++++ src/scripts/install/media/all.sh | 9 -- src/scripts/install/media/multimedia.sh | 4 - src/scripts/install/media/vlc.sh | 2 - src/scripts/install/packages/all.sh | 19 +++ src/scripts/install/packages/base.packages | 29 ++++ src/scripts/install/packages/desktop.packages | 2 + src/scripts/install/packages/dev.packages | 6 + .../install/packages/fastfetch.packages | 1 + src/scripts/install/packages/griffo.packages | 3 + .../install/packages/lsp-optional.packages | 1 + src/scripts/install/packages/lsp.packages | 15 +++ src/scripts/install/packages/media.packages | 5 + .../install/packages/productivity.packages | 6 + src/scripts/install/packages/shell.packages | 8 ++ .../install/post-install/completion-banner.sh | 2 +- src/scripts/install/productivity/all.sh | 10 -- .../install/productivity/libreoffice.sh | 2 - .../install/productivity/productivity-apt.sh | 2 - src/scripts/install/security/security-apt.sh | 13 -- .../install/security/security.packages | 7 - src/scripts/install/shell/all.sh | 3 - src/scripts/install/shell/fonts-apt.sh | 3 - src/scripts/install/shell/oh-my-posh.sh | 2 - src/scripts/install/shell/shell-apt.sh | 4 - src/scripts/install/shell/zsh-plugins.sh | 3 - src/scripts/lib/apt-packages.sh | 19 +++ src/scripts/lib/env.sh | 1 - src/scripts/lib/run.sh | 4 +- src/scripts/master.sh | 8 +- 74 files changed, 479 insertions(+), 508 deletions(-) create mode 100644 scripts/lib/validate-common.sh create mode 100755 scripts/validate-config.sh create mode 100755 scripts/validate.sh create mode 100644 setup_errors.log rename src/scripts/install/{security => apps}/all.sh (73%) rename src/scripts/install/{media => apps}/brave-browser.sh (100%) rename src/scripts/install/{dev => apps}/bruno.sh (100%) rename src/scripts/install/{productivity => apps}/etcher.sh (100%) rename src/scripts/install/{security => apps}/hacking-repos.sh (100%) rename src/scripts/install/{security => apps}/proton-pass.sh (100%) rename src/scripts/install/{security => apps}/protonvpn.sh (100%) rename src/scripts/install/{security => apps}/signal-desktop.sh (100%) rename src/scripts/install/{security => apps}/ufw-docker.sh (100%) rename src/scripts/install/{security => apps}/zaproxy.sh (100%) rename src/scripts/install/{productivity => apps}/zoom.sh (100%) rename src/scripts/install/{cli => }/btop.sh (82%) delete mode 100644 src/scripts/install/cli/all.sh delete mode 100644 src/scripts/install/cli/btop.packages delete mode 100644 src/scripts/install/cli/cli-tools.sh delete mode 100644 src/scripts/install/cli/cli.packages delete mode 100644 src/scripts/install/cli/fastfetch.packages delete mode 100644 src/scripts/install/cli/fastfetch.sh delete mode 100644 src/scripts/install/cli/yazi.packages delete mode 100644 src/scripts/install/cli/yazi.sh delete mode 100644 src/scripts/install/desktop/all.sh delete mode 100644 src/scripts/install/desktop/gnome-apt.sh delete mode 100644 src/scripts/install/desktop/gnome.packages delete mode 100644 src/scripts/install/dev/dev-tools-apt.sh delete mode 100644 src/scripts/install/dev/dev-tools.packages delete mode 100755 src/scripts/install/dev/lsp-deps-apt.sh delete mode 100644 src/scripts/install/dev/python.sh create mode 100644 src/scripts/install/fastfetch.sh rename src/scripts/install/{cli => }/flatpak.sh (100%) create mode 100644 src/scripts/install/griffo.sh delete mode 100644 src/scripts/install/media/all.sh delete mode 100644 src/scripts/install/media/multimedia.sh delete mode 100644 src/scripts/install/media/vlc.sh create mode 100644 src/scripts/install/packages/all.sh create mode 100644 src/scripts/install/packages/base.packages create mode 100644 src/scripts/install/packages/desktop.packages create mode 100644 src/scripts/install/packages/dev.packages create mode 100644 src/scripts/install/packages/fastfetch.packages create mode 100644 src/scripts/install/packages/griffo.packages create mode 100644 src/scripts/install/packages/lsp-optional.packages create mode 100644 src/scripts/install/packages/lsp.packages create mode 100644 src/scripts/install/packages/media.packages create mode 100644 src/scripts/install/packages/productivity.packages create mode 100644 src/scripts/install/packages/shell.packages delete mode 100644 src/scripts/install/productivity/all.sh delete mode 100644 src/scripts/install/productivity/libreoffice.sh delete mode 100644 src/scripts/install/productivity/productivity-apt.sh delete mode 100644 src/scripts/install/security/security-apt.sh delete mode 100644 src/scripts/install/security/security.packages delete mode 100644 src/scripts/install/shell/fonts-apt.sh delete mode 100644 src/scripts/install/shell/shell-apt.sh delete mode 100644 src/scripts/install/shell/zsh-plugins.sh create mode 100644 src/scripts/lib/apt-packages.sh diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 98cc0c3..fc75868 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -6,7 +6,7 @@ body: - type: markdown attributes: value: >- - Give **Ubuntu version**, **repro**, and `setup_errors.log` excerpts. + Give **Ubuntu version**, **repro**, and `./scripts/validate.sh` output. Read **CONTRIBUTING.md** before submitting. - type: textarea @@ -44,7 +44,7 @@ body: id: logs attributes: label: Logs (optional but helpful) - description: Relevant excerpt from repo-root `setup_errors.log` or CI URL. + description: Relevant `./scripts/validate.sh` output or CI URL. render: plaintext validations: required: false diff --git a/.github/workflows/test-runner.yaml b/.github/workflows/test-runner.yaml index 2fd64e7..5732d24 100644 --- a/.github/workflows/test-runner.yaml +++ b/.github/workflows/test-runner.yaml @@ -19,58 +19,13 @@ jobs: submodules: recursive - name: Make scripts executable - run: | - find src/scripts -name '*.sh' -exec chmod +x {} + + run: find src/scripts -name '*.sh' -exec chmod +x {} + - # CI: no GNOME session; config/system/gnome-gsettings.sh exits early. + # CI: no GNOME session; gnome-gsettings.sh exits early. - name: Run setup scripts run: | cd src/scripts - bash master.sh || true - - - name: Validate installed tools and apps - run: | - export PATH="${HOME}/.local/bin:/usr/local/bin:${PATH}" - chmod +x scripts/validate-installs.sh - ./scripts/validate-installs.sh - - - name: Check error log - working-directory: ${{ github.workspace }} - run: | - ERROR_LOG="setup_errors.log" - if [[ -f "$ERROR_LOG" ]] && [[ -s "$ERROR_LOG" ]]; then - FILTERED_LOG=$(mktemp) - re='' - re+='Running kernel seems to be up-to-date|Restarting services|' - re+='Services to be restarted|Service restarts being deferred|' - re+='Flatpak system operation|ConfigureRemote not allowed|' - re+='No containers need to be restarted|No VM guests are running|' - re+='User sessions running outdated binaries|' - re+='No user sessions are running outdated binaries|' - re+='runner @ user manager service|needrestart|' - re+='No services need to be restarted|' - re+='chsh: PAM: Authentication failure|Password:|systemctl restart|' - re+='WARNING: apt does not have a stable CLI|' - re+='Synchronizing state of docker|' - re+='Executing: /usr/lib/systemd|^Cloning into|' - re+='^Updating files:|^Resolving |^Connecting to |' - re+='^HTTP request sent|' - re+='^Length:|^Saving to:|' - re+='^--[0-9]{4}-[0-9]{2}-[0-9]{2}|^[0-9]{4}-[0-9]{2}-[0-9]{2}.*saved|' - re+='^[[:space:]]*[0-9]+K|done\.$|^[[:space:]]*100%|^npm notice|' - re+='% Total|% Received|% Xferd|Average Speed|Dload Upload|' - re+='Time Time Time Current|--:--:--|' - re+='^[[:space:]]*[0-9]+(\.[0-9]+)?%[[:space:]]*$|' - re+='^#+[[:space:]]*[0-9]+(\.[0-9]+)?%[[:space:]]*$|' - re+='^curl:.*progress|' - grep -v -E "$re" "$ERROR_LOG" \ - | grep -v '^[[:space:]]*$' >"$FILTERED_LOG" || true + bash master.sh - if [[ -s "$FILTERED_LOG" ]]; then - echo "❌ Errors found:" - cat "$FILTERED_LOG" - rm -f "$FILTERED_LOG" - exit 1 - fi - rm -f "$FILTERED_LOG" - fi + - name: Validate installs and config + run: chmod +x scripts/validate.sh && ./scripts/validate.sh diff --git a/.gitignore b/.gitignore index 036b5c0..3a8c7cc 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,4 @@ # Log files -setup_errors.log setup_summary.txt # Node diff --git a/AGENTS.md b/AGENTS.md index 2ecff1b..61db731 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -46,18 +46,20 @@ pull requests. Run `npm ci` and the relevant tools when you touch those file typ ### Test workflow `.github/workflows/test-runner.yaml` runs `src/scripts/master.sh` on `ubuntu-latest`, then -`scripts/validate-installs.sh` (version and presence checks for each installed tool/app). +`scripts/validate.sh` (install binaries/packages and config paths/settings). GNOME gsettings scripts no-op without an active GNOME session. ## Layout | Path | Role | |------|------| -| `src/scripts/lib/env.sh` | `PROJECT_ROOT`, `ERROR_LOG_FILE`, `TEMP_DIR` | +| `src/scripts/lib/env.sh` | `PROJECT_ROOT`, `TEMP_DIR` | | `src/scripts/lib/run.sh` | `run_script` helper | | `src/scripts/lib/gnome-session.sh` | Skip GNOME config when not on GNOME | | `src/scripts/lib/zsh-login.sh` | `.zshrc` pass-cli guard for provisioning | -| `src/scripts/install//` | Per-package install scripts + `all.sh` | +| `src/scripts/install/packages/*.packages` | Apt package lists (one per line) | +| `src/scripts/lib/apt-packages.sh` | `install_apt_packages_from_file` helper | +| `src/scripts/install/` | `packages/`, `apps/`, `dev/`, `shell/`, `post-install/` | | `src/scripts/config//` | Dotfiles/GNOME/system config + `all.sh` | ## Commits diff --git a/README.md b/README.md index 888c324..27f3045 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Ubuntu setup scripts -Provisioning for a personal Ubuntu desktop: per-app install scripts under +Provisioning for a personal Ubuntu desktop: install scripts under `src/scripts/install/`, dotfiles and system config under `src/scripts/config/`, orchestrated by `master.sh`. @@ -12,8 +12,8 @@ bash run-install.sh # install only bash run-config.sh # config only ``` -CI runs `master.sh` on `ubuntu-latest`, then `scripts/validate-installs.sh` to -check that expected binaries and packages are present. +CI runs `master.sh` on `ubuntu-latest`, then `scripts/validate.sh` to confirm +expected binaries/packages and config outcomes (dotfiles paths, UFW, system policy). ## Package manager preference @@ -24,91 +24,48 @@ Install scripts prefer, in order: 3. **AppImage** or upstream static/binary releases 4. **snap** (only when no practical alternative) -## What gets installed - -### CLI (`install/cli/`) - -Apt tools are listed one per line in `*.packages` files (Omarchy-style) and -installed by the matching script (`grep` skips `#` comments and blank lines). - -| File | Tool(s) | Method | -|------|---------|--------| -| `cli.packages` | bat, curl, eza, fzf, jq, ripgrep, tree-sitter-cli, tealdeer (`tldr`), zoxide, whois, unzip, libsecret, gcc, pkg-config, … | apt (universe) | -| `yazi.packages` | yazi, lazygit, lazydocker | apt ([debian.griffo.io](https://debian.griffo.io/apt)) | -| `btop.packages` | btop | apt (Ubuntu ≥ 22.04), else GitHub musl binary, else snap | -| `fastfetch.packages` | fastfetch | apt (PPA) | -| — | Flathub remotes | `flatpak.sh` (after `flatpak` from `cli.packages`) | - -### Media (`install/media/`) - -| App | Method | -|-----|--------| -| Brave Browser | apt (vendor repo) | -| VLC | apt | -| ffmpeg, ubuntu-restricted-extras | apt | - -### Desktop (`install/desktop/`) - -| Tool | Method | -|------|--------| -| GNOME Tweaks, shell extensions | apt (`gnome.packages`) | - -### Productivity (`install/productivity/`) - -| App | Method | -|-----|--------| -| LibreOffice | apt | -| Zoom | `.deb`, else Flatpak, else snap | -| KeePassXC, Redshift, Flameshot | apt | -| balenaEtcher | apt (`.deb` from GitHub releases) | +## Install layout + +| Path | Role | +|------|------| +| `install/preflight/` | apt update, essentials (git, curl, universe), timezone | +| `install/packages/*.packages` | One apt package per line; installed by `packages/all.sh` | +| `install/griffo.sh`, `fastfetch.sh`, `btop.sh`, `flatpak.sh` | Repos, PPAs, or fallbacks only where apt lists are not enough | +| `install/apps/` | Vendor apt repos, `.deb`, Flatpak/snap fallbacks | +| `install/dev/` | NodeSource, nvm, LSP language stacks, Docker, Neovim PPA, rustup, gems, pip/npm tools | +| `install/shell/` | Ghostty, Meslo font, Oh My Posh | +| `install/post-install/` | apt maintain, Docker service, completion banner | + +### Package lists (`install/packages/`) + +| File | Contents | +|------|----------| +| `base.packages` | CLI and security tools (bat, fzf, gh, jq, ripgrep, ufw, nmap, exiftool, …) | +| `shell.packages` | zsh, tmux, fonts, plugins | +| `media.packages` | vlc, ffmpeg, gstreamer | +| `desktop.packages` | GNOME Tweaks, shell extensions | +| `productivity.packages` | LibreOffice, KeePassXC, Redshift, Flameshot | +| `lsp.packages` | Mason LSP runtimes (Go, Ruby, PHP, Lua, …) | +| `lsp-optional.packages` | Julia (skipped when unavailable on apt) | +| `dev.packages` | Neovim, Python | +| `griffo.packages` | yazi, lazygit, lazydocker ([debian.griffo.io](https://debian.griffo.io/apt)) | +| `fastfetch.packages` | fastfetch (PPA) | + +### Apps (`install/apps/`) + +Brave, Signal, Proton VPN/Pass, Bruno, Zoom, Etcher, OWASP ZAP, ufw-docker, +Hacking git clones — each script handles its own repo or `.deb` when apt lists are +not enough. ### Development (`install/dev/`) -| Tool | Method | -|------|--------| -| Node.js | apt (NodeSource) | -| nvm | upstream install script | -| Python 3, pip, venv, dev headers | apt | -| Mason LSP runtimes (Go, Ruby, PHP, Java, Lua, Julia, C toolchain) | apt | -| Rust / cargo | rustup | -| Solargraph (Ruby gem for `solargraph` LSP) | gem (`--user-install`) | -| Vue CLI | npm global | -| Docker CE + Compose | apt (Docker vendor repo) | -| Neovim | apt (PPA) + Python extras | -| gh, shellcheck | apt (`dev-tools.packages`) | -| **Bruno** (API client) | apt ([debian.usebruno.com](http://debian.usebruno.com/)), else Flatpak | -| Semgrep | pip (`--user`) | -| Cursor Agent CLI | [cursor.com/install](https://cursor.com/install) | - -### Security (`install/security/`) - -| Tool | Method | -|------|--------| -| UFW, OpenVPN, nmap, exiftool | apt (`security.packages`) | -| ufw-docker | [chaifeng/ufw-docker](https://github.com/chaifeng/ufw-docker) → `/usr/local/bin` | -| Proton VPN | apt (vendor `.deb` + packages) | -| Proton Pass (desktop) | vendor `.deb` | -| pass-cli | GitHub release binary | -| Signal Desktop | apt (vendor repo) | -| OWASP ZAP | Flatpak, else snap (`--classic`) | -| PayloadsAllTheThings, SecLists | git clone into `~/Hacking` | - -### Shell (`install/shell/`) - -| Tool | Method | -|------|--------| -| zsh, tmux, powerline | apt | -| zsh-autosuggestions, zsh-syntax-highlighting | apt | -| Font Awesome, Fira Code, Powerline fonts | apt | -| Meslo Nerd Font | GitHub release → `/usr/share/fonts` | -| Oh My Posh | [ohmyposh.dev](https://ohmyposh.dev) → `~/.local/bin` | -| Ghostty | [ghostty-ubuntu](https://github.com/mkasberg/ghostty-ubuntu) install script | +Node.js (NodeSource), nvm, Docker CE + Compose, rustup, Solargraph gem, Semgrep, +Vue CLI, Cursor Agent CLI. ### Preflight & post-install -- apt update/upgrade, essentials (git, curl, universe enabled) -- timezone (Los Angeles) -- Docker service enabled; UFW rules applied in config (LocalSend, Docker DNS, ufw-docker) +- apt update/upgrade, essentials, universe, timezone (Los Angeles) +- Docker service enabled; UFW rules in `config/security/` (LocalSend, Docker DNS, ufw-docker) ## Explicitly not installed @@ -129,7 +86,6 @@ These are **not** provisioned by this repo (remove from old notes or other dotfi Symlinks and settings from `src/dotfiles` (submodule): Zsh, tmux, Neovim, btop, fastfetch, Kitty/Alacritty/Ghostty, Git, VS Code `settings.json`, GNOME gsettings (skipped in CI without a GNOME session), UFW defaults and rules (LocalSend, -Docker DNS, ufw-docker), home directory -layout. +Docker DNS, ufw-docker), home directory layout. See [AGENTS.md](AGENTS.md) for contributor conventions, ShellCheck, and CI details. diff --git a/scripts/lib/validate-common.sh b/scripts/lib/validate-common.sh new file mode 100644 index 0000000..23a3fc2 --- /dev/null +++ b/scripts/lib/validate-common.sh @@ -0,0 +1,93 @@ +#!/bin/bash + +FAILURES=0 + +section() { + printf '\n== %s ==\n' "$1" +} + +pass() { + local name="$1" + local detail="${2:-}" + if [[ -n "$detail" ]]; then + printf ' ok %-28s %s\n' "$name" "$detail" + else + printf ' ok %s\n' "$name" + fi +} + +fail() { + local name="$1" + local detail="${2:-not found}" + printf ' FAIL %-28s %s\n' "$name" "$detail" >&2 + FAILURES=$((FAILURES + 1)) +} + +version_of() { + local cmd=("$@") + "${cmd[@]}" 2>/dev/null | head -n1 | tr -d '\r' || true +} + +check_version() { + local name="$1" + shift + local rc=0 + "$@" >/dev/null 2>&1 || rc=$? + if [[ "$rc" -eq 0 ]]; then + pass "$name" "$(version_of "$@")" + else + fail "$name" "expected: $*" + fi +} + +check_command() { + local name="$1" + local bin="$2" + if command -v "$bin" >/dev/null 2>&1; then + pass "$name" "$(command -v "$bin")" + else + fail "$name" "command not in PATH: $bin" + fi +} + +check_dpkg() { + local name="$1" + local pkg="$2" + if dpkg -s "$pkg" >/dev/null 2>&1; then + pass "$name" "$(dpkg -s "$pkg" 2>/dev/null | awk -F': ' '/^Version:/{print $2; exit}')" + else + fail "$name" "dpkg package missing: $pkg" + fi +} + +check_path() { + local name="$1" + local path="$2" + if [[ -e "$path" ]]; then + pass "$name" "$path" + else + fail "$name" "missing path: $path" + fi +} + +flatpak_installed() { + local app_id="$1" + flatpak list --columns=application --app 2>/dev/null | grep -Fxq "$app_id" && return 0 + flatpak list --user --columns=application --app 2>/dev/null | grep -Fxq "$app_id" && return 0 + return 1 +} + +snap_installed() { + local snap_name="$1" + snap list "$snap_name" 2>/dev/null | grep -q "^${snap_name} " +} + +finish_validation() { + local label="$1" + printf '\n' + if [[ "$FAILURES" -gt 0 ]]; then + printf '%s failed: %d check(s).\n' "$label" "$FAILURES" >&2 + exit 1 + fi + printf '%s passed.\n' "$label" +} diff --git a/scripts/validate-config.sh b/scripts/validate-config.sh new file mode 100755 index 0000000..1027b64 --- /dev/null +++ b/scripts/validate-config.sh @@ -0,0 +1,56 @@ +#!/usr/bin/env bash +# Verify config outcomes after master.sh / run-config.sh. +set -uo pipefail + +cd "$(dirname "$0")/.." || exit 1 + +# shellcheck source=lib/validate-common.sh +source "$(dirname "$0")/lib/validate-common.sh" + +dotfiles="${PWD}/src/dotfiles" + +section 'Dotfiles' +check_path dotfiles-nvim "$HOME/.config/nvim" +check_path dotfiles-fastfetch "$HOME/.config/fastfetch" +check_path dotfiles-btop "$HOME/.config/btop" +check_path dotfiles-zellij "$HOME/.config/zellij" +check_path dotfiles-tmux "$HOME/.config/tmux" +check_path dotfiles-ghostty "$HOME/.config/ghostty" +check_path dotfiles-path "$HOME/.dotfiles_path" +if [[ -f "$HOME/.dotfiles_path" ]]; then + dotfiles_link=$(head -1 "$HOME/.dotfiles_path") + if [[ "$dotfiles_link" == "$dotfiles" ]]; then + pass dotfiles-path-value "$dotfiles_link" + else + fail dotfiles-path-value "expected: $dotfiles" + fi +fi +check_path zshrc "$HOME/.zshrc" + +section 'Home layout' +check_path screenshots-dir "$HOME/Pictures/Screenshots" +check_path projects-personal "$HOME/Projects/personal" +check_path hacking-dir "$HOME/Hacking" + +section 'Git' +if git config --global user.name >/dev/null 2>&1; then + pass git-user-name "$(git config --global user.name)" +else + fail git-user-name 'git config --global user.name' +fi + +section 'System' +if sudo ufw status 2>/dev/null | grep -qi 'Status: active'; then + pass ufw-active 'ufw enabled' +else + fail ufw-active 'ufw status active' +fi +check_path logind-lid /etc/systemd/logind.conf.d/50-lid.conf +check_path sysctl-keepalive /etc/sysctl.d/99-tcp-keepalive.conf +if [[ -f /etc/default/apport ]] && grep -q '^enabled=0' /etc/default/apport; then + pass apport-disabled /etc/default/apport +else + fail apport-disabled 'enabled=0 in /etc/default/apport' +fi + +finish_validation 'Config validation' diff --git a/scripts/validate-installs.sh b/scripts/validate-installs.sh index 28903f8..cb74889 100755 --- a/scripts/validate-installs.sh +++ b/scripts/validate-installs.sh @@ -6,95 +6,16 @@ cd "$(dirname "$0")/.." || exit 1 export PATH="${HOME}/.cargo/bin:${HOME}/.local/bin:/usr/local/bin:${PATH}" -FAILURES=0 - -section() { - printf '\n== %s ==\n' "$1" -} - -pass() { - local name="$1" - local detail="${2:-}" - if [[ -n "$detail" ]]; then - printf ' ok %-28s %s\n' "$name" "$detail" - else - printf ' ok %s\n' "$name" - fi -} - -fail() { - local name="$1" - local detail="${2:-not found}" - printf ' FAIL %-28s %s\n' "$name" "$detail" >&2 - FAILURES=$((FAILURES + 1)) -} - -version_of() { - local cmd=("$@") - "${cmd[@]}" 2>/dev/null | head -n1 | tr -d '\r' || true -} - -check_version() { - local name="$1" - shift - local rc=0 - "$@" >/dev/null 2>&1 || rc=$? - if [[ "$rc" -eq 0 ]]; then - pass "$name" "$(version_of "$@")" - else - fail "$name" "expected: $*" - fi -} - -check_command() { - local name="$1" - local bin="$2" - if command -v "$bin" >/dev/null 2>&1; then - pass "$name" "$(command -v "$bin")" - else - fail "$name" "command not in PATH: $bin" - fi -} - -check_dpkg() { - local name="$1" - local pkg="$2" - if dpkg -s "$pkg" >/dev/null 2>&1; then - pass "$name" "$(dpkg -s "$pkg" 2>/dev/null | awk -F': ' '/^Version:/{print $2; exit}')" - else - fail "$name" "dpkg package missing: $pkg" - fi -} - -check_path() { - local name="$1" - local path="$2" - if [[ -e "$path" ]]; then - pass "$name" "$path" - else - fail "$name" "missing path: $path" - fi -} - -flatpak_installed() { - local app_id="$1" - flatpak list --columns=application --app 2>/dev/null | grep -Fxq "$app_id" && return 0 - flatpak list --user --columns=application --app 2>/dev/null | grep -Fxq "$app_id" && return 0 - return 1 -} - -snap_installed() { - local snap_name="$1" - snap list "$snap_name" 2>/dev/null | grep -q "^${snap_name} " -} +# shellcheck source=lib/validate-common.sh +source "$(dirname "$0")/lib/validate-common.sh" # --- Preflight (install/preflight) --- section 'Preflight' check_version curl curl --version check_version wget wget --version -# --- CLI (install/cli) --- -section 'CLI' +# --- Packages (install/packages) --- +section 'Packages' if command -v batcat >/dev/null 2>&1; then check_version bat batcat --version elif command -v bat >/dev/null 2>&1; then @@ -125,14 +46,12 @@ check_version btop btop --version check_version fastfetch fastfetch --version check_version flatpak flatpak --version -# --- Media (install/media) --- -section 'Media' +# --- Apps (install/apps) --- +section 'Apps' check_version brave brave-browser --version check_version vlc vlc --version check_version ffmpeg ffmpeg -version -# --- Productivity (install/productivity) --- -section 'Productivity' check_version libreoffice libreoffice --version check_dpkg keepassxc keepassxc check_version flameshot flameshot --version @@ -168,7 +87,11 @@ check_version cargo cargo --version check_version php php --version check_version composer composer --version check_version java java --version -check_version julia julia --version +if command -v julia >/dev/null 2>&1; then + check_version julia julia --version +else + pass julia 'optional (not in apt on all Ubuntu releases)' +fi check_version lua lua5.4 -e 'print(_VERSION)' check_version luarocks luarocks --version check_version gcc gcc --version @@ -221,16 +144,10 @@ fi check_path nvm "$HOME/.nvm/nvm.sh" -# --- Security (install/security) --- +# --- Security (install/apps + config/security) --- section 'Security' check_version nmap nmap --version -if command -v exiftool >/dev/null 2>&1; then - check_version exiftool exiftool -ver -elif dpkg -s libimage-exiftool-perl >/dev/null 2>&1; then - pass exiftool "$(dpkg -s libimage-exiftool-perl 2>/dev/null | awk -F': ' '/^Version:/{print $2; exit}')" -else - fail exiftool 'libimage-exiftool-perl (exiftool)' -fi +check_version exiftool exiftool -ver check_version openvpn openvpn --version check_dpkg ufw ufw check_path ufw-docker /usr/local/bin/ufw-docker @@ -261,17 +178,8 @@ fi check_path hacking-payloads "$HOME/Hacking/PayloadsAllTheThings" check_path hacking-seclists "$HOME/Hacking/SecLists" -# --- Desktop (install/desktop) --- -section 'Desktop' check_dpkg gnome-tweaks gnome-tweaks check_dpkg gnome-shell-extensions gnome-shell-extensions -if command -v gnome-extensions >/dev/null 2>&1; then - pass gnome-extensions "$(command -v gnome-extensions)" -elif dpkg -s gnome-shell-extensions >/dev/null 2>&1; then - pass gnome-extensions 'packages installed (CLI needs gnome-shell on desktop)' -else - fail gnome-extensions 'gnome.packages (gnome-shell-extensions)' -fi # --- Shell (install/shell) --- section 'Shell' @@ -296,11 +204,4 @@ else fail ghostty 'ghostty terminal' fi -# --- Summary --- -printf '\n' -if [[ "$FAILURES" -gt 0 ]]; then - printf 'Install validation failed: %d check(s) missing or wrong version.\n' "$FAILURES" >&2 - exit 1 -fi - -printf 'All install validations passed.\n' +finish_validation 'Install validation' diff --git a/scripts/validate.sh b/scripts/validate.sh new file mode 100755 index 0000000..b7e7b62 --- /dev/null +++ b/scripts/validate.sh @@ -0,0 +1,14 @@ +#!/usr/bin/env bash +# CI/local gate: installed tools and config outcomes after master.sh. +set -uo pipefail + +cd "$(dirname "$0")/.." || exit 1 +export PATH="${HOME}/.cargo/bin:${HOME}/.local/bin:/usr/local/bin:${PATH}" + +failures=0 +chmod +x scripts/validate-installs.sh scripts/validate-config.sh + +./scripts/validate-installs.sh || failures=$((failures + 1)) +./scripts/validate-config.sh || failures=$((failures + 1)) + +exit "$failures" diff --git a/setup_errors.log b/setup_errors.log new file mode 100644 index 0000000..3439894 --- /dev/null +++ b/setup_errors.log @@ -0,0 +1,81 @@ +The provided value is outside of the valid range +No such schema “org.gnome.gnome-screenshot” +No such schema “org.gnome.desktop.screenshots” +No such key “autohide-delay” +Cloning into '/home/garret/.nvm'... +E: The repository 'https://ppa.launchpadcontent.net/neovim-ppa/stable/ubuntu resolute Release' does not have a Release file. +N: Updating from such a repository can't be done securely, and is therefore disabled by default. +N: See apt-secure(8) manpage for repository creation and user configuration details. +E: The repository 'https://ppa.launchpadcontent.net/neovim-ppa/stable/ubuntu resolute Release' does not have a Release file. +N: Updating from such a repository can't be done securely, and is therefore disabled by default. +N: See apt-secure(8) manpage for repository creation and user configuration details. +[ERROR] Failed to update apt cache +[2026-06-02 21:07:44] ERROR: Failed to update apt cache +error: externally-managed-environment + +× This environment is externally managed +╰─> To install Python packages system-wide, try apt install + python3-xyz, where xyz is the package you are trying to + install. + + If you wish to install a non-Debian-packaged Python package, + create a virtual environment using python3 -m venv path/to/venv. + Then use path/to/venv/bin/python and path/to/venv/bin/pip. Make + sure you have python3-full installed. + + If you wish to install a non-Debian packaged Python application, + it may be easiest to use pipx install xyz, which will manage a + virtual environment for you. Make sure you have pipx installed. + + See /usr/share/doc/python3.14/README.venv for more information. + +note: If you believe this is a mistake, please contact your Python installation or OS distribution provider. You can override this, at the risk of breaking your Python installation or OS, by passing --break-system-packages. +hint: See PEP 668 for the detailed specification. +E: The repository 'https://ppa.launchpadcontent.net/neovim-ppa/stable/ubuntu resolute Release' does not have a Release file. +N: Updating from such a repository can't be done securely, and is therefore disabled by default. +N: See apt-secure(8) manpage for repository creation and user configuration details. +[ERROR] Failed to update apt cache +[2026-06-02 21:08:01] ERROR: Failed to update apt cache +E: The repository 'https://ppa.launchpadcontent.net/neovim-ppa/stable/ubuntu resolute Release' does not have a Release file. +N: Updating from such a repository can't be done securely, and is therefore disabled by default. +N: See apt-secure(8) manpage for repository creation and user configuration details. +[ERROR] Failed to update apt cache +[2026-06-02 21:08:04] ERROR: Failed to update apt cache +--2026-06-02 21:08:33-- https://updates.signal.org/desktop/apt/keys.asc +Resolving updates.signal.org (updates.signal.org)... 2606:4700::6812:3a6, 2606:4700::6812:2a6, 104.18.3.166, ... +Connecting to updates.signal.org (updates.signal.org)|2606:4700::6812:3a6|:443... connected. +HTTP request sent, awaiting response... 200 OK +Length: 3090 (3.0K) [application/pgp-signature] +Saving to: ‘/tmp/ubuntu-setup-19960/signal-key.asc’ + + 0K ... 100% 59.3M=0s + +2026-06-02 21:08:33 (59.3 MB/s) - ‘/tmp/ubuntu-setup-19960/signal-key.asc’ saved [3090/3090] + +E: The repository 'https://ppa.launchpadcontent.net/neovim-ppa/stable/ubuntu resolute Release' does not have a Release file. +N: Updating from such a repository can't be done securely, and is therefore disabled by default. +N: See apt-secure(8) manpage for repository creation and user configuration details. +[ERROR] Failed to update apt cache +[2026-06-02 21:08:36] ERROR: Failed to update apt cache +Cloning into '/home/garret/Hacking/PayloadsAllTheThings'... +Cloning into '/home/garret/Hacking/SecLists'... +Updating files: 3% (231/6272) Updating files: 4% (251/6272) Updating files: 5% (314/6272) Updating files: 6% (377/6272) Updating files: 7% (440/6272) Updating files: 8% (502/6272) Updating files: 9% (565/6272) Updating files: 10% (628/6272) Updating files: 11% (690/6272) Updating files: 12% (753/6272) Updating files: 13% (816/6272) Updating files: 14% (879/6272) Updating files: 15% (941/6272) Updating files: 16% (1004/6272) Updating files: 17% (1067/6272) Updating files: 18% (1129/6272) Updating files: 19% (1192/6272) Updating files: 20% (1255/6272) Updating files: 21% (1318/6272) Updating files: 22% (1380/6272) Updating files: 23% (1443/6272) Updating files: 24% (1506/6272) Updating files: 25% (1568/6272) Updating files: 26% (1631/6272) Updating files: 27% (1694/6272) Updating files: 28% (1757/6272) Updating files: 29% (1819/6272) Updating files: 30% (1882/6272) Updating files: 31% (1945/6272) Updating files: 32% (2008/6272) Updating files: 33% (2070/6272) Updating files: 34% (2133/6272) Updating files: 35% (2196/6272) Updating files: 36% (2258/6272) Updating files: 37% (2321/6272) Updating files: 38% (2384/6272) Updating files: 39% (2447/6272) Updating files: 40% (2509/6272) Updating files: 41% (2572/6272) Updating files: 42% (2635/6272) Updating files: 43% (2697/6272) Updating files: 44% (2760/6272) Updating files: 45% (2823/6272) Updating files: 46% (2886/6272) Updating files: 47% (2948/6272) Updating files: 48% (3011/6272) Updating files: 49% (3074/6272) Updating files: 50% (3136/6272) Updating files: 51% (3199/6272) Updating files: 52% (3262/6272) Updating files: 53% (3325/6272) Updating files: 54% (3387/6272) Updating files: 55% (3450/6272) Updating files: 56% (3513/6272) Updating files: 57% (3576/6272) Updating files: 58% (3638/6272) Updating files: 59% (3701/6272) Updating files: 60% (3764/6272) Updating files: 61% (3826/6272) Updating files: 62% (3889/6272) Updating files: 63% (3952/6272) Updating files: 64% (4015/6272) Updating files: 65% (4077/6272) Updating files: 66% (4140/6272) Updating files: 67% (4203/6272) Updating files: 68% (4265/6272) Updating files: 69% (4328/6272) Updating files: 70% (4391/6272) Updating files: 71% (4454/6272) Updating files: 72% (4516/6272) Updating files: 73% (4579/6272) Updating files: 74% (4642/6272) Updating files: 75% (4704/6272) Updating files: 76% (4767/6272) Updating files: 77% (4830/6272) Updating files: 78% (4893/6272) Updating files: 79% (4955/6272) Updating files: 80% (5018/6272) Updating files: 81% (5081/6272) Updating files: 82% (5144/6272) Updating files: 82% (5158/6272) Updating files: 83% (5206/6272) Updating files: 84% (5269/6272) Updating files: 85% (5332/6272) Updating files: 86% (5394/6272) Updating files: 86% (5456/6272) Updating files: 87% (5457/6272) Updating files: 88% (5520/6272) Updating files: 89% (5583/6272) Updating files: 90% (5645/6272) Updating files: 91% (5708/6272) Updating files: 92% (5771/6272) Updating files: 93% (5833/6272) Updating files: 94% (5896/6272) Updating files: 95% (5959/6272) Updating files: 96% (6022/6272) Updating files: 96% (6039/6272) Updating files: 97% (6084/6272) Updating files: 98% (6147/6272) Updating files: 99% (6210/6272) Updating files: 100% (6272/6272) Updating files: 100% (6272/6272), done. +E: The repository 'https://ppa.launchpadcontent.net/neovim-ppa/stable/ubuntu resolute Release' does not have a Release file. +N: Updating from such a repository can't be done securely, and is therefore disabled by default. +N: See apt-secure(8) manpage for repository creation and user configuration details. +[ERROR] Failed to update apt cache +[2026-06-02 21:10:43] ERROR: Failed to update apt cache + % Total % Received % Xferd Average Speed Time Time Time Current + Dload Upload Total Spent Left Speed + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 100 16.97M 100 16.97M 0 0 25.44M 0 0 100 16.97M 100 16.97M 0 0 25.44M 0 0 100 16.97M 100 16.97M 0 0 25.44M 0 0 +N: Download is performed unsandboxed as root as file '/home/garret/ubuntu-setup-scripts/ghostty_1.3.1-0.ppa2_amd64_26.04.deb' couldn't be accessed by user '_apt'. - pkgAcquire::Run (13: Permission denied) +/usr/share/fonts/truetype: failed to write cache +Cloning into '/tmp/ubuntu-setup-23266/oh-my-posh-repo'... +E: The repository 'https://ppa.launchpadcontent.net/neovim-ppa/stable/ubuntu resolute Release' does not have a Release file. +N: Updating from such a repository can't be done securely, and is therefore disabled by default. +N: See apt-secure(8) manpage for repository creation and user configuration details. +[ERROR] Failed to update apt cache +[2026-06-02 21:11:13] ERROR: Failed to update apt cache +Synchronizing state of docker.service with SysV service script with /usr/lib/systemd/systemd-sysv-install. +Executing: /usr/lib/systemd/systemd-sysv-install enable docker diff --git a/src/scripts/install/all.sh b/src/scripts/install/all.sh index ee2945b..4115d22 100644 --- a/src/scripts/install/all.sh +++ b/src/scripts/install/all.sh @@ -6,12 +6,8 @@ source "$DIR/../lib/env.sh" # shellcheck source=../lib/run.sh source "$DIR/../lib/run.sh" -run_script "$DIR/preflight/all.sh" -run_script "$DIR/cli/all.sh" -run_script "$DIR/media/all.sh" -run_script "$DIR/productivity/all.sh" -run_script "$DIR/desktop/all.sh" +run_script "$DIR/packages/all.sh" +run_script "$DIR/apps/all.sh" run_script "$DIR/dev/all.sh" -run_script "$DIR/security/all.sh" run_script "$DIR/shell/all.sh" run_script "$DIR/post-install/all.sh" diff --git a/src/scripts/install/security/all.sh b/src/scripts/install/apps/all.sh similarity index 73% rename from src/scripts/install/security/all.sh rename to src/scripts/install/apps/all.sh index a200964..bf26c4c 100644 --- a/src/scripts/install/security/all.sh +++ b/src/scripts/install/apps/all.sh @@ -4,10 +4,13 @@ DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" # shellcheck source=../../lib/run.sh source "$DIR/../../lib/run.sh" -run_script "$DIR/security-apt.sh" -run_script "$DIR/ufw-docker.sh" +run_script "$DIR/brave-browser.sh" +run_script "$DIR/signal-desktop.sh" run_script "$DIR/protonvpn.sh" run_script "$DIR/proton-pass.sh" -run_script "$DIR/signal-desktop.sh" +run_script "$DIR/bruno.sh" +run_script "$DIR/zoom.sh" +run_script "$DIR/etcher.sh" run_script "$DIR/zaproxy.sh" +run_script "$DIR/ufw-docker.sh" run_script "$DIR/hacking-repos.sh" diff --git a/src/scripts/install/media/brave-browser.sh b/src/scripts/install/apps/brave-browser.sh similarity index 100% rename from src/scripts/install/media/brave-browser.sh rename to src/scripts/install/apps/brave-browser.sh diff --git a/src/scripts/install/dev/bruno.sh b/src/scripts/install/apps/bruno.sh similarity index 100% rename from src/scripts/install/dev/bruno.sh rename to src/scripts/install/apps/bruno.sh diff --git a/src/scripts/install/productivity/etcher.sh b/src/scripts/install/apps/etcher.sh similarity index 100% rename from src/scripts/install/productivity/etcher.sh rename to src/scripts/install/apps/etcher.sh diff --git a/src/scripts/install/security/hacking-repos.sh b/src/scripts/install/apps/hacking-repos.sh similarity index 100% rename from src/scripts/install/security/hacking-repos.sh rename to src/scripts/install/apps/hacking-repos.sh diff --git a/src/scripts/install/security/proton-pass.sh b/src/scripts/install/apps/proton-pass.sh similarity index 100% rename from src/scripts/install/security/proton-pass.sh rename to src/scripts/install/apps/proton-pass.sh diff --git a/src/scripts/install/security/protonvpn.sh b/src/scripts/install/apps/protonvpn.sh similarity index 100% rename from src/scripts/install/security/protonvpn.sh rename to src/scripts/install/apps/protonvpn.sh diff --git a/src/scripts/install/security/signal-desktop.sh b/src/scripts/install/apps/signal-desktop.sh similarity index 100% rename from src/scripts/install/security/signal-desktop.sh rename to src/scripts/install/apps/signal-desktop.sh diff --git a/src/scripts/install/security/ufw-docker.sh b/src/scripts/install/apps/ufw-docker.sh similarity index 100% rename from src/scripts/install/security/ufw-docker.sh rename to src/scripts/install/apps/ufw-docker.sh diff --git a/src/scripts/install/security/zaproxy.sh b/src/scripts/install/apps/zaproxy.sh similarity index 100% rename from src/scripts/install/security/zaproxy.sh rename to src/scripts/install/apps/zaproxy.sh diff --git a/src/scripts/install/productivity/zoom.sh b/src/scripts/install/apps/zoom.sh similarity index 100% rename from src/scripts/install/productivity/zoom.sh rename to src/scripts/install/apps/zoom.sh diff --git a/src/scripts/install/cli/btop.sh b/src/scripts/install/btop.sh similarity index 82% rename from src/scripts/install/cli/btop.sh rename to src/scripts/install/btop.sh index 88e902c..8d4df85 100644 --- a/src/scripts/install/cli/btop.sh +++ b/src/scripts/install/btop.sh @@ -1,17 +1,12 @@ #!/bin/bash -DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" - if command -v btop >/dev/null 2>&1; then exit 0 fi ubuntu_release="$(lsb_release -rs 2>/dev/null || echo "")" if [[ -n "$ubuntu_release" ]] && dpkg --compare-versions "$ubuntu_release" ge 22.04 2>/dev/null; then - mapfile -t packages < <(grep -v '^#' "$DIR/btop.packages" | grep -v '^[[:space:]]*$') - if [[ ${#packages[@]} -gt 0 ]]; then - sudo DEBIAN_FRONTEND=noninteractive apt-get install -y "${packages[@]}" || true - fi + sudo DEBIAN_FRONTEND=noninteractive apt-get install -y btop || true fi if command -v btop >/dev/null 2>&1; then exit 0 diff --git a/src/scripts/install/cli/all.sh b/src/scripts/install/cli/all.sh deleted file mode 100644 index 9e61c9e..0000000 --- a/src/scripts/install/cli/all.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/bash - -DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -# shellcheck source=../../lib/run.sh -source "$DIR/../../lib/run.sh" - -run_script "$DIR/flatpak.sh" -run_script "$DIR/cli-tools.sh" -run_script "$DIR/yazi.sh" -run_script "$DIR/btop.sh" -run_script "$DIR/fastfetch.sh" diff --git a/src/scripts/install/cli/btop.packages b/src/scripts/install/cli/btop.packages deleted file mode 100644 index 784cba6..0000000 --- a/src/scripts/install/cli/btop.packages +++ /dev/null @@ -1,3 +0,0 @@ -# Apt when available (Ubuntu >= 22.04); fallbacks in btop.sh - -btop diff --git a/src/scripts/install/cli/cli-tools.sh b/src/scripts/install/cli/cli-tools.sh deleted file mode 100644 index 127eece..0000000 --- a/src/scripts/install/cli/cli-tools.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/bash - -DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -packages_file="$DIR/cli.packages" - -mapfile -t packages < <(grep -v '^#' "$packages_file" | grep -v '^[[:space:]]*$') -if [[ ${#packages[@]} -eq 0 ]]; then - exit 0 -fi - -sudo DEBIAN_FRONTEND=noninteractive apt-get install -y "${packages[@]}" diff --git a/src/scripts/install/cli/cli.packages b/src/scripts/install/cli/cli.packages deleted file mode 100644 index 145bfb8..0000000 --- a/src/scripts/install/cli/cli.packages +++ /dev/null @@ -1,26 +0,0 @@ -# Apt packages for CLI tools (universe / main). One package per line. -# Installed by cli-tools.sh. Add tools here; use a separate *.packages file when -# a tool needs a PPA or third-party repo (see yazi.packages, fastfetch.packages). - -bat -curl -dbus-x11 -eza -fd-find -flatpak -fzf -gcc -git -htop -jq -libsecret-1-0 -libsecret-1-dev -pkg-config -ripgrep -tealdeer -tree-sitter-cli -unzip -vim -whois -wget -zoxide diff --git a/src/scripts/install/cli/fastfetch.packages b/src/scripts/install/cli/fastfetch.packages deleted file mode 100644 index 6c3d4a0..0000000 --- a/src/scripts/install/cli/fastfetch.packages +++ /dev/null @@ -1,3 +0,0 @@ -# PPA: zhangsongcui3371/fastfetch (configured in fastfetch.sh) - -fastfetch diff --git a/src/scripts/install/cli/fastfetch.sh b/src/scripts/install/cli/fastfetch.sh deleted file mode 100644 index 11c0537..0000000 --- a/src/scripts/install/cli/fastfetch.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/bash - -DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" - -sudo add-apt-repository -y ppa:zhangsongcui3371/fastfetch || true -sudo apt-get update -y || true - -mapfile -t packages < <(grep -v '^#' "$DIR/fastfetch.packages" | grep -v '^[[:space:]]*$') -if [[ ${#packages[@]} -gt 0 ]]; then - sudo DEBIAN_FRONTEND=noninteractive apt-get install -y "${packages[@]}" -fi diff --git a/src/scripts/install/cli/yazi.packages b/src/scripts/install/cli/yazi.packages deleted file mode 100644 index d29c41a..0000000 --- a/src/scripts/install/cli/yazi.packages +++ /dev/null @@ -1,5 +0,0 @@ -# debian.griffo.io apt repo (configured in yazi.sh) - -lazydocker -lazygit -yazi diff --git a/src/scripts/install/cli/yazi.sh b/src/scripts/install/cli/yazi.sh deleted file mode 100644 index 0207c40..0000000 --- a/src/scripts/install/cli/yazi.sh +++ /dev/null @@ -1,24 +0,0 @@ -#!/bin/bash - -DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" - -yazi_key="/etc/apt/trusted.gpg.d/debian.griffo.io.gpg" -if [[ ! -f "$yazi_key" ]]; then - curl -fsSL https://debian.griffo.io/EA0F721D231FDD3A0A17B9AC7808B4DD62C41256.asc | \ - sudo gpg --dearmor --yes -o "$yazi_key" || true -fi - -yazi_list="/etc/apt/sources.list.d/debian.griffo.io.list" -ubuntu_codename="$(lsb_release -sc 2>/dev/null || echo "")" -if [[ -n "$ubuntu_codename" ]]; then - if [[ ! -f "$yazi_list" ]] || ! grep -q debian.griffo.io "$yazi_list" 2>/dev/null; then - echo "deb https://debian.griffo.io/apt $ubuntu_codename main" | \ - sudo tee "$yazi_list" >/dev/null || true - sudo apt-get update -y || true - fi -fi - -mapfile -t packages < <(grep -v '^#' "$DIR/yazi.packages" | grep -v '^[[:space:]]*$') -if [[ ${#packages[@]} -gt 0 ]]; then - sudo DEBIAN_FRONTEND=noninteractive apt-get install -y "${packages[@]}" -fi diff --git a/src/scripts/install/desktop/all.sh b/src/scripts/install/desktop/all.sh deleted file mode 100644 index 9063b15..0000000 --- a/src/scripts/install/desktop/all.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/bash - -DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -# shellcheck source=../../lib/run.sh -source "$DIR/../../lib/run.sh" - -run_script "$DIR/gnome-apt.sh" diff --git a/src/scripts/install/desktop/gnome-apt.sh b/src/scripts/install/desktop/gnome-apt.sh deleted file mode 100644 index 626481c..0000000 --- a/src/scripts/install/desktop/gnome-apt.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/bash - -DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -packages_file="$DIR/gnome.packages" - -mapfile -t packages < <(grep -v '^#' "$packages_file" | grep -v '^[[:space:]]*$') -if [[ ${#packages[@]} -eq 0 ]]; then - exit 0 -fi - -sudo DEBIAN_FRONTEND=noninteractive apt-get install -y "${packages[@]}" diff --git a/src/scripts/install/desktop/gnome.packages b/src/scripts/install/desktop/gnome.packages deleted file mode 100644 index 62ca14e..0000000 --- a/src/scripts/install/desktop/gnome.packages +++ /dev/null @@ -1,4 +0,0 @@ -# GNOME desktop tools (gnome-extensions CLI ships with gnome-shell on desktop installs) - -gnome-shell-extensions -gnome-tweaks diff --git a/src/scripts/install/dev/all.sh b/src/scripts/install/dev/all.sh index 8478c52..208435b 100644 --- a/src/scripts/install/dev/all.sh +++ b/src/scripts/install/dev/all.sh @@ -3,17 +3,18 @@ DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" # shellcheck source=../../lib/run.sh source "$DIR/../../lib/run.sh" +# shellcheck source=../../lib/apt-packages.sh +source "$DIR/../../lib/apt-packages.sh" +run_script "$DIR/neovim.sh" run_script "$DIR/nodesource-nodejs.sh" run_script "$DIR/nvm.sh" -run_script "$DIR/python.sh" -run_script "$DIR/lsp-deps-apt.sh" +install_apt_packages_from_file "$DIR/../packages/lsp.packages" +install_apt_packages_from_file "$DIR/../packages/lsp-optional.packages" optional +install_apt_packages_from_file "$DIR/../packages/dev.packages" run_script "$DIR/rustup.sh" run_script "$DIR/ruby-gems.sh" -run_script "$DIR/vue-cli.sh" run_script "$DIR/docker.sh" -run_script "$DIR/neovim.sh" -run_script "$DIR/dev-tools-apt.sh" -run_script "$DIR/bruno.sh" +run_script "$DIR/vue-cli.sh" run_script "$DIR/semgrep.sh" run_script "$DIR/cursor-cli.sh" diff --git a/src/scripts/install/dev/dev-tools-apt.sh b/src/scripts/install/dev/dev-tools-apt.sh deleted file mode 100644 index ea6e2f6..0000000 --- a/src/scripts/install/dev/dev-tools-apt.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/bash - -DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -packages_file="$DIR/dev-tools.packages" - -mapfile -t packages < <(grep -v '^#' "$packages_file" | grep -v '^[[:space:]]*$') -if [[ ${#packages[@]} -eq 0 ]]; then - exit 0 -fi - -sudo DEBIAN_FRONTEND=noninteractive apt-get install -y "${packages[@]}" diff --git a/src/scripts/install/dev/dev-tools.packages b/src/scripts/install/dev/dev-tools.packages deleted file mode 100644 index d412e23..0000000 --- a/src/scripts/install/dev/dev-tools.packages +++ /dev/null @@ -1,4 +0,0 @@ -# Dev CLI tools (apt). One package per line. - -gh -shellcheck diff --git a/src/scripts/install/dev/docker.sh b/src/scripts/install/dev/docker.sh index 78bc66f..ec007a2 100644 --- a/src/scripts/install/dev/docker.sh +++ b/src/scripts/install/dev/docker.sh @@ -1,10 +1,11 @@ #!/bin/bash -sudo DEBIAN_FRONTEND=noninteractive apt-get install -y apt-transport-https ca-certificates software-properties-common gnupg lsb-release + if [[ ! -f /usr/share/keyrings/docker-archive-keyring.gpg ]]; then curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg || true fi if ! grep -q download.docker.com /etc/apt/sources.list.d/*.list 2>/dev/null; then - echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list >/dev/null || true + echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | \ + sudo tee /etc/apt/sources.list.d/docker.list >/dev/null || true sudo apt-get update -y || true fi sudo DEBIAN_FRONTEND=noninteractive apt-get install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin diff --git a/src/scripts/install/dev/lsp-deps-apt.sh b/src/scripts/install/dev/lsp-deps-apt.sh deleted file mode 100755 index 9738cce..0000000 --- a/src/scripts/install/dev/lsp-deps-apt.sh +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/bash -sudo DEBIAN_FRONTEND=noninteractive apt-get install -y \ - build-essential \ - gzip \ - tar \ - curl \ - golang-go \ - ruby-full \ - ruby-dev \ - default-jdk-headless \ - php-cli \ - php-mbstring \ - php-xml \ - php-zip \ - composer \ - lua5.4 \ - liblua5.4-dev \ - luarocks - -# Julia is not in all Ubuntu releases (e.g. ubuntu-latest); do not fail the batch above. -sudo DEBIAN_FRONTEND=noninteractive apt-get install -y julia || true diff --git a/src/scripts/install/dev/neovim.sh b/src/scripts/install/dev/neovim.sh index a67b8a4..d4458ac 100644 --- a/src/scripts/install/dev/neovim.sh +++ b/src/scripts/install/dev/neovim.sh @@ -1,4 +1,4 @@ #!/bin/bash + sudo add-apt-repository -y ppa:neovim-ppa/stable || true sudo apt-get update -y || true -sudo DEBIAN_FRONTEND=noninteractive apt-get install -y neovim python3-neovim python3-dev python3-pip diff --git a/src/scripts/install/dev/nodesource-nodejs.sh b/src/scripts/install/dev/nodesource-nodejs.sh index 51bc490..84caba4 100644 --- a/src/scripts/install/dev/nodesource-nodejs.sh +++ b/src/scripts/install/dev/nodesource-nodejs.sh @@ -2,7 +2,6 @@ NODE_MAJOR=24 nodesource_key="/etc/apt/keyrings/nodesource.gpg" nodesource_list="/etc/apt/sources.list.d/nodesource.list" -sudo DEBIAN_FRONTEND=noninteractive apt-get install -y ca-certificates curl gnupg sudo mkdir -p /etc/apt/keyrings if [[ ! -f "$nodesource_key" ]]; then curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | sudo gpg --dearmor -o "$nodesource_key" || true diff --git a/src/scripts/install/dev/python.sh b/src/scripts/install/dev/python.sh deleted file mode 100644 index 48690d7..0000000 --- a/src/scripts/install/dev/python.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/bash -sudo DEBIAN_FRONTEND=noninteractive apt-get install -y python3 python3-pip python3-venv python3-dev diff --git a/src/scripts/install/fastfetch.sh b/src/scripts/install/fastfetch.sh new file mode 100644 index 0000000..74b469c --- /dev/null +++ b/src/scripts/install/fastfetch.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +# shellcheck source=../lib/apt-packages.sh +source "$DIR/../lib/apt-packages.sh" + +sudo add-apt-repository -y ppa:zhangsongcui3371/fastfetch || true +sudo apt-get update -y || true +install_apt_packages_from_file "$DIR/packages/fastfetch.packages" diff --git a/src/scripts/install/cli/flatpak.sh b/src/scripts/install/flatpak.sh similarity index 100% rename from src/scripts/install/cli/flatpak.sh rename to src/scripts/install/flatpak.sh diff --git a/src/scripts/install/griffo.sh b/src/scripts/install/griffo.sh new file mode 100644 index 0000000..4e67e8a --- /dev/null +++ b/src/scripts/install/griffo.sh @@ -0,0 +1,23 @@ +#!/bin/bash + +DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +# shellcheck source=../lib/apt-packages.sh +source "$DIR/../lib/apt-packages.sh" + +griffo_key="/etc/apt/trusted.gpg.d/debian.griffo.io.gpg" +if [[ ! -f "$griffo_key" ]]; then + curl -fsSL https://debian.griffo.io/EA0F721D231FDD3A0A17B9AC7808B4DD62C41256.asc | \ + sudo gpg --dearmor --yes -o "$griffo_key" || true +fi + +griffo_list="/etc/apt/sources.list.d/debian.griffo.io.list" +ubuntu_codename="$(lsb_release -sc 2>/dev/null || echo "")" +if [[ -n "$ubuntu_codename" ]]; then + if [[ ! -f "$griffo_list" ]] || ! grep -q debian.griffo.io "$griffo_list" 2>/dev/null; then + echo "deb https://debian.griffo.io/apt $ubuntu_codename main" | \ + sudo tee "$griffo_list" >/dev/null || true + sudo apt-get update -y || true + fi +fi + +install_apt_packages_from_file "$DIR/packages/griffo.packages" diff --git a/src/scripts/install/media/all.sh b/src/scripts/install/media/all.sh deleted file mode 100644 index cc97867..0000000 --- a/src/scripts/install/media/all.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/bash - -DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -# shellcheck source=../../lib/run.sh -source "$DIR/../../lib/run.sh" - -run_script "$DIR/brave-browser.sh" -run_script "$DIR/vlc.sh" -run_script "$DIR/multimedia.sh" diff --git a/src/scripts/install/media/multimedia.sh b/src/scripts/install/media/multimedia.sh deleted file mode 100644 index 5825087..0000000 --- a/src/scripts/install/media/multimedia.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/bash -sudo DEBIAN_FRONTEND=noninteractive apt-get install -y ffmpeg gstreamer1.0-plugins-bad gstreamer1.0-plugins-ugly gstreamer1.0-libav -echo "ttf-mscorefonts-installer msttcorefonts/accepted-mscorefonts-eula select true" | sudo debconf-set-selections || true -sudo DEBIAN_FRONTEND=noninteractive apt-get install -y ubuntu-restricted-extras || true diff --git a/src/scripts/install/media/vlc.sh b/src/scripts/install/media/vlc.sh deleted file mode 100644 index d8f007b..0000000 --- a/src/scripts/install/media/vlc.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/bash -sudo DEBIAN_FRONTEND=noninteractive apt-get install -y vlc diff --git a/src/scripts/install/packages/all.sh b/src/scripts/install/packages/all.sh new file mode 100644 index 0000000..50c8207 --- /dev/null +++ b/src/scripts/install/packages/all.sh @@ -0,0 +1,19 @@ +#!/bin/bash + +DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +# shellcheck source=../../lib/run.sh +source "$DIR/../../lib/run.sh" +# shellcheck source=../../lib/apt-packages.sh +source "$DIR/../../lib/apt-packages.sh" + +for list in base shell media desktop productivity; do + install_apt_packages_from_file "$DIR/${list}.packages" +done + +echo "ttf-mscorefonts-installer msttcorefonts/accepted-mscorefonts-eula select true" | sudo debconf-set-selections || true +sudo DEBIAN_FRONTEND=noninteractive apt-get install -y ubuntu-restricted-extras || true + +run_script "$DIR/../griffo.sh" +run_script "$DIR/../fastfetch.sh" +run_script "$DIR/../btop.sh" +run_script "$DIR/../flatpak.sh" diff --git a/src/scripts/install/packages/base.packages b/src/scripts/install/packages/base.packages new file mode 100644 index 0000000..4328e43 --- /dev/null +++ b/src/scripts/install/packages/base.packages @@ -0,0 +1,29 @@ +# CLI, security, and general apt tools (universe/main). Preflight installs git/curl first. + +bat +btop +dbus-x11 +eza +fd-find +flatpak +fzf +gcc +gh +htop +jq +libimage-exiftool-perl +libsecret-1-0 +libsecret-1-dev +nmap +openvpn +pkg-config +ripgrep +shellcheck +tealdeer +tree-sitter-cli +ufw +unzip +vim +whois +wget +zoxide diff --git a/src/scripts/install/packages/desktop.packages b/src/scripts/install/packages/desktop.packages new file mode 100644 index 0000000..4d4a09a --- /dev/null +++ b/src/scripts/install/packages/desktop.packages @@ -0,0 +1,2 @@ +gnome-shell-extensions +gnome-tweaks diff --git a/src/scripts/install/packages/dev.packages b/src/scripts/install/packages/dev.packages new file mode 100644 index 0000000..26d72a3 --- /dev/null +++ b/src/scripts/install/packages/dev.packages @@ -0,0 +1,6 @@ +neovim +python3 +python3-dev +python3-neovim +python3-pip +python3-venv diff --git a/src/scripts/install/packages/fastfetch.packages b/src/scripts/install/packages/fastfetch.packages new file mode 100644 index 0000000..215b1e7 --- /dev/null +++ b/src/scripts/install/packages/fastfetch.packages @@ -0,0 +1 @@ +fastfetch diff --git a/src/scripts/install/packages/griffo.packages b/src/scripts/install/packages/griffo.packages new file mode 100644 index 0000000..5d2cb5a --- /dev/null +++ b/src/scripts/install/packages/griffo.packages @@ -0,0 +1,3 @@ +lazydocker +lazygit +yazi diff --git a/src/scripts/install/packages/lsp-optional.packages b/src/scripts/install/packages/lsp-optional.packages new file mode 100644 index 0000000..9146f2b --- /dev/null +++ b/src/scripts/install/packages/lsp-optional.packages @@ -0,0 +1 @@ +julia diff --git a/src/scripts/install/packages/lsp.packages b/src/scripts/install/packages/lsp.packages new file mode 100644 index 0000000..ca00c99 --- /dev/null +++ b/src/scripts/install/packages/lsp.packages @@ -0,0 +1,15 @@ +build-essential +composer +default-jdk-headless +golang-go +gzip +liblua5.4-dev +luarocks +lua5.4 +php-cli +php-mbstring +php-xml +php-zip +ruby-dev +ruby-full +tar diff --git a/src/scripts/install/packages/media.packages b/src/scripts/install/packages/media.packages new file mode 100644 index 0000000..8fd69aa --- /dev/null +++ b/src/scripts/install/packages/media.packages @@ -0,0 +1,5 @@ +ffmpeg +gstreamer1.0-libav +gstreamer1.0-plugins-bad +gstreamer1.0-plugins-ugly +vlc diff --git a/src/scripts/install/packages/productivity.packages b/src/scripts/install/packages/productivity.packages new file mode 100644 index 0000000..dfcbd06 --- /dev/null +++ b/src/scripts/install/packages/productivity.packages @@ -0,0 +1,6 @@ +flameshot +keepassxc +libreoffice +libreoffice-gtk3 +libreoffice-style-breeze +redshift diff --git a/src/scripts/install/packages/shell.packages b/src/scripts/install/packages/shell.packages new file mode 100644 index 0000000..5c39b84 --- /dev/null +++ b/src/scripts/install/packages/shell.packages @@ -0,0 +1,8 @@ +fonts-font-awesome +fonts-firacode +fonts-powerline +powerline +tmux +zsh +zsh-autosuggestions +zsh-syntax-highlighting diff --git a/src/scripts/install/post-install/completion-banner.sh b/src/scripts/install/post-install/completion-banner.sh index 2ed5ebc..465b354 100644 --- a/src/scripts/install/post-install/completion-banner.sh +++ b/src/scripts/install/post-install/completion-banner.sh @@ -8,4 +8,4 @@ if [[ -f "$art" ]]; then echo "============================================================================" echo fi -echo "Setup completed. Check $ERROR_LOG_FILE for any errors." +echo "Setup completed." diff --git a/src/scripts/install/productivity/all.sh b/src/scripts/install/productivity/all.sh deleted file mode 100644 index fd782a1..0000000 --- a/src/scripts/install/productivity/all.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/bash - -DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -# shellcheck source=../../lib/run.sh -source "$DIR/../../lib/run.sh" - -run_script "$DIR/libreoffice.sh" -run_script "$DIR/zoom.sh" -run_script "$DIR/productivity-apt.sh" -run_script "$DIR/etcher.sh" diff --git a/src/scripts/install/productivity/libreoffice.sh b/src/scripts/install/productivity/libreoffice.sh deleted file mode 100644 index 2e78754..0000000 --- a/src/scripts/install/productivity/libreoffice.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/bash -sudo DEBIAN_FRONTEND=noninteractive apt-get install -y libreoffice libreoffice-gtk3 libreoffice-style-breeze diff --git a/src/scripts/install/productivity/productivity-apt.sh b/src/scripts/install/productivity/productivity-apt.sh deleted file mode 100644 index 926f5e1..0000000 --- a/src/scripts/install/productivity/productivity-apt.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/bash -sudo DEBIAN_FRONTEND=noninteractive apt-get install -y keepassxc redshift flameshot diff --git a/src/scripts/install/security/security-apt.sh b/src/scripts/install/security/security-apt.sh deleted file mode 100644 index 96fee14..0000000 --- a/src/scripts/install/security/security-apt.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/bash - -DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -packages_file="$DIR/security.packages" - -sudo apt-get update -y || true - -mapfile -t packages < <(grep -v '^#' "$packages_file" | grep -v '^[[:space:]]*$') -if [[ ${#packages[@]} -eq 0 ]]; then - exit 0 -fi - -sudo DEBIAN_FRONTEND=noninteractive apt-get install -y "${packages[@]}" diff --git a/src/scripts/install/security/security.packages b/src/scripts/install/security/security.packages deleted file mode 100644 index 7ffa9eb..0000000 --- a/src/scripts/install/security/security.packages +++ /dev/null @@ -1,7 +0,0 @@ -# Security and network tooling. One package per line. -# libimage-exiftool-perl provides the exiftool command on Ubuntu. - -libimage-exiftool-perl -nmap -openvpn -ufw diff --git a/src/scripts/install/shell/all.sh b/src/scripts/install/shell/all.sh index e07baf3..909500d 100644 --- a/src/scripts/install/shell/all.sh +++ b/src/scripts/install/shell/all.sh @@ -4,9 +4,6 @@ DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" # shellcheck source=../../lib/run.sh source "$DIR/../../lib/run.sh" -run_script "$DIR/shell-apt.sh" run_script "$DIR/ghostty.sh" -run_script "$DIR/fonts-apt.sh" run_script "$DIR/meslo-nerd-font.sh" -run_script "$DIR/zsh-plugins.sh" run_script "$DIR/oh-my-posh.sh" diff --git a/src/scripts/install/shell/fonts-apt.sh b/src/scripts/install/shell/fonts-apt.sh deleted file mode 100644 index f25535f..0000000 --- a/src/scripts/install/shell/fonts-apt.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash - -sudo DEBIAN_FRONTEND=noninteractive apt-get install -y fonts-font-awesome fonts-firacode fonts-powerline diff --git a/src/scripts/install/shell/oh-my-posh.sh b/src/scripts/install/shell/oh-my-posh.sh index d8cb1ea..fa4e947 100644 --- a/src/scripts/install/shell/oh-my-posh.sh +++ b/src/scripts/install/shell/oh-my-posh.sh @@ -1,7 +1,5 @@ #!/bin/bash -sudo DEBIAN_FRONTEND=noninteractive apt-get install -y unzip curl - install_script="$TEMP_DIR/oh-my-posh-install.sh" curl -fsSL https://ohmyposh.dev/install.sh -o "$install_script" || exit 0 bash "$install_script" -d "${HOME}/.local/bin" 2>/dev/null || true diff --git a/src/scripts/install/shell/shell-apt.sh b/src/scripts/install/shell/shell-apt.sh deleted file mode 100644 index 8a366ca..0000000 --- a/src/scripts/install/shell/shell-apt.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/bash - -sudo apt-get update -y || true -sudo DEBIAN_FRONTEND=noninteractive apt-get install -y zsh tmux powerline diff --git a/src/scripts/install/shell/zsh-plugins.sh b/src/scripts/install/shell/zsh-plugins.sh deleted file mode 100644 index e33caf1..0000000 --- a/src/scripts/install/shell/zsh-plugins.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash - -sudo DEBIAN_FRONTEND=noninteractive apt-get install -y zsh-autosuggestions zsh-syntax-highlighting diff --git a/src/scripts/lib/apt-packages.sh b/src/scripts/lib/apt-packages.sh new file mode 100644 index 0000000..115e8d0 --- /dev/null +++ b/src/scripts/lib/apt-packages.sh @@ -0,0 +1,19 @@ +#!/bin/bash + +# Read package names from a file (one per line; # comments and blanks ignored) and apt install. + +install_apt_packages_from_file() { + local packages_file="$1" + local optional="${2:-}" + + mapfile -t packages < <(grep -v '^#' "$packages_file" | grep -v '^[[:space:]]*$') + if [[ ${#packages[@]} -eq 0 ]]; then + return 0 + fi + + if [[ "$optional" == optional ]]; then + sudo DEBIAN_FRONTEND=noninteractive apt-get install -y "${packages[@]}" || true + else + sudo DEBIAN_FRONTEND=noninteractive apt-get install -y "${packages[@]}" + fi +} diff --git a/src/scripts/lib/env.sh b/src/scripts/lib/env.sh index c251399..343908e 100644 --- a/src/scripts/lib/env.sh +++ b/src/scripts/lib/env.sh @@ -5,6 +5,5 @@ SCRIPTS_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" PROJECT_ROOT="$(cd "$SCRIPTS_DIR/../.." && pwd)" export PROJECT_ROOT -export ERROR_LOG_FILE="${PROJECT_ROOT}/setup_errors.log" export TEMP_DIR="/tmp/ubuntu-setup-$$" mkdir -p "$TEMP_DIR" diff --git a/src/scripts/lib/run.sh b/src/scripts/lib/run.sh index d163420..0f27b72 100644 --- a/src/scripts/lib/run.sh +++ b/src/scripts/lib/run.sh @@ -1,7 +1,5 @@ #!/bin/bash run_script() { - bash "$1" 2>>"$ERROR_LOG_FILE" || { - echo "[$(date '+%Y-%m-%d %H:%M:%S')] Failed: $1" >>"$ERROR_LOG_FILE" - } + bash "$1" || true } diff --git a/src/scripts/master.sh b/src/scripts/master.sh index 62abcb5..07e2b4e 100755 --- a/src/scripts/master.sh +++ b/src/scripts/master.sh @@ -13,13 +13,7 @@ ensure_zshrc_login_safe run_script "$DIR/install/preflight/all.sh" run_script "$DIR/config/system/all.sh" run_script "$DIR/config/home/all.sh" -run_script "$DIR/install/cli/all.sh" -run_script "$DIR/install/media/all.sh" -run_script "$DIR/install/productivity/all.sh" -run_script "$DIR/install/dev/all.sh" +run_script "$DIR/install/all.sh" run_script "$DIR/config/dev/all.sh" -run_script "$DIR/install/security/all.sh" run_script "$DIR/config/security/all.sh" -run_script "$DIR/install/shell/all.sh" -run_script "$DIR/install/post-install/all.sh" run_script "$DIR/config/shell/all.sh" From 3db2df5314c9e98b5cd097303a9a8f8eec935fbc Mon Sep 17 00:00:00 2001 From: Garret Patten Date: Thu, 4 Jun 2026 15:26:04 -0400 Subject: [PATCH 7/8] Configure git credential helper --- scripts/validate-config.sh | 7 +++++++ src/scripts/config/dev/gitconfig.sh | 11 +++++++++-- src/scripts/install/dev/all.sh | 1 + .../install/dev/git-credential-libsecret.sh | 15 +++++++++++++++ src/scripts/install/packages/base.packages | 1 + 5 files changed, 33 insertions(+), 2 deletions(-) create mode 100644 src/scripts/install/dev/git-credential-libsecret.sh diff --git a/scripts/validate-config.sh b/scripts/validate-config.sh index 1027b64..aa6b772 100755 --- a/scripts/validate-config.sh +++ b/scripts/validate-config.sh @@ -33,6 +33,13 @@ check_path projects-personal "$HOME/Projects/personal" check_path hacking-dir "$HOME/Hacking" section 'Git' +credential_helper="/usr/share/doc/git/contrib/credential/libsecret/git-credential-libsecret" +check_path git-credential-libsecret "$credential_helper" +if git config --global --get credential.helper 2>/dev/null | grep -Fq "$credential_helper"; then + pass git-credential-helper "$credential_helper" +else + fail git-credential-helper "git config --global credential.helper $credential_helper" +fi if git config --global user.name >/dev/null 2>&1; then pass git-user-name "$(git config --global user.name)" else diff --git a/src/scripts/config/dev/gitconfig.sh b/src/scripts/config/dev/gitconfig.sh index 2194793..e29cd61 100644 --- a/src/scripts/config/dev/gitconfig.sh +++ b/src/scripts/config/dev/gitconfig.sh @@ -1,7 +1,14 @@ #!/bin/bash -[[ -f "$HOME/.gitconfig" ]] && exit 0 -git config --global credential.helper store +credential_helper="/usr/share/doc/git/contrib/credential/libsecret/git-credential-libsecret" +if [[ -x "$credential_helper" ]]; then + git config --global credential.helper "$credential_helper" +fi + +if [[ -f "$HOME/.gitconfig" ]]; then + exit 0 +fi + git config --global http.postBuffer 157286400 git config --global pack.window 1 git config --global user.email "garret.patten@proton.me" diff --git a/src/scripts/install/dev/all.sh b/src/scripts/install/dev/all.sh index 208435b..5b3543e 100644 --- a/src/scripts/install/dev/all.sh +++ b/src/scripts/install/dev/all.sh @@ -11,6 +11,7 @@ run_script "$DIR/nodesource-nodejs.sh" run_script "$DIR/nvm.sh" install_apt_packages_from_file "$DIR/../packages/lsp.packages" install_apt_packages_from_file "$DIR/../packages/lsp-optional.packages" optional +run_script "$DIR/git-credential-libsecret.sh" install_apt_packages_from_file "$DIR/../packages/dev.packages" run_script "$DIR/rustup.sh" run_script "$DIR/ruby-gems.sh" diff --git a/src/scripts/install/dev/git-credential-libsecret.sh b/src/scripts/install/dev/git-credential-libsecret.sh new file mode 100644 index 0000000..d9ea5ea --- /dev/null +++ b/src/scripts/install/dev/git-credential-libsecret.sh @@ -0,0 +1,15 @@ +#!/bin/bash + +credential_src="/usr/share/doc/git/contrib/credential/libsecret" +credential_bin="$credential_src/git-credential-libsecret" + +if [[ ! -d "$credential_src" ]]; then + exit 0 +fi + +if [[ -x "$credential_bin" ]]; then + exit 0 +fi + +cd "$credential_src" || exit 0 +sudo make diff --git a/src/scripts/install/packages/base.packages b/src/scripts/install/packages/base.packages index 4328e43..a337a9d 100644 --- a/src/scripts/install/packages/base.packages +++ b/src/scripts/install/packages/base.packages @@ -11,6 +11,7 @@ gcc gh htop jq +make libimage-exiftool-perl libsecret-1-0 libsecret-1-dev From 3f2fd43769987584a7f52423a7b65862fc41b3e2 Mon Sep 17 00:00:00 2001 From: Garret Patten Date: Thu, 4 Jun 2026 16:24:38 -0400 Subject: [PATCH 8/8] update: validation --- scripts/validate-config.sh | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/scripts/validate-config.sh b/scripts/validate-config.sh index aa6b772..a96fb5d 100755 --- a/scripts/validate-config.sh +++ b/scripts/validate-config.sh @@ -36,15 +36,10 @@ section 'Git' credential_helper="/usr/share/doc/git/contrib/credential/libsecret/git-credential-libsecret" check_path git-credential-libsecret "$credential_helper" if git config --global --get credential.helper 2>/dev/null | grep -Fq "$credential_helper"; then - pass git-credential-helper "$credential_helper" + pass git-credential-helper 'ready for next commit (name and PAT at push)' else fail git-credential-helper "git config --global credential.helper $credential_helper" fi -if git config --global user.name >/dev/null 2>&1; then - pass git-user-name "$(git config --global user.name)" -else - fail git-user-name 'git config --global user.name' -fi section 'System' if sudo ufw status 2>/dev/null | grep -qi 'Status: active'; then