feat(iso): build end-4 deps in-image, ship end4-pC as default shell
Tests / tests (push) Successful in 2m35s
Tests / tests (push) Successful in 2m35s
- customize_airootfs.sh stages dots-hyprland at /opt, runs ./setup install-deps as a throwaway builder, harvests the built packages into /opt/localrepo so pacstrap resolves them offline - image ships its own [local-aur] (file:///opt/localrepo); CI and localrepo/update.sh keep that copy in sync; .gitignore covers work/, out/ and airootfs/opt/localrepo/ - alvin-install runs ./setup install --skip-alldeps on the target - clone pctrade/end4-pC into /etc/skel/.config/quickshell, patch qsConfig ii -> end4-pC in the staged variables.lua (guarded + idempotent), and restore the fork after setup rsync --delete's ~/.config/quickshell - ship user presets in skel, point fish `q` alias at end4-pC - AGENTS.md: document the fourth package source and new gotchas
This commit is contained in:
@@ -22,9 +22,21 @@ jobs:
|
|||||||
- name: Setup local AUR repo
|
- name: Setup local AUR repo
|
||||||
run: |
|
run: |
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
shopt -s nullglob
|
||||||
mkdir -p /tmp/localrepo
|
mkdir -p /tmp/localrepo
|
||||||
cp localrepo/*.pkg.tar.zst localrepo/local-aur.db* localrepo/local-aur.files* /tmp/localrepo/
|
cp localrepo/*.pkg.tar.zst localrepo/local-aur.db* localrepo/local-aur.files* /tmp/localrepo/
|
||||||
sed -i 's|file:///home/alvin/AlvinArch/localrepo|file:///tmp/localrepo|' pacman.conf
|
sed -i 's|file:///home/alvin/AlvinArch/localrepo|file:///tmp/localrepo|' pacman.conf
|
||||||
|
# The medium needs its own copy: the ISO's /etc/pacman.conf points
|
||||||
|
# [local-aur] at file:///opt/localrepo, which pacstrap reads at
|
||||||
|
# install time to resolve packages that are not in the official repos
|
||||||
|
# (built during the ISO build and harvested there by
|
||||||
|
# airootfs/root/customize_airootfs.sh).
|
||||||
|
mkdir -p airootfs/opt/localrepo
|
||||||
|
shipped=(localrepo/*.pkg.tar.zst localrepo/local-aur.db* localrepo/local-aur.files*)
|
||||||
|
if (( ${#shipped[@]} > 0 )); then
|
||||||
|
cp -L "${shipped[@]}" airootfs/opt/localrepo/
|
||||||
|
fi
|
||||||
|
echo "airootfs/opt/localrepo: $(ls airootfs/opt/localrepo | wc -l) file(s)"
|
||||||
|
|
||||||
- name: Install archiso and dependencies
|
- name: Install archiso and dependencies
|
||||||
run: |
|
run: |
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
# Multi-GB mkarchiso output (see AGENTS.md build command)
|
||||||
|
work/
|
||||||
|
out/
|
||||||
|
|
||||||
|
# In-image copy of localrepo/ — populated by localrepo/update.sh and
|
||||||
|
# .gitea/workflows/build-iso.yaml, shipped as /opt/localrepo on the ISO
|
||||||
|
airootfs/opt/localrepo/
|
||||||
@@ -17,6 +17,9 @@ sudo mkarchiso -v -w work -o out/ .
|
|||||||
./localrepo/update.sh pkg1.pkg.tar.zst # add files, then re-index
|
./localrepo/update.sh pkg1.pkg.tar.zst # add files, then re-index
|
||||||
```
|
```
|
||||||
|
|
||||||
|
`update.sh` also refreshes `airootfs/opt/localrepo/` (the copy that ships on the
|
||||||
|
ISO), so run it after touching `localrepo/` before building.
|
||||||
|
|
||||||
## CI Checks (must pass before merge)
|
## CI Checks (must pass before merge)
|
||||||
|
|
||||||
- **ShellCheck**: all `.sh` files checked with `shellcheck -x -s bash`
|
- **ShellCheck**: all `.sh` files checked with `shellcheck -x -s bash`
|
||||||
@@ -32,6 +35,13 @@ sudo mkarchiso -v -w work -o out/ .
|
|||||||
2. **`localrepo/*.pkg.tar.zst`** — pre-built AUR packages. The `local-aur` repo is configured in `pacman.conf` and picked up by mkarchiso automatically.
|
2. **`localrepo/*.pkg.tar.zst`** — pre-built AUR packages. The `local-aur` repo is configured in `pacman.conf` and picked up by mkarchiso automatically.
|
||||||
3. **`build-end4-deps.sh`** — builds end-4 AUR deps at build time.
|
3. **`build-end4-deps.sh`** — builds end-4 AUR deps at build time.
|
||||||
|
|
||||||
|
There is a **fourth source**: `customize_airootfs.sh` runs end-4's own
|
||||||
|
`./setup install-deps` inside the image (as a throwaway `ii-builder` account),
|
||||||
|
which resolves and compiles everything the dotfiles need (quickshell, MicroTeX,
|
||||||
|
theming, fonts, ...). Those packages are installed in the live system, land in
|
||||||
|
`pkglist.x86_64.txt`, and are harvested into `/opt/localrepo` so pacstrap can
|
||||||
|
install them into the target without the network.
|
||||||
|
|
||||||
**Important**: `localrepo/update.sh` auto-appends new package names to `packages.x86_64`. If you remove a package from `packages.x86_64` that exists in `localrepo/`, it will be re-added on the next `update.sh` run.
|
**Important**: `localrepo/update.sh` auto-appends new package names to `packages.x86_64`. If you remove a package from `packages.x86_64` that exists in `localrepo/`, it will be re-added on the next `update.sh` run.
|
||||||
|
|
||||||
## Key Files
|
## Key Files
|
||||||
@@ -42,14 +52,23 @@ sudo mkarchiso -v -w work -o out/ .
|
|||||||
| `profiledef.sh` | ISO metadata, compression, boot modes |
|
| `profiledef.sh` | ISO metadata, compression, boot modes |
|
||||||
| `pacman.conf` | Repos: cachyos → core → extra → multilib → chaotic-aur → local-aur |
|
| `pacman.conf` | Repos: cachyos → core → extra → multilib → chaotic-aur → local-aur |
|
||||||
| `bootstrap_packages` | Minimal build-time packages (`base`, `arch-install-scripts`) |
|
| `bootstrap_packages` | Minimal build-time packages (`base`, `arch-install-scripts`) |
|
||||||
| `airootfs/root/customize_airootfs.sh` | Runs inside chroot during build: keyrings, oh-my-zsh, lazy.nvim, plugins |
|
| `airootfs/root/customize_airootfs.sh` | Runs inside chroot during build: keyrings, skel dotfiles (incl. end4-pC), qsConfig patch, end-4 `install-deps`, package harvest, uv/font pre-warm |
|
||||||
|
| `airootfs/root/.live-pacman.conf` | `/etc/pacman.conf` of the built image (adds `[local-aur]` = `file:///opt/localrepo`) |
|
||||||
|
| `airootfs/usr/local/bin/alvin-install` | Installer: partitions, pacstrap, user, end-4 dotfiles (`--skip-alldeps`), boot |
|
||||||
| `localrepo/build-end4-deps.sh` | Non-interactive AUR builds for end-4 dependencies |
|
| `localrepo/build-end4-deps.sh` | Non-interactive AUR builds for end-4 dependencies |
|
||||||
| `localrepo/update.sh` | Regenerates localrepo DB + syncs names to packages.x86_64 |
|
| `localrepo/update.sh` | Regenerates localrepo DB, syncs names to packages.x86_64, syncs `airootfs/opt/localrepo/` |
|
||||||
|
|
||||||
## Gotchas
|
## Gotchas
|
||||||
|
|
||||||
- The profile root is the **repo root** (not a `releng/` subdirectory). The CI build-iso workflow uses `mkarchiso -v -w work -o out/ releng` but this is a naming convention — the actual profile files live at the repo root.
|
- The profile root is the **repo root** (not a `releng/` subdirectory). The CI build-iso workflow uses `mkarchiso -v -w work -o out/ releng` but this is a naming convention — the actual profile files live at the repo root.
|
||||||
- `customize_airootfs.sh` clones git repos (oh-my-zsh, lazy.nvim, plugins) into `/etc/skel` during the ISO build. These require network access at build time but make the live ISO work offline.
|
- `customize_airootfs.sh` clones git repos (oh-my-zsh, lazy.nvim, plugins, end-4 dots) into `/etc/skel` and `/opt` during the ISO build. These require network access at build time but make the live ISO work offline.
|
||||||
|
- `customize_airootfs.sh` runs `./setup install-deps -f -s --skip-plasmaintg` as the throwaway user `ii-builder` (end-4's scripts refuse to run as root) and aborts the build if it fails. `--skip-plasmaintg` is deliberate: that optional Firefox widget pulls 410 packages / 526 MiB of KDE.
|
||||||
- The `[local-aur]` repo path in `pacman.conf` (`file:///home/alvin/alvinarch/localrepo`) is for local builds only. The CI does not use this path.
|
- The `[local-aur]` repo path in `pacman.conf` (`file:///home/alvin/alvinarch/localrepo`) is for local builds only. The CI does not use this path.
|
||||||
|
- The **image** ships its own `[local-aur]` at `file:///opt/localrepo` (see `.live-pacman.conf`). It holds `localrepo/` (copied by CI/`update.sh`) plus everything `install-deps` built. pacstrap runs without `-P`, so the target keeps the stock `/etc/pacman.conf`; `alvin-install` strips `[local-aur]` from it anyway as a safety net, because `/opt/localrepo` exists only on the medium.
|
||||||
|
- `alvin-install` runs end-4 with `--skip-alldeps` — dependencies must come from the ISO. It feeds `yes i` to end-4's failure prompt: inside the installer chroot the medium's `/run` is bind-mounted in, so end-4's `systemctl --machine=…@.host --user enable … --now` lines can never work (and `--now` would start services on the live medium). `install_end4_dots` re-applies the enable-only part (bluetooth, ydotool, i2c module) outside the chroot and reports every step end-4 had to skip. If the end-4 step reports "incomplete", check that `hyprctl`/`quickshell`/the venv were resolvable (harvest) before re-running anything.
|
||||||
|
- `/etc/skel/.cache/uv` + `/etc/skel/.local/share/uv/python` are pre-warmed by the build (~460 MB: CPython 3.12 and the pinned wheel cache) so end-4's `uv venv`/`uv pip install` at install time needs no network.
|
||||||
|
- **end4-pC** (`pctrade/end4-pC`) is the default quickshell config: cloned into `/etc/skel/.config/quickshell/end4-pC` at build time, selected by patching `hl.env("qsConfig", "ii")` → `"end4-pC"` in the **staged** `/opt/dots-hyprland/dots/.config/hypr/hyprland/variables.lua` (there is no `hypr/hyprland/` in this repo — `./setup install` copies it to the installed system). `alvin-install` re-copies end4-pC into the user's home *after* `./setup install`, because end-4's installer `rsync --delete`s all of `~/.config/quickshell`.
|
||||||
|
- `airootfs/etc/skel/.config/illogical-impulse/presets/` carries the user's presets (`Laptop.json`, `Personal-Performance.json`, `Personal-Performance.zip`). They embed `/home/alvin/...` paths, so wallpapers/screenshots need fixing up after install.
|
||||||
- End-4 metapackages are built from `localrepo/end4-pkgbuilds/` (quickshell-git, bibata-modern-classic-bin, microtex-git).
|
- End-4 metapackages are built from `localrepo/end4-pkgbuilds/` (quickshell-git, bibata-modern-classic-bin, microtex-git).
|
||||||
- `packages.x86_64` is sorted alphabetically. Keep it sorted when adding/removing entries.
|
- `packages.x86_64` is sorted alphabetically. Keep it sorted when adding/removing entries.
|
||||||
|
- `airootfs/opt/localrepo/` is a build artifact (gitignored) — never commit it.
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ if status is-interactive
|
|||||||
alias celar "printf '\033[2J\033[3J\033[1;1H'"
|
alias celar "printf '\033[2J\033[3J\033[1;1H'"
|
||||||
alias claer "printf '\033[2J\033[3J\033[1;1H'"
|
alias claer "printf '\033[2J\033[3J\033[1;1H'"
|
||||||
alias pamcan pacman
|
alias pamcan pacman
|
||||||
alias q 'qs -c ii'
|
alias q 'qs -c end4-pC'
|
||||||
if test "$TERM" != "linux"
|
if test "$TERM" != "linux"
|
||||||
alias ls 'eza --icons'
|
alias ls 'eza --icons'
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -0,0 +1,677 @@
|
|||||||
|
{
|
||||||
|
"appearance": {
|
||||||
|
"extraBackgroundTint": true,
|
||||||
|
"fakeScreenRounding": 0,
|
||||||
|
"fonts": {
|
||||||
|
"expressive": "Space Grotesk",
|
||||||
|
"iconNerd": "JetBrains Mono NF",
|
||||||
|
"main": "Google Sans Flex",
|
||||||
|
"monospace": "JetBrains Mono NF",
|
||||||
|
"numbers": "Google Sans Flex",
|
||||||
|
"reading": "Readex Pro",
|
||||||
|
"title": "Google Sans Flex"
|
||||||
|
},
|
||||||
|
"palette": {
|
||||||
|
"accentColor": "",
|
||||||
|
"type": "scheme-tonal-spot"
|
||||||
|
},
|
||||||
|
"transparency": {
|
||||||
|
"automatic": true,
|
||||||
|
"backgroundTransparency": 0.11,
|
||||||
|
"contentTransparency": 0.57,
|
||||||
|
"enable": false
|
||||||
|
},
|
||||||
|
"wallpaperTheming": {
|
||||||
|
"enableAppsAndShell": true,
|
||||||
|
"enableQtApps": true,
|
||||||
|
"enableTerminal": true,
|
||||||
|
"terminalGenerationProps": {
|
||||||
|
"forceDarkMode": false,
|
||||||
|
"harmonizeThreshold": 100,
|
||||||
|
"harmony": 0.5,
|
||||||
|
"termFgBoost": 0.35
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"apps": {
|
||||||
|
"bluetooth": "kcmshell6 kcm_bluetooth",
|
||||||
|
"changePassword": "kitty -1 --hold=yes fish -i -c 'passwd'",
|
||||||
|
"manageUser": "kcmshell6 kcm_users",
|
||||||
|
"network": "kcmshell6 kcm_networkmanagement",
|
||||||
|
"networkEthernet": "kcmshell6 kcm_networkmanagement",
|
||||||
|
"taskManager": "plasma-systemmonitor --page-name Processes",
|
||||||
|
"terminal": "kitty -1",
|
||||||
|
"update": "kitty -1 --hold=yes fish -i -c 'pkexec pacman -Syu'",
|
||||||
|
"volumeMixer": "~/.config/hypr/hyprland/scripts/launch_first_available.sh \"pavucontrol-qt\" \"pavucontrol\""
|
||||||
|
},
|
||||||
|
"background": {
|
||||||
|
"blurRadius": 32,
|
||||||
|
"centeredWallpaper": false,
|
||||||
|
"centeredWallpaperColor": "primaryContainer",
|
||||||
|
"centeredWallpaperOnlyWhenLocked": false,
|
||||||
|
"centeredWallpaperShape": "Cookie7Sided",
|
||||||
|
"centeredWallpaperSize": 400,
|
||||||
|
"enableWallpaperPreview": false,
|
||||||
|
"hideWhenFullscreen": true,
|
||||||
|
"lockWall": "",
|
||||||
|
"parallax": {
|
||||||
|
"autoVertical": false,
|
||||||
|
"enableSidebar": true,
|
||||||
|
"enableWorkspace": true,
|
||||||
|
"vertical": false,
|
||||||
|
"widgetsFactor": 1.2,
|
||||||
|
"workspaceZoom": 1.07
|
||||||
|
},
|
||||||
|
"screenList": [],
|
||||||
|
"showBlur": true,
|
||||||
|
"showGrid": true,
|
||||||
|
"showSnapLines": true,
|
||||||
|
"splitRatio": "25",
|
||||||
|
"splitSide": "right",
|
||||||
|
"thumbnailPath": "",
|
||||||
|
"wallpaperAnimation": "random",
|
||||||
|
"wallpaperPath": "/home/alvin/Pictures/Wallpapers/Dynamic-Wallpapers/Dark/japan-street-Dark.png",
|
||||||
|
"widgets": {
|
||||||
|
"blurRadius": 32,
|
||||||
|
"blurWidgets": false,
|
||||||
|
"calendar": {
|
||||||
|
"enable": true,
|
||||||
|
"placementStrategy": "free",
|
||||||
|
"sizeMode": "2x2",
|
||||||
|
"x": 1596,
|
||||||
|
"y": 744,
|
||||||
|
"z": 4
|
||||||
|
},
|
||||||
|
"clock": {
|
||||||
|
"color": "",
|
||||||
|
"cookie": {
|
||||||
|
"aiStyling": false,
|
||||||
|
"constantlyRotate": false,
|
||||||
|
"dateInClock": true,
|
||||||
|
"dateStyle": "bubble",
|
||||||
|
"dialNumberStyle": "full",
|
||||||
|
"hourHandStyle": "hollow",
|
||||||
|
"hourMarks": false,
|
||||||
|
"minuteHandStyle": "medium",
|
||||||
|
"secondHandStyle": "line",
|
||||||
|
"sides": 12,
|
||||||
|
"timeIndicators": true,
|
||||||
|
"useSineCookie": false
|
||||||
|
},
|
||||||
|
"digital": {
|
||||||
|
"adaptiveAlignment": true,
|
||||||
|
"animateChange": true,
|
||||||
|
"font": {
|
||||||
|
"family": "Google Sans Flex",
|
||||||
|
"roundness": 1.1290989771359807,
|
||||||
|
"size": 129.49608904933814,
|
||||||
|
"weight": 595.725165314564,
|
||||||
|
"width": 99.44532190132371
|
||||||
|
},
|
||||||
|
"showDate": true,
|
||||||
|
"vertical": false
|
||||||
|
},
|
||||||
|
"enable": true,
|
||||||
|
"pixel": {
|
||||||
|
"orientation": "vertical"
|
||||||
|
},
|
||||||
|
"placementStrategy": "leastBusy",
|
||||||
|
"quote": {
|
||||||
|
"enable": true,
|
||||||
|
"followClock": false,
|
||||||
|
"text": "Kawaī neko o zenbu tabe chaimasu."
|
||||||
|
},
|
||||||
|
"showOnlyWhenLocked": false,
|
||||||
|
"style": "digital",
|
||||||
|
"styleLocked": "cookie",
|
||||||
|
"x": 1423,
|
||||||
|
"y": 383,
|
||||||
|
"z": 3
|
||||||
|
},
|
||||||
|
"customImage": {
|
||||||
|
"enable": true,
|
||||||
|
"path": "",
|
||||||
|
"placementStrategy": "free",
|
||||||
|
"shape": "Cookie4Sided",
|
||||||
|
"size": 200,
|
||||||
|
"x": 400,
|
||||||
|
"y": 100,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"customText": {
|
||||||
|
"alignment": "center",
|
||||||
|
"color": "",
|
||||||
|
"content": "Hello world",
|
||||||
|
"enable": true,
|
||||||
|
"fontFamily": "Caveat",
|
||||||
|
"fontSize": 72,
|
||||||
|
"placementStrategy": "free",
|
||||||
|
"shadow": true,
|
||||||
|
"x": 400,
|
||||||
|
"y": 300,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"images": {
|
||||||
|
"enable": false,
|
||||||
|
"placementStrategy": "free",
|
||||||
|
"x": 400,
|
||||||
|
"y": 100,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"media": {
|
||||||
|
"backgroundShape": "Cookie4Sided",
|
||||||
|
"enable": true,
|
||||||
|
"placementStrategy": "free",
|
||||||
|
"showControls": true,
|
||||||
|
"showLyrics": false,
|
||||||
|
"showTitles": true,
|
||||||
|
"sizeMode": "1x3",
|
||||||
|
"x": 744,
|
||||||
|
"y": 876,
|
||||||
|
"z": 1
|
||||||
|
},
|
||||||
|
"notes": {
|
||||||
|
"enable": false,
|
||||||
|
"placementStrategy": "free",
|
||||||
|
"x": 400,
|
||||||
|
"y": 100,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"resources": {
|
||||||
|
"enable": false,
|
||||||
|
"placementStrategy": "free",
|
||||||
|
"vertical": false,
|
||||||
|
"x": 400,
|
||||||
|
"y": 100,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"shadow": true,
|
||||||
|
"sticker": {
|
||||||
|
"enable": false,
|
||||||
|
"items": [],
|
||||||
|
"outlineColor": "#ffffff",
|
||||||
|
"outlineWidth": 8,
|
||||||
|
"path": "",
|
||||||
|
"placementStrategy": "free",
|
||||||
|
"rotation": 0,
|
||||||
|
"size": 200,
|
||||||
|
"x": 400,
|
||||||
|
"y": 100,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"timers": {
|
||||||
|
"enable": false,
|
||||||
|
"placementStrategy": "free",
|
||||||
|
"vertical": false,
|
||||||
|
"x": 400,
|
||||||
|
"y": 100,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"todo": {
|
||||||
|
"enable": false,
|
||||||
|
"placementStrategy": "free",
|
||||||
|
"x": 400,
|
||||||
|
"y": 100,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"userCard": {
|
||||||
|
"enable": false,
|
||||||
|
"placementStrategy": "free",
|
||||||
|
"sizeMode": "1x2",
|
||||||
|
"x": 400,
|
||||||
|
"y": 100,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"visualizer": {
|
||||||
|
"colorSource": "theme",
|
||||||
|
"enable": true,
|
||||||
|
"height": 343,
|
||||||
|
"placementStrategy": "free",
|
||||||
|
"ringSize": 380,
|
||||||
|
"sensitivity": 1.65,
|
||||||
|
"style": "mirror",
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"z": -1000
|
||||||
|
},
|
||||||
|
"weather": {
|
||||||
|
"enable": false,
|
||||||
|
"expanded": false,
|
||||||
|
"placementStrategy": "mostBusy",
|
||||||
|
"sizeMode": "1x3",
|
||||||
|
"x": 400,
|
||||||
|
"y": 100,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"worldClock": {
|
||||||
|
"clockCount": 4,
|
||||||
|
"enable": false,
|
||||||
|
"placementStrategy": "free",
|
||||||
|
"sizeMode": "2x2",
|
||||||
|
"timezones": [
|
||||||
|
"Australia/Sydney",
|
||||||
|
"Asia/Tokyo",
|
||||||
|
"Europe/London",
|
||||||
|
"America/New_York"
|
||||||
|
],
|
||||||
|
"x": 400,
|
||||||
|
"y": 100,
|
||||||
|
"z": 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"widgetsLocked": false
|
||||||
|
},
|
||||||
|
"bar": {
|
||||||
|
"autoHide": {
|
||||||
|
"enable": false,
|
||||||
|
"hoverRegionWidth": 2,
|
||||||
|
"pushWindows": false,
|
||||||
|
"showWhenPressingSuper": {
|
||||||
|
"delay": 140,
|
||||||
|
"enable": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"borderless": "transparent",
|
||||||
|
"bottom": false,
|
||||||
|
"centerOnlyReserveFrame": false,
|
||||||
|
"cornerStyle": 3,
|
||||||
|
"divider": {
|
||||||
|
"spacing": 20,
|
||||||
|
"style": "rect"
|
||||||
|
},
|
||||||
|
"dynamicIsland": {
|
||||||
|
"leftWidget": "clockWidget",
|
||||||
|
"rightWidget": "systemIcons",
|
||||||
|
"showMediaControls": false,
|
||||||
|
"visualizerStyle": "wave"
|
||||||
|
},
|
||||||
|
"floatStyleShadow": true,
|
||||||
|
"followFrameColor": false,
|
||||||
|
"frameColor": "secondaryContainer",
|
||||||
|
"frameThickness": 4,
|
||||||
|
"groupColor": "layer1",
|
||||||
|
"indicators": {
|
||||||
|
"notifications": {
|
||||||
|
"showUnreadCount": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"layouts": {
|
||||||
|
"leftLayout": [
|
||||||
|
"leftSidebarButton",
|
||||||
|
"activeWindow",
|
||||||
|
"resources"
|
||||||
|
],
|
||||||
|
"middleLayout": [
|
||||||
|
"media",
|
||||||
|
"clockWidget",
|
||||||
|
"workspaces",
|
||||||
|
"utilButtons",
|
||||||
|
"weatherBar",
|
||||||
|
"batteryIndicator"
|
||||||
|
],
|
||||||
|
"rightLayout": [
|
||||||
|
"sysTray",
|
||||||
|
"updatesCount",
|
||||||
|
"bluetooth",
|
||||||
|
"systemIcons"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"media": {
|
||||||
|
"alwaysVisible": false,
|
||||||
|
"maxWidth": 280,
|
||||||
|
"minWidth": 100,
|
||||||
|
"onlyTitle": false,
|
||||||
|
"preferredPlayer": "",
|
||||||
|
"showLyrics": false
|
||||||
|
},
|
||||||
|
"resources": {
|
||||||
|
"alwaysShowCpu": true,
|
||||||
|
"alwaysShowCpuTemp": true,
|
||||||
|
"alwaysShowDisk": false,
|
||||||
|
"alwaysShowRam": true,
|
||||||
|
"alwaysShowSwap": false,
|
||||||
|
"cpuWarningThreshold": 90,
|
||||||
|
"memoryWarningThreshold": 95,
|
||||||
|
"showValue": true,
|
||||||
|
"style": "outline",
|
||||||
|
"swapWarningThreshold": 85
|
||||||
|
},
|
||||||
|
"screenList": [],
|
||||||
|
"showBackground": true,
|
||||||
|
"showFrame": false,
|
||||||
|
"tooltips": {
|
||||||
|
"clickToShow": false,
|
||||||
|
"enable": true
|
||||||
|
},
|
||||||
|
"topLeftIcon": "spark",
|
||||||
|
"utilButtons": {
|
||||||
|
"isRecording": false,
|
||||||
|
"showColorPicker": false,
|
||||||
|
"showDarkModeToggle": false,
|
||||||
|
"showKeyboardToggle": true,
|
||||||
|
"showMicToggle": true,
|
||||||
|
"showPerformanceProfileToggle": true,
|
||||||
|
"showScreenRecord": false,
|
||||||
|
"showScreenSnip": false,
|
||||||
|
"showWallpaperToggle": false
|
||||||
|
},
|
||||||
|
"verbose": true,
|
||||||
|
"vertical": false,
|
||||||
|
"workspaces": {
|
||||||
|
"alwaysShowNumbers": true,
|
||||||
|
"indicatorStyle": "dot",
|
||||||
|
"monochromeIcons": true,
|
||||||
|
"numberMap": [],
|
||||||
|
"showAppIcons": true,
|
||||||
|
"showNumberDelay": 200,
|
||||||
|
"shown": 10,
|
||||||
|
"useNerdFont": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"calendar": {
|
||||||
|
"locale": "en-GB"
|
||||||
|
},
|
||||||
|
"conflictKiller": {
|
||||||
|
"autoKillNotificationDaemons": true,
|
||||||
|
"autoKillTrays": true
|
||||||
|
},
|
||||||
|
"crosshair": {
|
||||||
|
"code": "0;P;d;1;0l;10;0o;2;1b;0"
|
||||||
|
},
|
||||||
|
"custom": {
|
||||||
|
"colorizeIcon": true,
|
||||||
|
"distroIcon": "google-gemini-symbolic"
|
||||||
|
},
|
||||||
|
"dock": {
|
||||||
|
"enable": true,
|
||||||
|
"height": 60,
|
||||||
|
"hoverRegionHeight": 2,
|
||||||
|
"hoverToReveal": true,
|
||||||
|
"ignoredAppRegexes": [],
|
||||||
|
"monochromeIcons": false,
|
||||||
|
"pinnedApps": [
|
||||||
|
"org.kde.dolphin",
|
||||||
|
"zen"
|
||||||
|
],
|
||||||
|
"pinnedOnStartup": false,
|
||||||
|
"showAppsButton": true,
|
||||||
|
"showBackground": true,
|
||||||
|
"showMedia": true,
|
||||||
|
"showPinButton": true
|
||||||
|
},
|
||||||
|
"hacks": {
|
||||||
|
"arbitraryRaceConditionDelay": 20
|
||||||
|
},
|
||||||
|
"hyprland": {
|
||||||
|
"animations": {
|
||||||
|
"animation": "normal",
|
||||||
|
"enable": true
|
||||||
|
},
|
||||||
|
"decoration": {
|
||||||
|
"activeOpacity": 1,
|
||||||
|
"blur": {
|
||||||
|
"enabled": false,
|
||||||
|
"passes": 3,
|
||||||
|
"size": 1
|
||||||
|
},
|
||||||
|
"inactiveOpacity": 0.95,
|
||||||
|
"rounding": 22,
|
||||||
|
"shadow": {
|
||||||
|
"enabled": true,
|
||||||
|
"range": 4
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"general": {
|
||||||
|
"borderColor": {
|
||||||
|
"activeOpacity": 0.47,
|
||||||
|
"activeRole": "layer0Border",
|
||||||
|
"enable": false,
|
||||||
|
"inactiveOpacity": 0.2,
|
||||||
|
"inactiveRole": "layer0Border"
|
||||||
|
},
|
||||||
|
"borderSize": 1,
|
||||||
|
"gapsIn": 2,
|
||||||
|
"gapsOut": 5
|
||||||
|
},
|
||||||
|
"idle": {
|
||||||
|
"lock": 300,
|
||||||
|
"screenOff": 600,
|
||||||
|
"suspend": 10800
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"interactions": {
|
||||||
|
"deadPixelWorkaround": {
|
||||||
|
"enable": false
|
||||||
|
},
|
||||||
|
"scrolling": {
|
||||||
|
"fasterTouchpadScroll": false,
|
||||||
|
"mouseScrollDeltaThreshold": 120,
|
||||||
|
"mouseScrollFactor": 120,
|
||||||
|
"touchpadScrollFactor": 450
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"launcher": {
|
||||||
|
"pinnedApps": [
|
||||||
|
"org.kde.dolphin",
|
||||||
|
"kitty",
|
||||||
|
"cmake-gui"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"light": {
|
||||||
|
"antiFlashbang": {
|
||||||
|
"enable": false
|
||||||
|
},
|
||||||
|
"night": {
|
||||||
|
"automatic": false,
|
||||||
|
"colorTemperature": 5559,
|
||||||
|
"from": "19:00",
|
||||||
|
"to": "06:30"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"lock": {
|
||||||
|
"blur": {
|
||||||
|
"enable": false,
|
||||||
|
"extraZoom": 1.1,
|
||||||
|
"radius": 100,
|
||||||
|
"size": 20
|
||||||
|
},
|
||||||
|
"centerClock": true,
|
||||||
|
"launchOnStartup": false,
|
||||||
|
"materialShapeChars": true,
|
||||||
|
"security": {
|
||||||
|
"requirePasswordToPower": true,
|
||||||
|
"unlockKeyring": true
|
||||||
|
},
|
||||||
|
"showLockedText": true,
|
||||||
|
"showMedia": true,
|
||||||
|
"showToolbars": true,
|
||||||
|
"showWidgets": false,
|
||||||
|
"useHyprlock": false
|
||||||
|
},
|
||||||
|
"media": {
|
||||||
|
"filterDuplicatePlayers": true
|
||||||
|
},
|
||||||
|
"notifications": {
|
||||||
|
"position": "top_right",
|
||||||
|
"timeout": 7000
|
||||||
|
},
|
||||||
|
"osd": {
|
||||||
|
"timeout": 3000
|
||||||
|
},
|
||||||
|
"osk": {
|
||||||
|
"layout": "qwerty_full",
|
||||||
|
"pinnedOnStartup": false
|
||||||
|
},
|
||||||
|
"overlay": {
|
||||||
|
"clickthroughOpacity": 0.8,
|
||||||
|
"darkenScreen": false,
|
||||||
|
"floatingImage": {
|
||||||
|
"imageSource": "https://media.tenor.com/H5U5bJzj3oAAAAAi/kukuru.gif",
|
||||||
|
"scale": 0.5
|
||||||
|
},
|
||||||
|
"openingZoomAnimation": true
|
||||||
|
},
|
||||||
|
"overview": {
|
||||||
|
"centerIcons": true,
|
||||||
|
"columns": 5,
|
||||||
|
"enable": true,
|
||||||
|
"orderBottomUp": false,
|
||||||
|
"orderRightLeft": false,
|
||||||
|
"rows": 2,
|
||||||
|
"scale": 0.18,
|
||||||
|
"style": "default"
|
||||||
|
},
|
||||||
|
"panelFamily": "ii",
|
||||||
|
"policies": {
|
||||||
|
"ai": 1,
|
||||||
|
"weeb": 1
|
||||||
|
},
|
||||||
|
"profile": {
|
||||||
|
"avatarPath": "/home/alvin/Sync_Documents/",
|
||||||
|
"avatarPicture": "/home/alvin/Sync_Documents/Alvin logo original.png",
|
||||||
|
"descriptionText": "::uptime::",
|
||||||
|
"displayName": "",
|
||||||
|
"onlinePresets": true
|
||||||
|
},
|
||||||
|
"regionSelector": {
|
||||||
|
"annotation": {
|
||||||
|
"useSatty": false
|
||||||
|
},
|
||||||
|
"circle": {
|
||||||
|
"padding": 10,
|
||||||
|
"strokeWidth": 6
|
||||||
|
},
|
||||||
|
"rect": {
|
||||||
|
"showAimLines": true
|
||||||
|
},
|
||||||
|
"targetRegions": {
|
||||||
|
"content": true,
|
||||||
|
"contentRegionOpacity": 0.8,
|
||||||
|
"layers": true,
|
||||||
|
"opacity": 0.3,
|
||||||
|
"selectionPadding": 5,
|
||||||
|
"showLabel": false,
|
||||||
|
"windows": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"resources": {
|
||||||
|
"historyLength": 60,
|
||||||
|
"updateInterval": 3100
|
||||||
|
},
|
||||||
|
"settings": {
|
||||||
|
"borderColor": "layer0Border",
|
||||||
|
"borderSize": 1,
|
||||||
|
"collapsedSections": [],
|
||||||
|
"style": "default"
|
||||||
|
},
|
||||||
|
"sidebar": {
|
||||||
|
"ai": {
|
||||||
|
"textFadeIn": false
|
||||||
|
},
|
||||||
|
"banner": true,
|
||||||
|
"bannerImage": "",
|
||||||
|
"booru": {
|
||||||
|
"allowNsfw": true,
|
||||||
|
"defaultProvider": "yandere",
|
||||||
|
"limit": 20,
|
||||||
|
"zerochan": {
|
||||||
|
"username": "theodorer61"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"bottomGroup": false,
|
||||||
|
"cornerOpen": {
|
||||||
|
"bottom": true,
|
||||||
|
"bottomLeftAction": "sidebarLeftOpen",
|
||||||
|
"bottomRightAction": "sidebarRightOpen",
|
||||||
|
"clickless": false,
|
||||||
|
"clicklessCornerEnd": true,
|
||||||
|
"clicklessCornerVerticalOffset": 1,
|
||||||
|
"cornerRegionHeight": 5,
|
||||||
|
"cornerRegionWidth": 250,
|
||||||
|
"enable": true,
|
||||||
|
"valueScroll": true,
|
||||||
|
"visualize": false
|
||||||
|
},
|
||||||
|
"keepRightSidebarLoaded": false,
|
||||||
|
"media": {
|
||||||
|
"artColors": false,
|
||||||
|
"artShape": "Oval",
|
||||||
|
"blurredBackground": false,
|
||||||
|
"enable": true,
|
||||||
|
"shapeArt": false,
|
||||||
|
"showLyrics": true
|
||||||
|
},
|
||||||
|
"mediaPlayer": false,
|
||||||
|
"quickSliders": {
|
||||||
|
"enable": true,
|
||||||
|
"showBrightness": true,
|
||||||
|
"showMic": true,
|
||||||
|
"showVolume": true
|
||||||
|
},
|
||||||
|
"quickToggles": {
|
||||||
|
"android": {
|
||||||
|
"columns": 6,
|
||||||
|
"toggles": [
|
||||||
|
{
|
||||||
|
"size": 2,
|
||||||
|
"type": "network"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"size": 2,
|
||||||
|
"type": "bluetooth"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"size": 2,
|
||||||
|
"type": "audio"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"size": 1,
|
||||||
|
"type": "idleInhibitor"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"size": 2,
|
||||||
|
"type": "mic"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"size": 1,
|
||||||
|
"type": "nightLight"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"size": 2,
|
||||||
|
"type": "powerProfile"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"style": "android"
|
||||||
|
},
|
||||||
|
"translator": {
|
||||||
|
"delay": 300,
|
||||||
|
"enable": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"tray": {
|
||||||
|
"filterPassive": true,
|
||||||
|
"invertPinnedItems": true,
|
||||||
|
"monochromeIcons": false,
|
||||||
|
"pinnedItems": [
|
||||||
|
"Fcitx"
|
||||||
|
],
|
||||||
|
"showItemId": false
|
||||||
|
},
|
||||||
|
"wallpaperSelector": {
|
||||||
|
"changeInterval": 0,
|
||||||
|
"closeAfterSelection": true,
|
||||||
|
"columns": 4,
|
||||||
|
"liveWallpapersPath": "",
|
||||||
|
"showBlurBackground": false,
|
||||||
|
"showHomePath": true,
|
||||||
|
"showSearchbar": true,
|
||||||
|
"sortMode": "time",
|
||||||
|
"useSystemFileDialog": false,
|
||||||
|
"userPath": "/home/alvin/Pictures/Wallpapers/"
|
||||||
|
},
|
||||||
|
"windows": {
|
||||||
|
"centerTitle": true,
|
||||||
|
"showTitlebar": true
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,676 @@
|
|||||||
|
{
|
||||||
|
"appearance": {
|
||||||
|
"extraBackgroundTint": true,
|
||||||
|
"fakeScreenRounding": 0,
|
||||||
|
"fonts": {
|
||||||
|
"expressive": "Space Grotesk",
|
||||||
|
"iconNerd": "JetBrains Mono NF",
|
||||||
|
"main": "Google Sans Flex",
|
||||||
|
"monospace": "JetBrains Mono NF",
|
||||||
|
"numbers": "Google Sans Flex",
|
||||||
|
"reading": "Readex Pro",
|
||||||
|
"title": "Google Sans Flex"
|
||||||
|
},
|
||||||
|
"palette": {
|
||||||
|
"accentColor": "",
|
||||||
|
"type": "scheme-tonal-spot"
|
||||||
|
},
|
||||||
|
"transparency": {
|
||||||
|
"automatic": true,
|
||||||
|
"backgroundTransparency": 0.11,
|
||||||
|
"contentTransparency": 0.57,
|
||||||
|
"enable": false
|
||||||
|
},
|
||||||
|
"wallpaperTheming": {
|
||||||
|
"enableAppsAndShell": true,
|
||||||
|
"enableQtApps": true,
|
||||||
|
"enableTerminal": true,
|
||||||
|
"terminalGenerationProps": {
|
||||||
|
"forceDarkMode": false,
|
||||||
|
"harmonizeThreshold": 100,
|
||||||
|
"harmony": 0.5,
|
||||||
|
"termFgBoost": 0.35
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"apps": {
|
||||||
|
"bluetooth": "kcmshell6 kcm_bluetooth",
|
||||||
|
"changePassword": "kitty -1 --hold=yes fish -i -c 'passwd'",
|
||||||
|
"manageUser": "kcmshell6 kcm_users",
|
||||||
|
"network": "kcmshell6 kcm_networkmanagement",
|
||||||
|
"networkEthernet": "kcmshell6 kcm_networkmanagement",
|
||||||
|
"taskManager": "plasma-systemmonitor --page-name Processes",
|
||||||
|
"terminal": "kitty -1",
|
||||||
|
"update": "kitty -1 --hold=yes fish -i -c 'pkexec pacman -Syu'",
|
||||||
|
"volumeMixer": "~/.config/hypr/hyprland/scripts/launch_first_available.sh \"pavucontrol-qt\" \"pavucontrol\""
|
||||||
|
},
|
||||||
|
"background": {
|
||||||
|
"blurRadius": 32,
|
||||||
|
"centeredWallpaper": false,
|
||||||
|
"centeredWallpaperColor": "primaryContainer",
|
||||||
|
"centeredWallpaperOnlyWhenLocked": false,
|
||||||
|
"centeredWallpaperShape": "Cookie7Sided",
|
||||||
|
"centeredWallpaperSize": 400,
|
||||||
|
"enableWallpaperPreview": false,
|
||||||
|
"hideWhenFullscreen": true,
|
||||||
|
"lockWall": "",
|
||||||
|
"parallax": {
|
||||||
|
"autoVertical": false,
|
||||||
|
"enableSidebar": true,
|
||||||
|
"enableWorkspace": true,
|
||||||
|
"vertical": false,
|
||||||
|
"widgetsFactor": 1.2,
|
||||||
|
"workspaceZoom": 1.07
|
||||||
|
},
|
||||||
|
"screenList": [],
|
||||||
|
"showBlur": true,
|
||||||
|
"showGrid": true,
|
||||||
|
"showSnapLines": true,
|
||||||
|
"splitRatio": "25",
|
||||||
|
"splitSide": "right",
|
||||||
|
"thumbnailPath": "",
|
||||||
|
"wallpaperAnimation": "random",
|
||||||
|
"wallpaperPath": "/home/alvin/Pictures/Wallpapers/Dynamic-Wallpapers/Dark/japan-street-Dark.png",
|
||||||
|
"widgets": {
|
||||||
|
"blurRadius": 32,
|
||||||
|
"blurWidgets": false,
|
||||||
|
"calendar": {
|
||||||
|
"enable": true,
|
||||||
|
"placementStrategy": "free",
|
||||||
|
"sizeMode": "2x2",
|
||||||
|
"x": 1596,
|
||||||
|
"y": 744,
|
||||||
|
"z": 4
|
||||||
|
},
|
||||||
|
"clock": {
|
||||||
|
"color": "",
|
||||||
|
"cookie": {
|
||||||
|
"aiStyling": false,
|
||||||
|
"constantlyRotate": false,
|
||||||
|
"dateInClock": true,
|
||||||
|
"dateStyle": "bubble",
|
||||||
|
"dialNumberStyle": "full",
|
||||||
|
"hourHandStyle": "hollow",
|
||||||
|
"hourMarks": false,
|
||||||
|
"minuteHandStyle": "medium",
|
||||||
|
"secondHandStyle": "line",
|
||||||
|
"sides": 12,
|
||||||
|
"timeIndicators": true,
|
||||||
|
"useSineCookie": false
|
||||||
|
},
|
||||||
|
"digital": {
|
||||||
|
"adaptiveAlignment": true,
|
||||||
|
"animateChange": true,
|
||||||
|
"font": {
|
||||||
|
"family": "Google Sans Flex",
|
||||||
|
"roundness": 1.1290989771359807,
|
||||||
|
"size": 129.49608904933814,
|
||||||
|
"weight": 350,
|
||||||
|
"width": 99.44532190132371
|
||||||
|
},
|
||||||
|
"showDate": true,
|
||||||
|
"vertical": false
|
||||||
|
},
|
||||||
|
"enable": true,
|
||||||
|
"pixel": {
|
||||||
|
"orientation": "vertical"
|
||||||
|
},
|
||||||
|
"placementStrategy": "leastBusy",
|
||||||
|
"quote": {
|
||||||
|
"enable": true,
|
||||||
|
"followClock": false,
|
||||||
|
"text": "Kawaī neko o zenbu tabe chaimasu."
|
||||||
|
},
|
||||||
|
"showOnlyWhenLocked": false,
|
||||||
|
"style": "digital",
|
||||||
|
"styleLocked": "cookie",
|
||||||
|
"x": 1423,
|
||||||
|
"y": 383,
|
||||||
|
"z": 3
|
||||||
|
},
|
||||||
|
"customImage": {
|
||||||
|
"enable": true,
|
||||||
|
"path": "",
|
||||||
|
"placementStrategy": "free",
|
||||||
|
"shape": "Cookie4Sided",
|
||||||
|
"size": 200,
|
||||||
|
"x": 400,
|
||||||
|
"y": 100,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"customText": {
|
||||||
|
"alignment": "center",
|
||||||
|
"color": "",
|
||||||
|
"content": "Hello world",
|
||||||
|
"enable": true,
|
||||||
|
"fontFamily": "Caveat",
|
||||||
|
"fontSize": 72,
|
||||||
|
"placementStrategy": "free",
|
||||||
|
"shadow": true,
|
||||||
|
"x": 400,
|
||||||
|
"y": 300,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"images": {
|
||||||
|
"enable": false,
|
||||||
|
"placementStrategy": "free",
|
||||||
|
"x": 400,
|
||||||
|
"y": 100,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"media": {
|
||||||
|
"backgroundShape": "Cookie4Sided",
|
||||||
|
"enable": true,
|
||||||
|
"placementStrategy": "free",
|
||||||
|
"showControls": true,
|
||||||
|
"showLyrics": false,
|
||||||
|
"showTitles": true,
|
||||||
|
"sizeMode": "1x3",
|
||||||
|
"x": 744,
|
||||||
|
"y": 876,
|
||||||
|
"z": 1
|
||||||
|
},
|
||||||
|
"notes": {
|
||||||
|
"enable": false,
|
||||||
|
"placementStrategy": "free",
|
||||||
|
"x": 400,
|
||||||
|
"y": 100,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"resources": {
|
||||||
|
"enable": false,
|
||||||
|
"placementStrategy": "free",
|
||||||
|
"vertical": false,
|
||||||
|
"x": 400,
|
||||||
|
"y": 100,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"shadow": true,
|
||||||
|
"sticker": {
|
||||||
|
"enable": false,
|
||||||
|
"items": [],
|
||||||
|
"outlineColor": "#ffffff",
|
||||||
|
"outlineWidth": 8,
|
||||||
|
"path": "",
|
||||||
|
"placementStrategy": "free",
|
||||||
|
"rotation": 0,
|
||||||
|
"size": 200,
|
||||||
|
"x": 400,
|
||||||
|
"y": 100,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"timers": {
|
||||||
|
"enable": false,
|
||||||
|
"placementStrategy": "free",
|
||||||
|
"vertical": false,
|
||||||
|
"x": 400,
|
||||||
|
"y": 100,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"todo": {
|
||||||
|
"enable": false,
|
||||||
|
"placementStrategy": "free",
|
||||||
|
"x": 400,
|
||||||
|
"y": 100,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"userCard": {
|
||||||
|
"enable": false,
|
||||||
|
"placementStrategy": "free",
|
||||||
|
"sizeMode": "1x2",
|
||||||
|
"x": 400,
|
||||||
|
"y": 100,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"visualizer": {
|
||||||
|
"colorSource": "theme",
|
||||||
|
"enable": true,
|
||||||
|
"height": 342,
|
||||||
|
"placementStrategy": "free",
|
||||||
|
"ringSize": 380,
|
||||||
|
"sensitivity": 1.65,
|
||||||
|
"style": "mirror",
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"z": -1000
|
||||||
|
},
|
||||||
|
"weather": {
|
||||||
|
"enable": false,
|
||||||
|
"expanded": false,
|
||||||
|
"placementStrategy": "mostBusy",
|
||||||
|
"sizeMode": "1x3",
|
||||||
|
"x": 400,
|
||||||
|
"y": 100,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"worldClock": {
|
||||||
|
"clockCount": 4,
|
||||||
|
"enable": false,
|
||||||
|
"placementStrategy": "free",
|
||||||
|
"sizeMode": "2x2",
|
||||||
|
"timezones": [
|
||||||
|
"Australia/Sydney",
|
||||||
|
"Asia/Tokyo",
|
||||||
|
"Europe/London",
|
||||||
|
"America/New_York"
|
||||||
|
],
|
||||||
|
"x": 400,
|
||||||
|
"y": 100,
|
||||||
|
"z": 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"widgetsLocked": false
|
||||||
|
},
|
||||||
|
"bar": {
|
||||||
|
"autoHide": {
|
||||||
|
"enable": false,
|
||||||
|
"hoverRegionWidth": 2,
|
||||||
|
"pushWindows": false,
|
||||||
|
"showWhenPressingSuper": {
|
||||||
|
"delay": 140,
|
||||||
|
"enable": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"borderless": "transparent",
|
||||||
|
"bottom": false,
|
||||||
|
"centerOnlyReserveFrame": false,
|
||||||
|
"cornerStyle": 3,
|
||||||
|
"divider": {
|
||||||
|
"spacing": 20,
|
||||||
|
"style": "rect"
|
||||||
|
},
|
||||||
|
"dynamicIsland": {
|
||||||
|
"leftWidget": "clockWidget",
|
||||||
|
"rightWidget": "systemIcons",
|
||||||
|
"showMediaControls": false,
|
||||||
|
"visualizerStyle": "wave"
|
||||||
|
},
|
||||||
|
"floatStyleShadow": true,
|
||||||
|
"followFrameColor": false,
|
||||||
|
"frameColor": "secondaryContainer",
|
||||||
|
"frameThickness": 4,
|
||||||
|
"groupColor": "layer1",
|
||||||
|
"indicators": {
|
||||||
|
"notifications": {
|
||||||
|
"showUnreadCount": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"layouts": {
|
||||||
|
"leftLayout": [
|
||||||
|
"leftSidebarButton",
|
||||||
|
"activeWindow",
|
||||||
|
"resources"
|
||||||
|
],
|
||||||
|
"middleLayout": [
|
||||||
|
"media",
|
||||||
|
"clockWidget",
|
||||||
|
"workspaces",
|
||||||
|
"utilButtons",
|
||||||
|
"weatherBar"
|
||||||
|
],
|
||||||
|
"rightLayout": [
|
||||||
|
"sysTray",
|
||||||
|
"updatesCount",
|
||||||
|
"bluetooth",
|
||||||
|
"systemIcons"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"media": {
|
||||||
|
"alwaysVisible": false,
|
||||||
|
"maxWidth": 280,
|
||||||
|
"minWidth": 100,
|
||||||
|
"onlyTitle": false,
|
||||||
|
"preferredPlayer": "",
|
||||||
|
"showLyrics": false
|
||||||
|
},
|
||||||
|
"resources": {
|
||||||
|
"alwaysShowCpu": true,
|
||||||
|
"alwaysShowCpuTemp": true,
|
||||||
|
"alwaysShowDisk": false,
|
||||||
|
"alwaysShowRam": true,
|
||||||
|
"alwaysShowSwap": false,
|
||||||
|
"cpuWarningThreshold": 90,
|
||||||
|
"memoryWarningThreshold": 95,
|
||||||
|
"showValue": true,
|
||||||
|
"style": "outline",
|
||||||
|
"swapWarningThreshold": 85
|
||||||
|
},
|
||||||
|
"screenList": [],
|
||||||
|
"showBackground": true,
|
||||||
|
"showFrame": false,
|
||||||
|
"tooltips": {
|
||||||
|
"clickToShow": false,
|
||||||
|
"enable": true
|
||||||
|
},
|
||||||
|
"topLeftIcon": "spark",
|
||||||
|
"utilButtons": {
|
||||||
|
"isRecording": false,
|
||||||
|
"showColorPicker": false,
|
||||||
|
"showDarkModeToggle": false,
|
||||||
|
"showKeyboardToggle": false,
|
||||||
|
"showMicToggle": true,
|
||||||
|
"showPerformanceProfileToggle": true,
|
||||||
|
"showScreenRecord": false,
|
||||||
|
"showScreenSnip": false,
|
||||||
|
"showWallpaperToggle": false
|
||||||
|
},
|
||||||
|
"verbose": true,
|
||||||
|
"vertical": false,
|
||||||
|
"workspaces": {
|
||||||
|
"alwaysShowNumbers": true,
|
||||||
|
"indicatorStyle": "dot",
|
||||||
|
"monochromeIcons": true,
|
||||||
|
"numberMap": [],
|
||||||
|
"showAppIcons": true,
|
||||||
|
"showNumberDelay": 200,
|
||||||
|
"shown": 10,
|
||||||
|
"useNerdFont": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"calendar": {
|
||||||
|
"locale": "en-GB"
|
||||||
|
},
|
||||||
|
"conflictKiller": {
|
||||||
|
"autoKillNotificationDaemons": true,
|
||||||
|
"autoKillTrays": true
|
||||||
|
},
|
||||||
|
"crosshair": {
|
||||||
|
"code": "0;P;d;1;0l;10;0o;2;1b;0"
|
||||||
|
},
|
||||||
|
"custom": {
|
||||||
|
"colorizeIcon": true,
|
||||||
|
"distroIcon": "google-gemini-symbolic"
|
||||||
|
},
|
||||||
|
"dock": {
|
||||||
|
"enable": true,
|
||||||
|
"height": 60,
|
||||||
|
"hoverRegionHeight": 2,
|
||||||
|
"hoverToReveal": true,
|
||||||
|
"ignoredAppRegexes": [],
|
||||||
|
"monochromeIcons": false,
|
||||||
|
"pinnedApps": [
|
||||||
|
"org.kde.dolphin",
|
||||||
|
"zen"
|
||||||
|
],
|
||||||
|
"pinnedOnStartup": false,
|
||||||
|
"showAppsButton": true,
|
||||||
|
"showBackground": true,
|
||||||
|
"showMedia": true,
|
||||||
|
"showPinButton": true
|
||||||
|
},
|
||||||
|
"hacks": {
|
||||||
|
"arbitraryRaceConditionDelay": 20
|
||||||
|
},
|
||||||
|
"hyprland": {
|
||||||
|
"animations": {
|
||||||
|
"animation": "normal",
|
||||||
|
"enable": true
|
||||||
|
},
|
||||||
|
"decoration": {
|
||||||
|
"activeOpacity": 1,
|
||||||
|
"blur": {
|
||||||
|
"enabled": false,
|
||||||
|
"passes": 3,
|
||||||
|
"size": 1
|
||||||
|
},
|
||||||
|
"inactiveOpacity": 0.95,
|
||||||
|
"rounding": 22,
|
||||||
|
"shadow": {
|
||||||
|
"enabled": true,
|
||||||
|
"range": 4
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"general": {
|
||||||
|
"borderColor": {
|
||||||
|
"activeOpacity": 0.47,
|
||||||
|
"activeRole": "layer0Border",
|
||||||
|
"enable": false,
|
||||||
|
"inactiveOpacity": 0.2,
|
||||||
|
"inactiveRole": "layer0Border"
|
||||||
|
},
|
||||||
|
"borderSize": 1,
|
||||||
|
"gapsIn": 2,
|
||||||
|
"gapsOut": 5
|
||||||
|
},
|
||||||
|
"idle": {
|
||||||
|
"lock": 300,
|
||||||
|
"screenOff": 600,
|
||||||
|
"suspend": 10800
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"interactions": {
|
||||||
|
"deadPixelWorkaround": {
|
||||||
|
"enable": false
|
||||||
|
},
|
||||||
|
"scrolling": {
|
||||||
|
"fasterTouchpadScroll": false,
|
||||||
|
"mouseScrollDeltaThreshold": 120,
|
||||||
|
"mouseScrollFactor": 120,
|
||||||
|
"touchpadScrollFactor": 450
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"launcher": {
|
||||||
|
"pinnedApps": [
|
||||||
|
"org.kde.dolphin",
|
||||||
|
"kitty",
|
||||||
|
"cmake-gui"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"light": {
|
||||||
|
"antiFlashbang": {
|
||||||
|
"enable": false
|
||||||
|
},
|
||||||
|
"night": {
|
||||||
|
"automatic": false,
|
||||||
|
"colorTemperature": 5559,
|
||||||
|
"from": "19:00",
|
||||||
|
"to": "06:30"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"lock": {
|
||||||
|
"blur": {
|
||||||
|
"enable": false,
|
||||||
|
"extraZoom": 1.1,
|
||||||
|
"radius": 100,
|
||||||
|
"size": 20
|
||||||
|
},
|
||||||
|
"centerClock": true,
|
||||||
|
"launchOnStartup": false,
|
||||||
|
"materialShapeChars": true,
|
||||||
|
"security": {
|
||||||
|
"requirePasswordToPower": true,
|
||||||
|
"unlockKeyring": true
|
||||||
|
},
|
||||||
|
"showLockedText": true,
|
||||||
|
"showMedia": true,
|
||||||
|
"showToolbars": true,
|
||||||
|
"showWidgets": false,
|
||||||
|
"useHyprlock": false
|
||||||
|
},
|
||||||
|
"media": {
|
||||||
|
"filterDuplicatePlayers": true
|
||||||
|
},
|
||||||
|
"notifications": {
|
||||||
|
"position": "top_right",
|
||||||
|
"timeout": 7000
|
||||||
|
},
|
||||||
|
"osd": {
|
||||||
|
"timeout": 3000
|
||||||
|
},
|
||||||
|
"osk": {
|
||||||
|
"layout": "qwerty_full",
|
||||||
|
"pinnedOnStartup": false
|
||||||
|
},
|
||||||
|
"overlay": {
|
||||||
|
"clickthroughOpacity": 0.8,
|
||||||
|
"darkenScreen": false,
|
||||||
|
"floatingImage": {
|
||||||
|
"imageSource": "https://media.tenor.com/H5U5bJzj3oAAAAAi/kukuru.gif",
|
||||||
|
"scale": 0.5
|
||||||
|
},
|
||||||
|
"openingZoomAnimation": true
|
||||||
|
},
|
||||||
|
"overview": {
|
||||||
|
"centerIcons": true,
|
||||||
|
"columns": 5,
|
||||||
|
"enable": true,
|
||||||
|
"orderBottomUp": false,
|
||||||
|
"orderRightLeft": false,
|
||||||
|
"rows": 2,
|
||||||
|
"scale": 0.18,
|
||||||
|
"style": "default"
|
||||||
|
},
|
||||||
|
"panelFamily": "ii",
|
||||||
|
"policies": {
|
||||||
|
"ai": 1,
|
||||||
|
"weeb": 1
|
||||||
|
},
|
||||||
|
"profile": {
|
||||||
|
"avatarPath": "",
|
||||||
|
"avatarPicture": "",
|
||||||
|
"descriptionText": "::uptime::",
|
||||||
|
"displayName": "",
|
||||||
|
"onlinePresets": false
|
||||||
|
},
|
||||||
|
"regionSelector": {
|
||||||
|
"annotation": {
|
||||||
|
"useSatty": false
|
||||||
|
},
|
||||||
|
"circle": {
|
||||||
|
"padding": 10,
|
||||||
|
"strokeWidth": 6
|
||||||
|
},
|
||||||
|
"rect": {
|
||||||
|
"showAimLines": true
|
||||||
|
},
|
||||||
|
"targetRegions": {
|
||||||
|
"content": true,
|
||||||
|
"contentRegionOpacity": 0.8,
|
||||||
|
"layers": true,
|
||||||
|
"opacity": 0.3,
|
||||||
|
"selectionPadding": 5,
|
||||||
|
"showLabel": false,
|
||||||
|
"windows": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"resources": {
|
||||||
|
"historyLength": 60,
|
||||||
|
"updateInterval": 3100
|
||||||
|
},
|
||||||
|
"settings": {
|
||||||
|
"borderColor": "layer0Border",
|
||||||
|
"borderSize": 1,
|
||||||
|
"collapsedSections": [],
|
||||||
|
"style": "default"
|
||||||
|
},
|
||||||
|
"sidebar": {
|
||||||
|
"ai": {
|
||||||
|
"textFadeIn": false
|
||||||
|
},
|
||||||
|
"banner": true,
|
||||||
|
"bannerImage": "",
|
||||||
|
"booru": {
|
||||||
|
"allowNsfw": true,
|
||||||
|
"defaultProvider": "yandere",
|
||||||
|
"limit": 20,
|
||||||
|
"zerochan": {
|
||||||
|
"username": "theodorer61"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"bottomGroup": false,
|
||||||
|
"cornerOpen": {
|
||||||
|
"bottom": true,
|
||||||
|
"bottomLeftAction": "sidebarLeftOpen",
|
||||||
|
"bottomRightAction": "sidebarRightOpen",
|
||||||
|
"clickless": false,
|
||||||
|
"clicklessCornerEnd": true,
|
||||||
|
"clicklessCornerVerticalOffset": 1,
|
||||||
|
"cornerRegionHeight": 5,
|
||||||
|
"cornerRegionWidth": 250,
|
||||||
|
"enable": true,
|
||||||
|
"valueScroll": true,
|
||||||
|
"visualize": false
|
||||||
|
},
|
||||||
|
"keepRightSidebarLoaded": false,
|
||||||
|
"media": {
|
||||||
|
"artColors": false,
|
||||||
|
"artShape": "Oval",
|
||||||
|
"blurredBackground": false,
|
||||||
|
"enable": true,
|
||||||
|
"shapeArt": false,
|
||||||
|
"showLyrics": true
|
||||||
|
},
|
||||||
|
"mediaPlayer": false,
|
||||||
|
"quickSliders": {
|
||||||
|
"enable": true,
|
||||||
|
"showBrightness": true,
|
||||||
|
"showMic": true,
|
||||||
|
"showVolume": true
|
||||||
|
},
|
||||||
|
"quickToggles": {
|
||||||
|
"android": {
|
||||||
|
"columns": 6,
|
||||||
|
"toggles": [
|
||||||
|
{
|
||||||
|
"size": 2,
|
||||||
|
"type": "network"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"size": 2,
|
||||||
|
"type": "bluetooth"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"size": 2,
|
||||||
|
"type": "audio"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"size": 1,
|
||||||
|
"type": "idleInhibitor"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"size": 2,
|
||||||
|
"type": "mic"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"size": 1,
|
||||||
|
"type": "nightLight"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"size": 2,
|
||||||
|
"type": "powerProfile"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"style": "android"
|
||||||
|
},
|
||||||
|
"translator": {
|
||||||
|
"delay": 300,
|
||||||
|
"enable": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"tray": {
|
||||||
|
"filterPassive": true,
|
||||||
|
"invertPinnedItems": true,
|
||||||
|
"monochromeIcons": false,
|
||||||
|
"pinnedItems": [
|
||||||
|
"Fcitx"
|
||||||
|
],
|
||||||
|
"showItemId": false
|
||||||
|
},
|
||||||
|
"wallpaperSelector": {
|
||||||
|
"changeInterval": 0,
|
||||||
|
"closeAfterSelection": true,
|
||||||
|
"columns": 4,
|
||||||
|
"liveWallpapersPath": "",
|
||||||
|
"showBlurBackground": false,
|
||||||
|
"showHomePath": true,
|
||||||
|
"showSearchbar": true,
|
||||||
|
"sortMode": "time",
|
||||||
|
"useSystemFileDialog": false,
|
||||||
|
"userPath": "/home/alvin/Pictures/Wallpapers/"
|
||||||
|
},
|
||||||
|
"windows": {
|
||||||
|
"centerTitle": true,
|
||||||
|
"showTitlebar": true
|
||||||
|
}
|
||||||
|
}
|
||||||
Binary file not shown.
@@ -48,4 +48,13 @@ Include = /etc/pacman.d/cachyos-mirrorlist
|
|||||||
|
|
||||||
[chaotic-aur]
|
[chaotic-aur]
|
||||||
SigLevel = Required DatabaseOptional
|
SigLevel = Required DatabaseOptional
|
||||||
Include = /etc/pacman.d/chaotic-mirrorlist
|
Include = /etc/pacman.d/chaotic-mirrorlist
|
||||||
|
|
||||||
|
[local-aur]
|
||||||
|
# Ships on the medium only: packages built at ISO build time (end-4
|
||||||
|
# dependencies, plus localrepo/). Keeps pacstrap from needing the network for
|
||||||
|
# anything that is not in the official repos. alvin-install strips this whole
|
||||||
|
# section from the target system's pacman.conf, because /opt/localrepo exists
|
||||||
|
# only on the live medium.
|
||||||
|
SigLevel = Optional TrustAll
|
||||||
|
Server = file:///opt/localrepo
|
||||||
|
|||||||
@@ -57,6 +57,181 @@ if [[ ! -d "${NVIM_DATA}/lazy/lazy.nvim" ]]; then
|
|||||||
https://github.com/folke/lazy.nvim.git "${NVIM_DATA}/lazy/lazy.nvim"
|
https://github.com/folke/lazy.nvim.git "${NVIM_DATA}/lazy/lazy.nvim"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# ── end-4 dots-hyprland, staged for alvin-install (avoids a clone at install) ─
|
||||||
|
DOTS_REPO="/opt/dots-hyprland"
|
||||||
|
if [[ ! -d "${DOTS_REPO}/.git" ]]; then
|
||||||
|
echo "[customize] Cloning end-4 dots-hyprland..."
|
||||||
|
git clone --depth=1 https://github.com/end-4/dots-hyprland.git "${DOTS_REPO}"
|
||||||
|
git -C "${DOTS_REPO}" submodule update --init --depth=1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ── end4-pC: the default quickshell config, shipped in skel ──────────────────
|
||||||
|
# pctrade/end4-pC is a fork of the ii shell config. It lives next to ii in
|
||||||
|
# ~/.config/quickshell and does not modify it; which one runs is decided by
|
||||||
|
# qsConfig (patched just below). The repo has no submodules.
|
||||||
|
if [[ ! -d "${SKEL}/.config/quickshell/end4-pC" ]]; then
|
||||||
|
echo "[customize] Cloning end4-pC quickshell config into skel..."
|
||||||
|
git clone --depth=1 https://github.com/pctrade/end4-pC.git \
|
||||||
|
"${SKEL}/.config/quickshell/end4-pC"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ── Default quickshell config: ii -> end4-pC ─────────────────────────────────
|
||||||
|
# alvin-install copies this staged repo onto the target and runs `./setup
|
||||||
|
# install`, whose rsync writes hypr/hyprland/variables.lua into the user's
|
||||||
|
# home - so patching the staged copy is what sets qsConfig on the installed
|
||||||
|
# system. Re-running is a no-op; anything other than ii/end4-pC aborts.
|
||||||
|
VARIABLES_LUA="${DOTS_REPO}/dots/.config/hypr/hyprland/variables.lua"
|
||||||
|
if grep -Fq 'hl.env("qsConfig", "ii")' "${VARIABLES_LUA}"; then
|
||||||
|
echo "[customize] Setting qsConfig to end4-pC..."
|
||||||
|
sed -i 's|hl\.env("qsConfig", "ii")|hl.env("qsConfig", "end4-pC")|' "${VARIABLES_LUA}"
|
||||||
|
fi
|
||||||
|
if ! grep -Fq 'hl.env("qsConfig", "end4-pC")' "${VARIABLES_LUA}"; then
|
||||||
|
echo "[customize] qsConfig is neither ii nor end4-pC in ${VARIABLES_LUA}" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# Pre-install end-4 dependencies into the image (network heavy, once per ISO)
|
||||||
|
# ============================================================================
|
||||||
|
# ./setup install-deps resolves and *builds* every AUR/source dependency the
|
||||||
|
# dotfiles need (quickshell, MicroTeX, theming, fonts, ...). Doing it here lets
|
||||||
|
# alvin-install run its end-4 step with --skip-alldeps, so an install only
|
||||||
|
# copies files - no AUR clones, no makepkg, no dependency resolution.
|
||||||
|
#
|
||||||
|
# The script refuses to run as root, hence the throwaway builder account.
|
||||||
|
# ============================================================================
|
||||||
|
BUILD_USER="ii-builder"
|
||||||
|
|
||||||
|
if ! id -u "${BUILD_USER}" &>/dev/null; then
|
||||||
|
useradd -m -u 1500 "${BUILD_USER}"
|
||||||
|
fi
|
||||||
|
echo "${BUILD_USER} ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/99-ii-builder
|
||||||
|
chmod 440 /etc/sudoers.d/99-ii-builder
|
||||||
|
|
||||||
|
# makepkg writes src/, pkg/ and *.pkg.tar.zst into the PKGBUILD directories,
|
||||||
|
# so the tree must be owned by the account that runs it.
|
||||||
|
chown -R "${BUILD_USER}:${BUILD_USER}" "${DOTS_REPO}"
|
||||||
|
|
||||||
|
# -f: never prompt (ask=false); -s: skip "pacman -Syu";
|
||||||
|
# --skip-plasmaintg: optional Firefox widget that pulls 410 pkgs / 526 MiB of
|
||||||
|
# KDE packages onto a non-KDE system;
|
||||||
|
# stdin: answer end-4's x() failure prompt with "e", so a failed command
|
||||||
|
# aborts the build instead of blocking forever without a TTY.
|
||||||
|
# shellcheck disable=SC2024 # the redirect is meant for the child, not sudo
|
||||||
|
if ! sudo -u "${BUILD_USER}" env HOME="/home/${BUILD_USER}" \
|
||||||
|
GIT_TERMINAL_PROMPT=0 \
|
||||||
|
bash -c "cd ${DOTS_REPO} && ./setup install-deps -f -s --skip-plasmaintg" \
|
||||||
|
< <(yes e); then
|
||||||
|
echo "[customize] end-4 ./setup install-deps failed" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ── Harvest the packages install-deps just built into the in-image local repo ─
|
||||||
|
# The live /etc/pacman.conf points [local-aur] at /opt/localrepo; without the
|
||||||
|
# harvested copies pacstrap cannot resolve these packages at install time and
|
||||||
|
# would silently drop them from the target system.
|
||||||
|
mkdir -p /opt/localrepo
|
||||||
|
shopt -s nullglob
|
||||||
|
|
||||||
|
# <name> <version> from a package's embedded .PKGINFO (update.sh does the same)
|
||||||
|
pkg_meta() {
|
||||||
|
tar -xOf "$1" .PKGINFO 2>/dev/null |
|
||||||
|
awk -F' = ' '/^pkgname = /{n=$2} /^pkgver = /{v=$2} END{print n, v}'
|
||||||
|
}
|
||||||
|
|
||||||
|
mapfile -d '' -t built_pkgs < <(
|
||||||
|
find "${DOTS_REPO}" "/home/${BUILD_USER}/.cache/yay" \
|
||||||
|
-name '*.pkg.tar.zst' -print0 2>/dev/null
|
||||||
|
)
|
||||||
|
|
||||||
|
declare -A built_file=() built_ver=()
|
||||||
|
for p in "${built_pkgs[@]}"; do
|
||||||
|
read -r n v < <(pkg_meta "$p")
|
||||||
|
[[ -n "${n:-}" && -n "${v:-}" ]] || continue
|
||||||
|
built_file["$n"]="$p"
|
||||||
|
built_ver["$n"]="$v"
|
||||||
|
done
|
||||||
|
|
||||||
|
# One entry per package name, and the entry must be the version the image
|
||||||
|
# actually installed - a stale copy with the same name but another version
|
||||||
|
# would let pacstrap install something else than what was tested.
|
||||||
|
for existing in /opt/localrepo/*.pkg.tar.zst; do
|
||||||
|
[[ -e "$existing" ]] || continue
|
||||||
|
read -r n v < <(pkg_meta "$existing")
|
||||||
|
[[ -n "${n:-}" ]] || continue
|
||||||
|
if [[ -n "${built_ver[$n]:-}" ]]; then
|
||||||
|
echo "[customize] Replacing localrepo ${n} ${v} with built ${built_ver[$n]}"
|
||||||
|
rm -f "$existing"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if ((${#built_file[@]} > 0)); then
|
||||||
|
echo "[customize] Harvesting ${#built_file[@]} package(s) into /opt/localrepo"
|
||||||
|
cp -f -- "${built_file[@]}" /opt/localrepo/
|
||||||
|
# makepkg -Afsi leaves its archives next to the PKGBUILD. They are already
|
||||||
|
# harvested (and installed in this image); keeping them in the dots tree
|
||||||
|
# would ship a second copy inside /opt/dots-hyprland, which alvin-install
|
||||||
|
# copies to ~/.dots-hyprland on every installed system.
|
||||||
|
find "${DOTS_REPO}" -type f -name '*.pkg.tar.zst' -delete
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Rebuild the repo database (CI/update.sh ship a pre-built one alongside the
|
||||||
|
# packages) and refresh the live system's copy of it. No network needed: the
|
||||||
|
# remote repos were synced during pacstrap.
|
||||||
|
local_pkgs=(/opt/localrepo/*.pkg.tar.zst)
|
||||||
|
if ((${#local_pkgs[@]} > 0)); then
|
||||||
|
echo "[customize] Rebuilding local-aur db (${#local_pkgs[@]} packages)..."
|
||||||
|
repo-add -R /opt/localrepo/local-aur.db.tar.gz "${local_pkgs[@]}"
|
||||||
|
mkdir -p /var/lib/pacman/sync
|
||||||
|
cp -fL /opt/localrepo/local-aur.db /var/lib/pacman/sync/local-aur.db
|
||||||
|
if [[ -f /opt/localrepo/local-aur.files ]]; then
|
||||||
|
cp -fL /opt/localrepo/local-aur.files /var/lib/pacman/sync/local-aur.files
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ── makepkg leftovers + throwaway account do not belong in the ISO ──────────
|
||||||
|
if [[ -d "${DOTS_REPO}/sdata/dist-arch" ]]; then
|
||||||
|
find "${DOTS_REPO}/sdata/dist-arch" -mindepth 2 -maxdepth 2 -type d \
|
||||||
|
\( -name src -o -name pkg \) -prune -exec rm -rf {} +
|
||||||
|
fi
|
||||||
|
rm -f /etc/sudoers.d/99-ii-builder
|
||||||
|
if ! userdel -r "${BUILD_USER}" 2>/dev/null; then
|
||||||
|
rm -rf "/home/${BUILD_USER:?}"
|
||||||
|
userdel "${BUILD_USER}"
|
||||||
|
fi
|
||||||
|
chown -R root:root "${DOTS_REPO}"
|
||||||
|
|
||||||
|
# ── Google Sans Flex into skel: install_google_sans_flex() early-returns once
|
||||||
|
# fc-list sees the font, so the install step needs no network ──────────────
|
||||||
|
FONT_DIR="${SKEL}/.local/share/fonts/illogical-impulse-google-sans-flex"
|
||||||
|
if [[ ! -f "${FONT_DIR}/.git/HEAD" ]]; then
|
||||||
|
echo "[customize] Pre-installing Google Sans Flex into skel..."
|
||||||
|
rm -rf "${FONT_DIR}"
|
||||||
|
git clone --depth=1 --recurse-submodules --shallow-submodules \
|
||||||
|
https://github.com/end-4/google-sans-flex "${FONT_DIR}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ── uv into skel: CPython 3.12 + the end-4 requirements wheel cache ──────────
|
||||||
|
# install-python-packages() runs `uv venv -p 3.12` and `uv pip install -r ...`
|
||||||
|
# during setup. Arch has no python312 package (uv would download one) and the
|
||||||
|
# pinned requirements are ~250 MiB of wheels, so warm both into skel: the venv
|
||||||
|
# is then created and filled straight from the image.
|
||||||
|
if command -v uv &>/dev/null; then
|
||||||
|
echo "[customize] Pre-warming uv (CPython 3.12 + requirements cache)..."
|
||||||
|
warm_venv="/tmp/uv-warm-venv"
|
||||||
|
rm -rf "${warm_venv}"
|
||||||
|
UV_CACHE_DIR="${SKEL}/.cache/uv" \
|
||||||
|
UV_PYTHON_INSTALL_DIR="${SKEL}/.local/share/uv/python" \
|
||||||
|
uv venv -p 3.12 "${warm_venv}"
|
||||||
|
UV_CACHE_DIR="${SKEL}/.cache/uv" \
|
||||||
|
UV_PYTHON_INSTALL_DIR="${SKEL}/.local/share/uv/python" \
|
||||||
|
uv pip install --python "${warm_venv}/bin/python" \
|
||||||
|
-r "${DOTS_REPO}/sdata/uv/requirements.txt"
|
||||||
|
rm -rf "${warm_venv}"
|
||||||
|
else
|
||||||
|
echo "[customize] uv not found - skipping python/wheel pre-warm."
|
||||||
|
fi
|
||||||
|
|
||||||
# ── Fish: ensure default shell is set for the live user ──────────────────────
|
# ── Fish: ensure default shell is set for the live user ──────────────────────
|
||||||
# The live user (usually 'archlinux' or 'root') gets fish as default shell
|
# The live user (usually 'archlinux' or 'root') gets fish as default shell
|
||||||
if command -v fish &>/dev/null; then
|
if command -v fish &>/dev/null; then
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ log() { echo "[$(date '+%H:%M:%S')] $*" >> "$LOG"; }
|
|||||||
|
|
||||||
cleanup() {
|
cleanup() {
|
||||||
set +e
|
set +e
|
||||||
|
rm -f "${TARGET}/etc/sudoers.d/99-end4-install" 2>/dev/null
|
||||||
umount -R "$TARGET" 2>/dev/null
|
umount -R "$TARGET" 2>/dev/null
|
||||||
cryptsetup close cryptroot 2>/dev/null
|
cryptsetup close cryptroot 2>/dev/null
|
||||||
true
|
true
|
||||||
@@ -443,7 +444,11 @@ Include = /etc/pacman.d/cachyos-mirrorlist
|
|||||||
REPO
|
REPO
|
||||||
fi
|
fi
|
||||||
|
|
||||||
sed -i '/\[local-aur\]/,/Include/d' "${TARGET}/etc/pacman.conf" 2>/dev/null || true
|
# [local-aur] lives only on the live medium (file:///opt/localrepo). The
|
||||||
|
# target's pacman.conf does not normally contain it - pacstrap is run
|
||||||
|
# without -P, so it keeps the stock file shipped by the pacman package -
|
||||||
|
# but drop it anyway in case that ever changes.
|
||||||
|
sed -i '/^\[local-aur\]$/,/^$/d' "${TARGET}/etc/pacman.conf" 2>/dev/null || true
|
||||||
|
|
||||||
ok "CachyOS repo configured."
|
ok "CachyOS repo configured."
|
||||||
}
|
}
|
||||||
@@ -520,6 +525,183 @@ install_git() {
|
|||||||
ok "Git configured for ${USERNAME}."
|
ok "Git configured for ${USERNAME}."
|
||||||
}
|
}
|
||||||
|
|
||||||
|
install_end4_dots() {
|
||||||
|
if [[ ! -d /opt/dots-hyprland ]]; then
|
||||||
|
warn "No staged dots-hyprland at /opt/dots-hyprland — skipping end-4 dotfiles."
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
info "Installing end-4 dotfiles (this may take a while)..."
|
||||||
|
|
||||||
|
local home_in_target="/home/${USERNAME}"
|
||||||
|
local repo_in_target="${home_in_target}/.dots-hyprland"
|
||||||
|
local repo_on_host="${TARGET}${repo_in_target}"
|
||||||
|
local dots_ok=true
|
||||||
|
local setups_done=true
|
||||||
|
|
||||||
|
cp -a /opt/dots-hyprland "$repo_on_host"
|
||||||
|
chown -R "${USERNAME}:${USERNAME}" "$repo_on_host"
|
||||||
|
|
||||||
|
echo "${USERNAME} ALL=(ALL) NOPASSWD:ALL" > "${TARGET}/etc/sudoers.d/99-end4-install"
|
||||||
|
chmod 440 "${TARGET}/etc/sudoers.d/99-end4-install"
|
||||||
|
|
||||||
|
# Everything appended to $LOG from here belongs to this attempt; used
|
||||||
|
# further down to report which steps end-4 had to skip.
|
||||||
|
local log_mark=0
|
||||||
|
if [[ -f "$LOG" ]]; then
|
||||||
|
log_mark=$(wc -l < "$LOG")
|
||||||
|
fi
|
||||||
|
|
||||||
|
# stdin feeds "i" to end-4's x() [R/e:i] failure prompt, which otherwise
|
||||||
|
# blocks forever on a TTY whose prompt text is redirected to $LOG.
|
||||||
|
# Its systemd lines cannot work from inside this chroot: the medium's /run
|
||||||
|
# is bind-mounted in, so `systemctl --machine=…@.host --user enable … --now`
|
||||||
|
# has no target session (and --now would start services on the live medium
|
||||||
|
# anyway) - they fail on every install. "i" lets the run carry on with the
|
||||||
|
# venv, groups and config sync instead of aborting at the first such line;
|
||||||
|
# the usable part of that step is re-applied below and every skip is
|
||||||
|
# reported afterwards.
|
||||||
|
# --skip-alldeps: every dependency was already installed at ISO build time
|
||||||
|
# (customize_airootfs.sh runs ./setup install-deps), so this only copies
|
||||||
|
# configs, sets up services and builds the python venv from the warm cache.
|
||||||
|
if ! arch-chroot "$TARGET" runuser -u "$USERNAME" -- \
|
||||||
|
env HOME="$home_in_target" bash -c \
|
||||||
|
"cd ${repo_in_target} && ./setup install -f -s --skip-alldeps" \
|
||||||
|
< <(yes i) >>"$LOG" 2>&1; then
|
||||||
|
warn "end-4 setup failed, retrying files only (see $LOG)."
|
||||||
|
setups_done=false
|
||||||
|
arch-chroot "$TARGET" runuser -u "$USERNAME" -- \
|
||||||
|
env HOME="$home_in_target" bash -c \
|
||||||
|
"cd ${repo_in_target} && ./setup install -f -s --skip-alldeps --skip-allsetups" \
|
||||||
|
< <(yes i) >>"$LOG" 2>&1 || dots_ok=false
|
||||||
|
fi
|
||||||
|
|
||||||
|
rm -f "${TARGET}/etc/sudoers.d/99-end4-install"
|
||||||
|
|
||||||
|
if ! arch-chroot "$TARGET" id -nG "$USERNAME" | grep -qw input; then
|
||||||
|
arch-chroot "$TARGET" groupadd -f i2c
|
||||||
|
arch-chroot "$TARGET" usermod -aG video,i2c,input "$USERNAME"
|
||||||
|
warn "end-4 group setup was missing and has been applied."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ── steps end-4 cannot take from inside the chroot ───────────────────────
|
||||||
|
# `enable` alone is a pure file operation and needs no running session, so
|
||||||
|
# redo those here - without --now, since the target is not booted yet.
|
||||||
|
local mods_conf="${TARGET}/etc/modules-load.d/i2c-dev.conf"
|
||||||
|
if [[ ! -f "$mods_conf" ]]; then
|
||||||
|
mkdir -p "$(dirname "$mods_conf")"
|
||||||
|
echo i2c-dev > "$mods_conf"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -f "${TARGET}/usr/lib/systemd/system/bluetooth.service" ]]; then
|
||||||
|
arch-chroot "$TARGET" systemctl enable bluetooth.service >>"$LOG" 2>&1 \
|
||||||
|
|| warn "Could not enable bluetooth.service (see $LOG)."
|
||||||
|
fi
|
||||||
|
if [[ -f "${TARGET}/usr/lib/systemd/user/ydotool.service" ]]; then
|
||||||
|
arch-chroot "$TARGET" runuser -u "$USERNAME" -- env HOME="$home_in_target" \
|
||||||
|
systemctl --user enable ydotool.service >>"$LOG" 2>&1 \
|
||||||
|
|| warn "Could not enable ydotool.service for ${USERNAME} (see $LOG)."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Everything end-4 answered "i" to. systemctl/gsettings are the lines known
|
||||||
|
# to be unusable in this chroot; anything else it had to skip is worth
|
||||||
|
# telling the user about.
|
||||||
|
local -a ignored=()
|
||||||
|
if ((log_mark > 0)); then
|
||||||
|
mapfile -t ignored < <(
|
||||||
|
sed -n "$((log_mark + 1)),\$p" "$LOG" | sed $'s/\x1b\\[[0-9;]*m//g' |
|
||||||
|
sed -n 's/^.*Command "\(.*\)" has failed but ignored by user\..*$/\1/p'
|
||||||
|
)
|
||||||
|
fi
|
||||||
|
if ((${#ignored[@]} > 0)); then
|
||||||
|
log "end-4 skipped ${#ignored[@]} step(s): ${ignored[*]}"
|
||||||
|
local step
|
||||||
|
local -a skipped=()
|
||||||
|
for step in "${ignored[@]}"; do
|
||||||
|
case "$step" in
|
||||||
|
*systemctl* | *gsettings*) ;;
|
||||||
|
*) skipped+=("$step") ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
if ((${#skipped[@]} > 0)); then
|
||||||
|
warn "end-4 had to skip: ${skipped[*]} (see $LOG)"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
if ! $setups_done; then
|
||||||
|
warn "end-4 setup did not complete — rerun as ${USERNAME}: cd ~/.dots-hyprland && ./setup install-setups"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# end-4's install step rsync --delete's the whole ~/.config/quickshell
|
||||||
|
# directory (sdata/subcmd-install/3.files-legacy.sh), which drops the
|
||||||
|
# end4-pC fork skel put into the user's home - restore it afterwards.
|
||||||
|
local fork_src="/etc/skel/.config/quickshell/end4-pC"
|
||||||
|
local fork_dst="${TARGET}${home_in_target}/.config/quickshell/end4-pC"
|
||||||
|
if [[ -d "$fork_src" ]]; then
|
||||||
|
mkdir -p "$(dirname "$fork_dst")"
|
||||||
|
rm -rf "$fork_dst"
|
||||||
|
cp -a "$fork_src" "$fork_dst"
|
||||||
|
chown -R "${USERNAME}:${USERNAME}" "$fork_dst"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Same for fish: end-4 syncs ~/.config/fish with rsync --delete, keeping
|
||||||
|
# only what upstream ships (auto-Hypr.fish, config.fish, fish_variables),
|
||||||
|
# which drops skel's extras (fisher/nvm functions, completions,
|
||||||
|
# fish_plugins) and restores its own `alias q 'qs -c ii'`. The default
|
||||||
|
# quickshell config on this ISO is end4-pC, so put the extras back and
|
||||||
|
# repoint that one alias.
|
||||||
|
local fish_src="/etc/skel/.config/fish"
|
||||||
|
local fish_dst="${TARGET}${home_in_target}/.config/fish"
|
||||||
|
if [[ -d "$fish_src" && -d "$fish_dst" ]]; then
|
||||||
|
rsync -a --exclude config.fish --exclude fish_variables \
|
||||||
|
"$fish_src/" "$fish_dst/"
|
||||||
|
if [[ -f "${fish_dst}/config.fish" ]]; then
|
||||||
|
sed -i "s/alias q 'qs -c ii'/alias q 'qs -c end4-pC'/" "${fish_dst}/config.fish"
|
||||||
|
grep -qF "alias q 'qs -c end4-pC'" "${fish_dst}/config.fish" \
|
||||||
|
|| warn "fish 'q' alias still points at the upstream ii config (see $LOG)."
|
||||||
|
fi
|
||||||
|
chown -R "${USERNAME}:${USERNAME}" "$fish_dst"
|
||||||
|
fi
|
||||||
|
|
||||||
|
local configs_ok=true
|
||||||
|
[[ -e "${TARGET}${home_in_target}/.config/hypr/hyprland.lua" \
|
||||||
|
&& -d "${TARGET}${home_in_target}/.config/quickshell/ii" \
|
||||||
|
&& -d "${TARGET}${home_in_target}/.config/quickshell/end4-pC" ]] || configs_ok=false
|
||||||
|
# Files alone are not enough: with --skip-alldeps the dependencies must
|
||||||
|
# have come from the ISO. hyprland and quickshell are installed at ISO
|
||||||
|
# build time, so their binaries missing here means pacstrap dropped them
|
||||||
|
# (they were not resolvable in the live repos). The venv is created from
|
||||||
|
# the image's uv cache at install time, so a missing python means the
|
||||||
|
# python step of end-4's setup never got to run.
|
||||||
|
if $configs_ok; then
|
||||||
|
[[ -x "${TARGET}/usr/bin/hyprctl" && -x "${TARGET}/usr/bin/quickshell" ]] \
|
||||||
|
|| configs_ok=false
|
||||||
|
[[ -x "${TARGET}${home_in_target}/.local/state/quickshell/.venv/bin/python" ]] \
|
||||||
|
|| configs_ok=false
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -d /etc/skel/.config/hypr/custom ]]; then
|
||||||
|
cp -rfT /etc/skel/.config/hypr/custom "${TARGET}${home_in_target}/.config/hypr/custom"
|
||||||
|
chown -R "${USERNAME}:${USERNAME}" "${TARGET}${home_in_target}/.config/hypr/custom"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Presets ship with absolute paths from the build machine; repoint them at
|
||||||
|
# the home that was just created (the images they name are not shipped).
|
||||||
|
local presets="${TARGET}${home_in_target}/.config/illogical-impulse/presets"
|
||||||
|
local preset
|
||||||
|
for preset in "$presets"/*.json; do
|
||||||
|
[[ -f "$preset" ]] || continue
|
||||||
|
sed -i "s|/home/alvin/|/home/${USERNAME}/|g" "$preset"
|
||||||
|
done
|
||||||
|
|
||||||
|
if $dots_ok && $configs_ok; then
|
||||||
|
log "end-4 dotfiles installed for ${USERNAME} (setups_done=${setups_done} skipped=${#ignored[@]})."
|
||||||
|
ok "end-4 dotfiles installed."
|
||||||
|
else
|
||||||
|
log "end-4 dotfiles incomplete for ${USERNAME} (setup_exit_ok=${dots_ok} configs=${configs_ok} setups=${setups_done} skipped=${#ignored[@]})."
|
||||||
|
warn "end-4 dotfiles incomplete (see $LOG) — as ${USERNAME}, run: cd ~/.dots-hyprland && ./setup install"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
install_mkinitcpio() {
|
install_mkinitcpio() {
|
||||||
info "Generating initramfs..."
|
info "Generating initramfs..."
|
||||||
|
|
||||||
@@ -597,6 +779,7 @@ main() {
|
|||||||
install_network
|
install_network
|
||||||
install_user
|
install_user
|
||||||
install_git
|
install_git
|
||||||
|
install_end4_dots
|
||||||
install_mkinitcpio
|
install_mkinitcpio
|
||||||
install_bootloader
|
install_bootloader
|
||||||
install_cleanup
|
install_cleanup
|
||||||
|
|||||||
@@ -22,11 +22,26 @@ mapfile -t pkgs < <(find "${repo_dir}" -maxdepth 1 -name '*.pkg.tar.zst' -print
|
|||||||
|
|
||||||
if [[ ${#pkgs[@]} -eq 0 ]]; then
|
if [[ ${#pkgs[@]} -eq 0 ]]; then
|
||||||
echo "No .pkg.tar.zst files in ${repo_dir}" >&2
|
echo "No .pkg.tar.zst files in ${repo_dir}" >&2
|
||||||
|
# keep the medium's copy honest too - an emptied localrepo/ must not
|
||||||
|
# leave the previous packages shipping on the next build
|
||||||
|
rm -rf "${profile_dir}/airootfs/opt/localrepo"
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
repo-add -R "${repo_dir}/${repo_name}.db.tar.gz" "${pkgs[@]}"
|
repo-add -R "${repo_dir}/${repo_name}.db.tar.gz" "${pkgs[@]}"
|
||||||
|
|
||||||
|
# Sync the medium's copy: the ISO ships its own [local-aur] at
|
||||||
|
# airootfs/opt/localrepo (pacman.conf on the live system points there, and
|
||||||
|
# pacstrap resolves these packages from it at install time).
|
||||||
|
img_repo="${profile_dir}/airootfs/opt/localrepo"
|
||||||
|
mkdir -p "${img_repo}"
|
||||||
|
rm -f "${img_repo}"/*.pkg.tar.zst "${img_repo}/${repo_name}".db \
|
||||||
|
"${img_repo}/${repo_name}".db.tar.gz "${img_repo}/${repo_name}".files \
|
||||||
|
"${img_repo}/${repo_name}".files.tar.gz
|
||||||
|
cp -f "${pkgs[@]}" "${img_repo}/"
|
||||||
|
cp -fL "${repo_dir}/${repo_name}".db* "${repo_dir}/${repo_name}".files* "${img_repo}/"
|
||||||
|
echo "Medium copy ready: ${img_repo}"
|
||||||
|
|
||||||
new_names=()
|
new_names=()
|
||||||
for p in "${pkgs[@]}"; do
|
for p in "${pkgs[@]}"; do
|
||||||
name=$(tar -xOf "${p}" .PKGINFO | sed -n 's/^pkgname = //p' | head -1)
|
name=$(tar -xOf "${p}" .PKGINFO | sed -n 's/^pkgname = //p' | head -1)
|
||||||
|
|||||||
Reference in New Issue
Block a user