summaryrefslogtreecommitdiff
path: root/arch-distrobox
blob: 77ffe19614ddefa484b6f79e94d70b9dba24928d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
#!/bin/sh
# ArchDistrobox - Craig Jennings <craigmartinjennings@gmail.com>
# License: GNU GPLv3

# Commentary
#
# There are two levels of errors:
# * CRASH: Issues that will halt forward progress, aborting this script.
# * ERROR: Issues not serious enough to halt the script.
# Both are printed on screen and in the $logfile.
# Stderr is also printed to the $logfile for all relevant info.
#
# This script sets up an Arch Linux distrobox setup for software development. 
#
# # Code

# uncomment to stop on any error
# set -e

### Constants

username=cjennings

dotfiles_repo="https://git.cjennings.net/dotfiles"
dotemacs_repo="https://git.cjennings.net/dotemacs.git"
dotfiles_home="/home/$username/.dotfiles"

logfile="/home/$username/archdistrobox-$(date +'%Y-%m-%d-%H-%M-%S').log"
source_dir="/home/$username/.local/src" # aur/git source goes here
packages_before="/home/$username/archdistrobox-preexisting-package-list.txt"
packages_after="/home/$username/archdistrobox-post-install-package-list.txt"
archdistrobox_packages="/home/$username/archdistrobox-installed-packages.txt"

### Intro
intro() {
    printf "\n\nArchDistrobox launched @ %s\n" "$(date +'%D %T')"| tee -a "$logfile"
    STARTTIME=$(date +%s)
    errors_encountered=0

    # begin with a clean logfile
    [ -f "$logfile" ] && rm -f "$logfile"
    touch "$logfile"

    # count the arch packages before install
    pacman -Q > "$packages_before" || \
        error "crash" "generating pre-install package list" "$?"
}

### General Functions
# Error
error () {
    # $1 = type ERROR, noted but the script will continue to run.
    #      anything else will produce CRASH, which halts the script
    # $2 = what was happening (e.g., "adding $username to group $groupname")
    # $3 = the error code (i.e., "$?")

    errors_encountered=$((errors_encountered+1))
    case "$1" in
        "error")
            printf "ERROR: %s failed with error code %s @ %s\n" \
                   "$2" "$3"  "$(date +'%T')"  | tee -a "$logfile"
            return 1;
            ;;
        *)
            printf "CRASH: %s failed with error: %s @ %s. Script halted.\n" \
                   "$2" "$3"  "$(date +'%T')"  | tee -a "$logfile"
            exit 1;
            ;;
    esac
}

#  Display
display () {
    # $1 = type (TITLE, ACTION)
    # $2 = description (answers: "what are you trying to do?")

    case "$1" in
        "title")
            printf "\n##### %s\n" "$2" | tee -a "$logfile"
            return 1;
            ;;
        "subtitle")
            printf "\n%s\n" "$2"  | tee -a "$logfile"
            ;;
        "task")
            printf "...%s @ %s\n" "$2" "$(date +'%T')" | tee -a "$logfile"
            return 1;
            ;;
        *)
            printf "CRASH: display () called with incorrect arguments.\n"
            printf "...called %s type, %s action @ %s\n" \
                   "$1" "$2"  "$(date +'%T')"   | tee -a "$logfile"
            exit 1;
            ;;
    esac

}

# Pacman Install
pacman_install() {
    action="installing $1 via pacman" && display "task" "$action"
    if ! (sudo pacman --noconfirm --needed -S "$1" >> "$logfile" 2>&1); then
        action="retrying $1" && display "task" "$action"
        if ! (sudo pacman --noconfirm --needed -S "$1" >> "$logfile" 2>&1); then
            action="retrying $1 once more" && display "task" "$action"
            (sudo pacman --noconfirm --needed -S "$1" >> "$logfile" 2>&1) ||
                error "error" "$action" "$?"
        fi
    fi
}

# Git Install
git_install() {
    prog_name="$(basename "$1" .git)"
    build_dir="$source_dir/$prog_name"
    action="building & installing $prog_name from source"
    display "task" "$action"

    if ! (git clone --depth 1 "$1" "$build_dir" >> "$logfile" 2>&1); then
        error "error" "cloning source code for $prog_name" "$?"
        (cd "$build_dir" && git pull --force origin master >> "$logfile" 2>&1) || \
            error "error" "pulling source code for $prog_name" "$?"
    fi

    (cd "$build_dir" && make install >> "$logfile" 2>&1) || \
        error "error" "building $prog_name from source code" "$?"
}

# AUR Install
aur_install() {
    action="installing $1 via the AUR" && display "task" "$action"
    if ! (yay -S --noconfirm "$1" >> "$logfile" 2>&1); then
        action="retrying $1" && display "task" "$action"
        if ! (yay -S --noconfirm "$1" >> "$logfile" 2>&1); then
            action="retrying $1 once more" && display "task" "$action"
            (yay -S --noconfirm "$1" >> "$logfile" 2>&1) ||
                error "error" "$action" "$?"
        fi
    fi
}

# PIP Install
pip_install() {
    [ -x "$(command -v "pip")" ] || pacman_install python-pip
    action="installing $1 via PIP" && display "task" "$action"
    (yes | pip install "$1" >> "$logfile" 2>&1)  || \
        error "error" "$action" "$?"
}

### Prerequisites
prerequisites() {
    # why these software packages are 'required'
    # linux-firmware    - ensuring hardware can be detected properly
    # base_devel        - required tools to compile
    # ca_certificates   - for validation of keyrings, etc.
    # coreutils         - comparing package lists
    # curl              - to transfer source code
    # git               - tools required to work with git source respositories
    # go                - required to build yay, the aur installer
    # ntp               - must communicate with other servers in synchronized manner
    # python            - required for python pip installs
    # stow              - places the dotfiles (see: https://bit.ly/41GmysO)
    # tar               - extract unix archives
    # vi                - should things go wrong, we'll need an editor
    # zsh               - we need a shell interpreter for yay; this one's mine

    display "title" "Prerequisites"

    display "subtitle" "Bootstrapping"

    # action="refreshing the package cache" && display "task" "$action"
    # (pacman -Syu --noconfirm >> "$logfile" 2>&1)  || error "crash" "$action" "$?"

    display "subtitle" "Required Software"

    for software in base-devel coreutils curl git go ntp openssh python \
                    stow tar vi zsh; do
        pacman_install "$software"
    done

    display "subtitle" "Creating Build/Install Directories"

    action="creating a directory to build/install software from git/AUR."
    (mkdir -p $source_dir) || \
        error "crash" "creating the directory $source_dir"

}

### User Customizations
user_customizations() {
    action="User Customizations" && display "title" "$action"

    action="cloning dotfiles" && display "task" "$action"
    (git clone --depth 1 $dotfiles_repo "$dotfiles_home" \
         >> "$logfile" 2>&1)  ||  error "error" "$action" "$?"

    action="moving dotfiles into place" && display "task" "$action"
    (cd "$dotfiles_home" &&  stow --no-folding --adopt * \
                                  >> "$logfile" 2>&1 )  || error "error" "$action" "$?"

    action="restoring dotfile versions" && display "task" "$action"
    (cd "$dotfiles_home" &&  git restore . \
                                 >> "$logfile" 2>&1 )  || error "error" "$action" "$?"

}

### AUR Installer
aur_installer () {
    display "title" "AUR Installer"

    yay_repo="https://aur.archlinux.org/yay.git"
    build_dir="$source_dir/yay"

    display "task" "creating yay build directory"
    if ! (mkdir -p "$build_dir" >> "$logfile" 2>&1); then
        error "crash" "creating yay build directory"
    fi

    display "task" "fetching source code for yay"
    if ! (git clone --depth 1 "$yay_repo" "$build_dir" >> "$logfile" 2>&1); then
        error "error" "cloning source code for yay"
        (cd "$build_dir" && git pull --force origin master >> "$logfile" 2>&1) || \
            error "crash" "changing directories to $build_dir and pulling source code" "$?"
    fi

    action="packaging and installing yay"; display "task" "$action"
    (cd "$build_dir" && makepkg --noconfirm -si >> "$logfile" 2>&1) || \
        error "crash" "$action" "$?"
}

### Desktop Environment
environment_tools() {
    display "title" "Environment Tools"

    # System Utilities

    action="System Utilities" && display "subtitle" "$action"
    pacman_install dmidecode
    pacman_install dosfstools
    pacman_install exfat-utils
    pacman_install lshw
    pacman_install ntfs-3g
    pacman_install sshfs
    pacman_install testdisk
    pacman_install udisks2
    aur_install downgrade
    aur_install inxi

    # File Associations

    action="File/Application Associations" && display "subtitle" "$action"
    pacman_install perl-file-mimeinfo
    pacman_install xdg-utils

    # Authentication Tools

    action="Authentication Tools" && display "subtitle" "$action"
    pacman_install gnupg
    pacman_install polkit
    pacman_install gnome-keyring

    # ensure correct permissions on .gpg directory
    # the colon means the user's group will have perms
    [ -d /home/"$username"/.gnupg ] || mkdir /home/"$username"/.gnupg
    chown -R "$username": /home/"$username"/.gnupg
    find /home/"$username"/.gnupg -type f -exec chmod 600 {} \;
    find /home/"$username"/.gnupg -type d -exec chmod 700 {} \;


    # Command Line Utilities

    action="Command Line Utilities" && display "subtitle" "$action"
    for software in htop mc ncdu tmux fzf zip unzip atool wget detox \
                         lsof usbutils moreutils; do
        pacman_install "$software"
    done;

	for software in task-spooler speedtest-go gotop-bin rar; do
        aur_install "$software"
    done;

    # Help And Documentation

	action="Help and Documentation" && display "subtitle" "$action"
	pacman_install man
	pacman_install arch-wiki-docs
	pacman_install tealdeer
	aur_install cht.sh-git
}

### Developer Workstation
developer_workstation () {

    action="Developer Workstation" && display "title" "$action"

    action="Programming Languages and Utilities" && display "subtitle" "$action"
    # C
    pacman_install clang       # C/C++ compiler
    pacman_install cmake       # make system
    pacman_install gdb         # the GNU debugger
    pacman_install splint      # C programming static analysis
    pacman_install valgrind    # memory management utility

    # java
    pacman_install jdk-openjdk # Java Development Kit
    pacman_install openjdk-doc # ...and the documentation

    # Lisps
    pacman_install guile       # GNU Scheme
    pacman_install sbcl        # Steel Bank Common Lisp
    pacman_install racket      # Racket + SICP mit-scheme emulation

    # Rust
    pacman_install rust        # Rust programming language

    # Python
	pacman_install pyright     # Python language server
	pacman_install pyenv       # Python environment manager

    # Shell
    pacman_install shellcheck  # Shell script linter
    pacman_install shfmt       # Shell script formatter

    # Go
    pacman_install delve       # Go programming language debugger
    pacman_install go-tools    # Go language utilities
    pacman_install gopls       # Go language server
    pacman_install staticcheck # Go programming language linter

    # Typescript
	pacman_install jq          # JSON processor
	pacman_install typescript  # Typescript programming language
	pacman_install nodejs      # Node-js JavaScript runtime environment
	pacman_install npm         # Node-js package manager
	aur_install nvm            # Node-js version manager

    # HTML
    pacman_install tidy        # HTML formatter
    pacman_install prettier    # Multi-language formatter

    # General Utilities
    pacman_install meld             # Visual diff
    pacman_install ripgrep          # Fast grep utility
    aur_install the_silver_searcher # Another fast grep utility

    action="Programming Editors" && display "subtitle" "$action"
    pacman_install mg
    pacman_install neovim

    action="Emacs Dependencies" && display "subtitle" "$action"
    pacman_install emacs

    # supporting utilities used by my emacs configuration
	aur_install exercism-bin         # command line tool for exercism.io
    aur_install isync                # email sync
    aur_install mu                   # email indexer and utilities
    aur_install multimarkdown        # markdown conversion
    aur_install proselint            # grammar checker
    aur_install gist                 # command-line gist poster
    pacman_install aspell            # spell check system
    pacman_install aspell-en         # spell check english files
    pacman_install fd                # a faster find for dired/dirvish
    pacman_install ffmpegthumbnailer # video previews in dired/dirvish
    pacman_install imagemagick       # image previews for dired/dirvish
    pacman_install libgccjit         # native compilation for Emacs
    pacman_install mediainfo         # generating media info in dired/dirvish
    pacman_install mpv               # video viewer
    pacman_install mailutils         # Emacs' IMAP mail support backend
    pacman_install msmtp             # mail transport for Mu4e
    pacman_install msmtp-mta         # mail transport for Mu4e
    pacman_install python-lsp-server # python language support
    pacman_install rlwrap            # adds readline support to programs (SBCL-related)
    pacman_install sdcv              # stardict dictionary system
    pacman_install yt-dlp            # video download

    action="setting up emacs configuration files" && display "task" "$action"
    (sudo -u "$username" git clone --recurse-submodules $dotemacs_repo /home/$username/.emacs.d  >> \
          "$logfile" 2>&1) || error "error" "$action" "$?"

    action="Android Utilities" && display "subtitle" "$action"
    pacman_install android-file-transfer
    pacman_install android-tools

    action="DevOps Utilities" && display "subtitle" "$action"

	action="installing devops virtualization and automation tools" && display "task" "$action"
	pacman_install vagrant
	pacman_install ansible
	
    # Docker within Podman! 

	pacman_install docker
	pacman_install docker-compose
	action="adding user to docker group" && display "task" "$action"
	(gpasswd -a $username docker >> "$logfile" 2>&1)  || error "error" "$action" "$?"
	action="enabling docker service to launch on boot" && display "task" "$action"
	systemctl enable docker.service >> "$logfile" 2>&1  || error "error" "$action" "$?"
}

### Supplemental Software
supplemental_software() {

    display "title" "Supplemental Software"

    # pacman installs
    pacman_install aria2                             # fast downloader
    pacman_install dash                              # posix compliant /bin/sh
    pacman_install dfc                               # better display of available space on mounted filesystems
    pacman_install docx2txt                          # recovers text from docx files
    pacman_install entr                              # run arbitrary commands when files change
    pacman_install figlet                            # words into ascii art
    pacman_install filezilla                         # ftp gui
    pacman_install gparted                           # disk partition utility
    pacman_install gucharmap                         # gui display of character maps
    pacman_install gzip                              # compression tool
    pacman_install libconfig                         # library for processing structured config files
    pacman_install mosh                              # alt SSH terminal with roaming and responsiveness support
    pacman_install neofetch                          # cli system information tool
    pacman_install odt2txt                           # converts from open document to text
    pacman_install p7zip                             # p7zip compression tool
    pacman_install pandoc                            # universal document converter
    pacman_install poppler-glib                      # poppler-glib document viewer library
    pacman_install pv                                # monitor progress of data through pipeline
    pacman_install ranger                            # terminal file manager
    pacman_install rclone                            # syncs files from gdrive, s3, dropbox, etc.
    pacman_install texlive-meta                      # latex
    pacman_install w3m                               # text based browser
    pacman_install xz                                # general purpose data compression tool
    pacman_install zathura                           # document viewer
    pacman_install zathura-cb                        # zathura plugin for comics
    pacman_install zathura-djvu                      # zathura plugin for djvu books
    pacman_install zathura-pdf-mupdf                 # zathura plugin for pdf
    pacman_install zlib                              # compression library

    # aur installs
    aur_install dtrx                                 # extraction tool
    aur_install figlet-fonts                         # fonts for figlet
    aur_install hfsprogs                             # file system tools for Mac OS
    aur_install mcomix                               # image viewer for comic books
    aur_install nsxiv                                # image viewer
	aur_install shell-gpt                            # gpt in your terminal
    aur_install tageditor                            # metadata editor for mkv, webm and related video files
    aur_install zsh-fast-syntax-highlighting-git     # Optimized and extended zsh-syntax-highlighting

    # git installs
    git_install https://github.com/clamiax/snore.git # sleep with feedback

}

### Outro
outro() {

    display "subtitle" "Statistics"
    action="identifying newly installed packages" && display "task" "$action"
    pacman -Q > "$packages_after"  || error "error" "$action" "$?"
    (comm -13 --nocheck-order "$packages_before" "$packages_after" > "$archdistrobox_packages")  || \
        error "error" "$action" "$?"

    action="comparing timestamps" && display "task" "$action"
    ENDTIME=$(date +%s)
    totalsecs=$(($ENDTIME - $STARTTIME))
    mins=$(($totalsecs / 60))
    secs=$(($totalsecs % 60))

    new_packages=$(cat $archdistrobox_packages | wc -l)

    printf "\n"
    printf "Completion time    : %s\n" "$(date +'%D %T')"  | tee -a "$logfile"
    printf "Elapsed time       : %s minutes, %s seconds\n" $mins $secs | tee -a "$logfile"
    printf "Errors encountered : %s\n" $errors_encountered | tee -a "$logfile"
    printf "Log file location  : %s\n" "$logfile"
    printf "Packages installed : %s\n" "$new_packages"
    printf "\n"
    printf "Please reboot before working with your new workstation.\n\n"
}

### Installation Steps
intro                 # take initial stats

prerequisites         # install software required to install software
user_customizations   # dotfiles
aur_installer         # install yay (comment out if using zfsarch install first)
environment_tools     # commonly used applications
developer_workstation # development tools and utilities
supplemental_software # everything else

outro                 # take end stats; show summary

exit 0