thoughts, things, etc. from andrew snow

Towards bootstrap!


Do you even exist if you don't have your own boutique dotfiles repo and bootstrap setup script?

The thing they never tell you about development boards is that you'll be basically installing a new operating system literally once a day, if you like to play around. If you like to play around, you'll wind up breaking stuff. Luckily we live in the future, where a quick wipe-flash-reinstall can be done in under 5 minutes, so why waste time trying to troubleshoot why Ubuntu wiped everything in your $PATH and then set /var/lib/chicken-pudding-pics as your system-wide executables folder?

How quickly one realizes the tedious nature of typing in the same commands over, and over. On a brand-new install, there's a shortlist of things that need to be done before LoC 1 can be hacked into being:

  • build tools (ex. build-essential devscripts llvm clang)
  • package managers (ex. rbenv, npm, rustup, pip/pyenv)
  • some vim config
  • prompt setup (tweak bash, or replace with zsh/fish etc. and tweak)

So on, so forth.

Over time I have slowly been distilling the things I tend to use more, from the things which aren't supremely critical. At the same time, having to work across many distros and cpu architectures, I did not like the potential necessity for a 'modular' setup with different base file configs depending on my hardware/software needs. Luckily, as an amateur developer, one of the first things you learn is how to work with basic if then statements... which means a single file can be executed in a multitude of environments, and self-configure properly by leaning heavily on alot of conditional statements which help determine what needs to be done.

Hacky? Suboptimal? Possibly. Unless you're a purist who thinks something like the Oh My Zsh! rc file is a crime against humanity, the scripts themselves are similar to the size of something like an OMZ install.

However, I spare no expense when I run my dependency installs - even on SoC boards I use 32GB SD cards at a minimum, so I never have space issues despite the fact that a random observer might think that my install process was doing a regex search and installing anything beginning with "lib-" and/or ending with "-dev".


Once again I have to stress that this has sprung up somewhat organically - initially I automated little chunks of my setup with small scripts that i would cat and sh, and then i started merging the scripts into other files - for example, i no longer worry at all about base16-shell - after setting up zsh, within my rc file is a simple conditional that looks for the default base16-shell folder, and either git clones it if nothing is found, or continues normally and loads base16-shell if it sees that it exists in its default location.

I probably did not describe that well, so check the code:

# base16 shell colorthemes: type "base16" in prompt and mash dat mf tab button
[ -n "$PS1" ] && \
    [ -s "$BASE16_SHELL/profile_helper.sh" ] && \
         eval "$("$BASE16_SHELL/profile_helper.sh")"

# check to see if the base16-shell default installation is present, and grab it if it isn't

 if [ -d "$HOME/.config/base16-shell/" ]; then
    export BASE16_INSTALLED="1"
     git clone https://github.com/chriskempson/base16-shell.git ~/.config/base16-shell

Yes, it's somewhat bassackwards in that it calls the script function and then looks to see if it's even there. And yes, it sets a BASE16_INSTALLED variable that is more or less vestigial and is never actually used - but the beauty of environmental variables is that so long as one is careful with the naming conventions, they will never bork your system - as far as I know there is no program that exists which relies on checking the output for $BASE16_INSTALLED, so for now it just kinda chills. The plan is to eventually use it in a more robust bootstrapping script as a way to do a sort of last-check, as well as to have it on-hand to use if there is another conditional that might only run in the absence of this script, etc.

Test drive

As of now, when I boot into a brand-new system, there are three things I do first:

  • [sudo] apt update && [sudo] apt upgrade -y
  • sudo apt install git wget curl zsh
  • curl https://becausethe.net/init | sh

Please do not use the `sh` command when first running the command - always look at anything you grab via `curl` first, before executing!!

This should be self-explanatory: I run an update/upgrade to get current. I then grab the three utilities critical to working with alot of remote files, as well as zsh because everything related to setting up my shell and prompt goes alot smoother when zsh is already present.

The last command grabs and executes a script which kicks off the bootstrap. Since you're a good and responsible human bean you first ran it without the | sh pipe, which means your commandline printed the following code to stdout:


echo -n "

 ██████╗  ███████╗  ██████╗  █████╗  ██╗   ██╗ ███████╗ ███████╗
 ██╔══██╗ ██╔════╝ ██╔════╝ ██╔══██╗ ██║   ██║ ██╔════╝ ██╔════╝
 ██████╔╝ █████╗   ██║      ███████║ ██║   ██║ ███████╗ █████╗
 ██╔══██╗ ██╔══╝   ██║      ██╔══██║ ██║   ██║ ╚════██║ ██╔══╝
 ██████╔╝ ███████╗ ╚██████╗ ██║  ██║ ╚██████╔╝ ███████║ ███████╗
 ╚═════╝  ╚══════╝  ╚═════╝ ╚═╝  ╚═╝  ╚═════╝  ╚══════╝ ╚══════╝"

 echo -n "

 ████████╗ ██╗  ██╗ ███████╗     ███╗   ██╗ ███████╗ ████████╗
 ╚══██╔══╝ ██║  ██║ ██╔════╝     ████╗  ██║ ██╔════╝ ╚══██╔══╝
    ██║    ███████║ █████╗       ██╔██╗ ██║ █████╗      ██║
    ██║    ██╔══██║ ██╔══╝       ██║╚██╗██║ ██╔══╝      ██║
    ██║    ██║  ██║ ███████╗ ██╗ ██║ ╚████║ ███████╗    ██║
    ╚═╝    ╚═╝  ╚═╝ ╚══════╝ ╚═╝ ╚═╝  ╚═══╝ ╚══════╝    ╚═╝"

sudo apt install -y zsh git pkg-config build-essential neofetch htop nmon nmap pinentry-tty htop devscripts

git clone https://github.com/jeromescuggs/.dotfiles

cd ~/ && $HOME/.dotfiles/env.sh

mkdir -p $HOME/.jrmbin && mkdir -p $HOME/gits

git clone https://github.com/jeromescuggs/git-r-done $HOME/gits/git-r-done

cp $HOME/gits/git-r-done/jrmgit $HOME/.jrmbin

This is the absolute bare minimal I need to get going - the rest is all tucked away in my .dotfiles repository which is downloaded by the script. Obviously I will need to change this when I get closer to sanitizing it for broad usage. The one thing which you might not immediately recognize is the setting up of a .jrmbin folder, where I then move a script, jrmgit into. (jrmbin is the location i use in my $PATH for any sort of small widget-y program; for more detail on the script, see my notes on jrmgit)

updated march 27