Skip to content

Commit 81d383f

Browse files
committed
2026-04-24
1 parent 254335d commit 81d383f

12 files changed

Lines changed: 173 additions & 108 deletions

File tree

Bakefile.sh

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ task.bootstrap() {
1616
}
1717

1818
task.init() {
19+
# TODO: Remove when transform is implemented
1920
cat > .clangd <<EOF
2021
# DO NOT MODIFY! This file is auto-autogenerated from Bakefile.sh.
2122
CompileFlags:
@@ -25,11 +26,6 @@ EOF
2526
printf '%s\n' '.clangd' >>.git/info/exclude
2627
fi
2728

28-
if ! mise trust --cd ~/.dotfiles --show mise | grep -q '~/.dotfiles: trusted'; then
29-
if ! output=$(mise trust ~/.dotfiles/.mise.toml 2>&1); then
30-
printf '%s\n' "$output"
31-
fi
32-
fi
3329
if [ ! -f ./.git/info/lefthook.checksum ]; then
3430
lefthook install
3531
fi

bootstrap-linux.sh

Lines changed: 35 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,38 @@
11
#!/usr/bin/env sh
22
set -e
33

4+
installcmd() {
5+
if iscmd "$1"; then
6+
log "Already installed $1"
7+
else
8+
log "Installing $1"
9+
10+
if iscmd 'pacman'; then
11+
run sudo pacman -S --noconfirm "$2"
12+
elif iscmd 'apt-get'; then
13+
run sudo apt-get -y install "$2"
14+
elif iscmd 'dnf'; then
15+
run sudo dnf -y install "$2"
16+
elif iscmd 'zypper'; then
17+
run sudo zypper -n install "$2"
18+
elif iscmd 'eopkg'; then
19+
run sudo eopkg -y install "$2"
20+
elif iscmd 'brew'; then
21+
run brew install "$2"
22+
else
23+
die 'Failed to determine package manager'
24+
fi
25+
26+
if ! iscmd "$1"; then
27+
die "Automatic installation of $1 failed"
28+
fi
29+
fi
30+
}
31+
32+
if [ -n "$FORCE_SOURCE" ]; then
33+
return 0
34+
fi
35+
436
# shellcheck disable=SC3028,SC3054,SC2039
537
if [ -n "$BASH" ] && [ "${BASH_SOURCE[0]}" != "$0" ]; then
638
printf '%s\n' "Error: This file should not be sourced"
@@ -39,7 +71,9 @@ main() {
3971
run ~/.dotfiles/bake bootstrap
4072

4173
# Symlink ~/scripts.
42-
run ln -fs ~/.dotfiles/hscripts ~/
74+
if [ ! -d ~/scripts ]; then
75+
run ln -sf ~/.dotfiles/hscripts ~/scripts
76+
fi
4377

4478
# Export variables.
4579
cat >~/.bootstrap/bootstrap-out.sh <<EOF
@@ -128,34 +162,6 @@ updatesystem() {
128162
fi
129163
}
130164

131-
installcmd() {
132-
if iscmd "$1"; then
133-
log "Already installed $1"
134-
else
135-
log "Installing $1"
136-
137-
if iscmd 'pacman'; then
138-
run sudo pacman -S --noconfirm "$2"
139-
elif iscmd 'apt-get'; then
140-
run sudo apt-get -y install "$2"
141-
elif iscmd 'dnf'; then
142-
run sudo dnf -y install "$2"
143-
elif iscmd 'zypper'; then
144-
run sudo zypper -n install "$2"
145-
elif iscmd 'eopkg'; then
146-
run sudo eopkg -y install "$2"
147-
elif iscmd 'brew'; then
148-
run brew install "$2"
149-
else
150-
die 'Failed to determine package manager'
151-
fi
152-
153-
if ! iscmd "$1"; then
154-
die "Automatic installation of $1 failed"
155-
fi
156-
fi
157-
}
158-
159165
clonerepo() {
160166
if [ -d "$2" ]; then
161167
log "Already cloned $1"

config/setup.sh

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,15 @@ fi
3232
CURL_CONFIG="$HOME/.dotfiles/config/curl_config.conf"
3333

3434
source ~/.dotfiles/config/setup-private.sh
35+
36+
util.is_in_container_or_chroot() {
37+
if command -v systemd-detect-virt &>/dev/null; then
38+
systemd-detect-virt --quiet --container || systemd-detect-virt --quiet --chroot
39+
else
40+
local stat1= stat2=
41+
stat1=$(stat -c %i /)
42+
stat2=$(stat -c %i /proc/1/root)
43+
44+
[ -e /.dockerenv ] && (( stat1 != stat2 ))
45+
fi
46+
}

docs/installation-unix.md

Lines changed: 3 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -40,41 +40,23 @@ chmod +x ~/.bootstrap/bootstrap.sh
4040
The bootstrap script performs the following steps:
4141

4242
- Installs Homebrew on macOS
43-
- Installs cURL, Git and Vim
43+
- Installs cURL, Git, Vim, and Zsh
4444
- Clones `hyperupcall/dotfiles` to `~/.dotfiles`
4545
- Symlinks `~/scripts` to `~/.dotfiles/scripts`
4646
- Creates `~/.bootstrap/bootstrap-out.sh`. Sourcing it:
4747
- Sets `NAME`, `EMAIL`, `EDITOR`, and `VISUAL`
48-
- Prepends `$HOME/.dotfiles/.data/bin` to `PATH`
48+
- Prepends `$HOME/.dotfiles/.data/bin` and `$HOME/.locall/bin` to `PATH`
4949
- Sources `~/.dotfiles/config/xdg.sh`, if it exists
5050

5151
## Next Steps
5252

5353
Additional scripts should be executed. They include:
5454

5555
- `. ~/.bootstrap/bootstrap-out.sh`
56+
- If on Ubuntu, run `sudo apt-get remove coreutils-from-uutils --allow-remove-essential`
5657
- `~/scripts/rare/transfer-secrets.sh`
57-
- Transfer SSH, PGP files to computer
5858
- Setup ZFS, BTRFS
5959
- `~/scripts/doctor.sh`
60-
- Install required dependencies
61-
- Fix files in home directory
62-
- Remove broken home directory symlinks
63-
- Remove autoappended lines in shell startup files
64-
- Create necessary symlinks
65-
- Set XDG user directories
66-
- Symlink XDG base and user directories
67-
- Add and remove necessary directories, files, and groups
68-
- Write to `~/.dotfiles/.data/{profile,github_token}`
69-
- Check permissions for `~/.{ssh,gnupg}`
70-
- Setup [dev](https://github.com/fox-incubating/dev)
71-
- Install NodeJS v23.6.0
72-
- Setup [d](https://github.com/fox-incubating/d)
73-
- Setup mise and lefthook
74-
- Configure for `~/.dotfiles`
75-
- Setup Git (at least v2.37.0)
76-
- Setup Neovim (at least v0.10.0)
77-
- Setup pass
7860
- Setup Browsers (Firefox, Brave)
7961
- Backup and restore settings (_do manually_):
8062
- uBlacklist

hscripts/backup-home.sh

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,15 @@ main() {
1616
--exclude '**/Steam/steamapps' \
1717
--exclude '**/Steam/ubuntu12_32' \
1818
--exclude '**/Steam/ubuntu12_64' \
19+
--exclude '**/Steam/appcache' \
1920
--exclude '**/*.git' \
2021
--exclude '**/*.hg' \
2122
--exclude '**/*.svn' \
2223
--exclude '**/google-fonts-repository' \
2324
--exclude '**/brave-browser*' \
2425
--exclude '**/chromium*' \
2526
--exclude '**/firefox*' \
27+
--exclude '**/mozilla-unified*' \
2628
--exclude '**/llvm-project*' \
2729
--exclude '**/gcc*' \
2830
--exclude '**/android*' \
@@ -32,8 +34,12 @@ main() {
3234
--exclude '**/node_modules' \
3335
--exclude '**/.npm/_cacache' \
3436
--exclude '**/pnpm/store' \
37+
--exclude '**/.rustup/toolchains' \
3538
--exclude '**/rustup/toolchains' \
39+
--exclude '**/.cargo/registry' \
3640
--exclude '**/cargo/registry' \
41+
--exclude "$HOME/go" \
42+
--exclude "$HOME/.gopath" \
3743
--exclude '**/mise/installs' \
3844
--exclude '**/miniforge3/pkgs' \
3945
--exclude '**/miniforge3/envs' \
@@ -50,6 +56,9 @@ main() {
5056
--exclude "$XDG_DATA_HOME/gradle/jdks" \
5157
--exclude "$XDG_DATA_HOME/flatpak/repo/objects" \
5258
--exclude "$XDG_DATA_HOME/flatpak/runtime" \
59+
--exclude "$XDG_DATA_HOME/flatpak/appstream" \
60+
--exclude "$XDG_DATA_HOME/Jan" \
61+
--exclude "$XDG_DATA_HOME/uv" \
5362
--exclude '**/target' \
5463
--exclude '**/target-*' \
5564
--exclude '**/dist' \
@@ -65,7 +74,7 @@ main() {
6574
--exclude '**/youtube-dl' \
6675
--exclude '**/.cache' \
6776
--exclude '**/*.iso' \
68-
"$backup_dir"::'backup-{now}-{hostname}' \
77+
"$backup_dir"::'backup-{now:%Y-%m-%d_%H:%M:%S}-{hostname}' \
6978
"$save_dir"
7079
fi
7180
}

hscripts/doctor.sh

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -272,25 +272,29 @@ main() {
272272
must.strict_permissions ~/.gnupg/ ~/.gnupg/*
273273

274274
if [[ $computer_profile == @(desktop|laptop) ]]; then
275-
if gpg --list-keys 0x2FB93BF35E14E7C4 &>/dev/null; then
276-
core.print_info "Has gpg key \"Edwin Kofler (FOR PASSWORDS ONLY) <edwin@kofler.dev>\""
275+
if gpg --list-keys "$_private_gpgkey1_id" &>/dev/null; then
276+
core.print_info "Has gpg key \"$_private_gpgkey1_user\""
277277
else
278-
core.print_info "Does not have gpg key \"Edwin Kofler (FOR PASSWORDS ONLY) <edwin@kofler.dev>\""
278+
core.print_info "Does not have gpg key \"$_private_gpgkey1_user\""
279279
fi
280-
if gpg --list-keys 0x3851E5FD042C7C6C &>/dev/null; then
281-
core.print_info "Has gpg key \"Edwin Kofler <edwin@kofler.dev>\""
280+
if gpg --list-keys "$_private_gpgkey2_id" &>/dev/null; then
281+
core.print_info "Has gpg key \"$_private_gpgkey2_user\""
282282
else
283-
core.print_die "Does not have gpg key \"Edwin Kofler <edwin@kofler.dev>\""
283+
core.print_die "Does not have gpg key \"$_private_gpgkey2_user\""
284284
fi
285285
fi
286286
}
287287

288+
~/scripts/setup/juno-computers.sh
289+
288290
# Install the most paramount tools.
289291
~/scripts/setup/d.sh
290292
~/scripts/setup/zsh.sh
291293
~/scripts/setup/ksh.sh
292294
~/scripts/setup/rust.sh
293295
~/scripts/setup/mise.sh
296+
~/scripts/setup/neovim.sh
297+
294298

295299
# Install personal tools.
296300
#~/scripts/setup/npm.sh
@@ -310,7 +314,6 @@ main() {
310314
~/scripts/setup/git.sh
311315

312316
# Install applications.
313-
~/scripts/setup/neovim.sh
314317
~/scripts/setup/firefox.sh
315318
~/scripts/setup/librewolf.sh
316319
~/scripts/setup/brave.sh
@@ -581,6 +584,7 @@ must.strict_permissions() {
581584

582585
dependencies.debian() {
583586
local packages=()
587+
packages+=(xdg-user-dirs)
584588
packages+=(apt-transport-https build-essential)
585589
packages+=(bash-completion curl rsync cmake ccache vim nano jq lvm2) # lint-ignore:curl-must-have-args
586590
packages+=(pkg-config libssl-dev) # For starship
@@ -592,6 +596,7 @@ dependencies.ubuntu() {
592596
}
593597
dependencies.fedora() {
594598
local packages=()
599+
packages+=(xdg-user-dirs)
595600
packages+=(@development-tools)
596601
packages+=(bash-completion curl rsync cmake ccache vim nano jq lvm2) # lint-ignore:curl-must-have-args
597602
packages+=(pkg-config openssl-devel) # For starship
@@ -601,6 +606,7 @@ dependencies.fedora() {
601606
}
602607
dependencies.opensuse() {
603608
local packages=()
609+
packages+=(xdg-user-dirs)
604610
packages+=(bash-completion curl rsync cmake ccache vim nano jq lvm2) # lint-ignore:curl-must-have-args
605611
packages+=(pkg-config openssl-devel) # For starship
606612

@@ -609,6 +615,7 @@ dependencies.opensuse() {
609615
}
610616
dependencies.arch() {
611617
local packages=()
618+
packages+=(xdg-user-dirs)
612619
packages+=(base-devl lvm2 openssl yay)
613620

614621
sudo pacman -Syu --noconfirm "${packages[@]}"

hscripts/transfer-data.sh

Lines changed: 35 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,20 @@
11
#!/usr/bin/env bash
2-
source ~/.dotfiles/config/setup.sh
2+
# DO NOT source setup.sh here. Otherwise, "_private" variables
3+
# cannot be accessed. This needs to be standalone and work before
4+
# running "doctor.sh".
35

46
main() {
7+
FORCE_SOURCE=1 source ~/.dotfiles/bootstrap-linux.sh
8+
installcif [ -n "$FORCE_SOURCE" ]; then
9+
return 0
10+
fi
11+
12+
# shellcheck disable=SC3028,SC3054,SC2039
13+
if [ -n "$BASH" ] && [ "${BASH_SOURCE[0]}" != "$0" ]; then
14+
printf '%s\n' "Error: This file should not be sourced"
15+
return 1
16+
fimd 'jq'
17+
518
local mode=
619
while :; do
720
local options='save|restore'
@@ -35,8 +48,8 @@ main() {
3548

3649
local answer=
3750
while :; do
38-
read -re -p 'Choose directory to put temporary file: ' answer
39-
if [[ $answer =~ [0-9]+ ]] && ((answer >= 0)) && ((answer < ${#options[@]})); then
51+
read -re -p 'Choose directory for temporary files: ' answer
52+
if [[ $answer =~ ^[0-9]+$ ]] && ((answer >= 0)) && ((answer < ${#options[@]})); then
4053
break
4154
fi
4255
done
@@ -47,15 +60,12 @@ main() {
4760
read -re -p 'Enter directory path: ' device_path
4861
fi
4962
device_path=${device_path%/}
50-
local -A paths=(
51-
[libreoffice]="$XDG_CONFIG_HOME/libreoffice/4/user"
52-
[fonts]="$XDG_DATA_HOME/fonts"
53-
[dbeaver]="$XDG_DATA_HOME/DBeaverData/workspace6/General/Scripts"
54-
[ankiuserdata]="$XDG_DATA_HOME/Anki2/Default User"
55-
[ankiaddons]="$XDG_DATA_HOME/Anki2/addons21"
56-
[applicationsdir]="$HOME/Other/Application Data"
57-
[devresources]="$HOME/.devresources"
58-
)
63+
64+
local tmp_gnupg_dir=$(mktemp -d --suffix='-gnupg')
65+
gpg --homedir "$tmp_gnupg_dir" --no-keyring --batch --yes --pinentry-mode loopback --passphrase-fd 3 --no-symkey-cache --decrypt "$device_path/_data/setup_private_sh.asc" 3<<<$(cat "$device_path/_data/pw.txt") | tar -xO > "$HOME/.dotfiles/config/setup-private.sh"
66+
67+
source ~/.dotfiles/config/setup.sh
68+
5969
local -A paths_encrypt=(
6070
[gnupg]="$HOME/.gnupg"
6171
[ssh]="$HOME/.ssh"
@@ -69,6 +79,15 @@ main() {
6979
[setup_private_sh]="$HOME/.dotfiles/config/setup-private.sh"
7080
[dotfiles_git_exclude]="$HOME/.dotfiles/.git/info/exclude"
7181
)
82+
local -A paths=(
83+
[libreoffice]="$XDG_CONFIG_HOME/libreoffice/4/user"
84+
[fonts]="$XDG_DATA_HOME/fonts"
85+
[dbeaver]="$XDG_DATA_HOME/DBeaverData/workspace6/General/Scripts"
86+
[ankiuserdata]="$XDG_DATA_HOME/Anki2/Default User"
87+
[ankiaddons]="$XDG_DATA_HOME/Anki2/addons21"
88+
[applicationsdir]="$HOME/Other/Application Data"
89+
[devresources]="$HOME/.devresources"
90+
)
7291

7392
if [ "$mode" = save ]; then
7493
if [ "$device_path_is_manual" = true ]; then
@@ -79,7 +98,7 @@ main() {
7998

8099
local password= temp_gnupg=
81100
password=$(LC_ALL=C tr -dc '[:graph:]' </dev/urandom | head -c 14)
82-
temp_gnupg=$(mktemp -d --suffix '-gnupg')
101+
temp_gnupg=$(mktemp -d --suffix='-gnupg')
83102
mkdir -p "$temp_gnupg"
84103
core.print_info "Password: $password"
85104

@@ -112,7 +131,7 @@ main() {
112131
cp -rT "$dir" "$dest"
113132
done
114133

115-
elif [ "$mode" = restore ]; then
134+
elif [ "$mode" = resto~/scripts/doctor.sh re ]; then
116135
local password= pw_file="$device_path/_data/pw.txt"
117136
if [ -f "$pw_file" ]; then
118137
password=$(<"$pw_file")
@@ -122,7 +141,7 @@ main() {
122141
fi
123142

124143
local temp_gnupg=
125-
temp_gnupg=$(mktemp -d --suffix '-gnupg')
144+
temp_gnupg=$(mktemp -d --suffix='-gnupg')
126145

127146
for name in "${!paths_encrypt[@]}"; do
128147
local dir="${paths_encrypt[$name]}"
@@ -179,7 +198,7 @@ main() {
179198
core.print_die "Invalid mode: $mode"
180199
fi
181200

182-
core.print_info 'Done! You may need to remove the source directory'
201+
core.print_info 'Done! You may want to remove $device_path/_data'
183202
}
184203

185204
util.if_file_sourced || _main "$@"

0 commit comments

Comments
 (0)