diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 0c92f61..84d64ff 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -1,12 +1,10 @@ on: [push] jobs: - build: + tests: runs-on: ubuntu-latest - name: + name: tests steps: - uses: actions/checkout@v2 - - name: Build Docker image - run: make build - - name: Test Docker image + - name: Run tests run: make test diff --git a/Dockerfile b/Dockerfile index 8140b90..336ec53 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,44 +1,27 @@ -from ubuntu:bionic +from ubuntu:bionic as install -# ---------------------------------------------------------------------------- # -# (usually) Cached steps -# ---------------------------------------------------------------------------- # - -# See bootstrap.sh -ENV FAST_MODE="true" -ENV WORKSPACE="$HOME/workspace" - -# Set Noninteractive +# Install sudo and make, git since built-in is skipped RUN echo 'debconf debconf/frontend select Noninteractive' | debconf-set-selections - -# Install sudo for compatibility, git since built-in is skipped, make -RUN apt-get -y update \ - && apt-get -y install sudo git make +RUN apt-get -qqy update \ + && apt-get -qqy install sudo git make # Create user with sudo priviledge -ENV USER="test-user" +ARG USER="test-user" RUN useradd --create-home -m "$USER" \ && adduser "$USER" sudo RUN echo "$USER ALL=(ALL) NOPASSWD: ALL" \ - >> /etc/sudoers - -# ---------------------------------------------------------------------------- # -# Filesystem copy steps -# ---------------------------------------------------------------------------- # + >>/etc/sudoers +# Filesystem steps +ENV WORKSPACE="/home/$USER/workspace" ADD --chown=test-user . "$WORKSPACE/dotfiles" WORKDIR "$WORKSPACE/dotfiles" -# ---------------------------------------------------------------------------- # -# Install steps -# ---------------------------------------------------------------------------- # - +# Install steps USER test-user -RUN make +ENV FAST_MODE="true" +ARG TARGET="all" +RUN make TARGET=$TARGET -# ---------------------------------------------------------------------------- # -# Test steps -# ---------------------------------------------------------------------------- # - -WORKDIR "$WORKSPACE/dotfiles/tests" -ENTRYPOINT ["make"] +# Test entrypoint +ENTRYPOINT [ "make", "--directory", "tests", "TARGET=$TARGET" ] diff --git a/Makefile b/Makefile index 2123784..9ce9a78 100644 --- a/Makefile +++ b/Makefile @@ -1,14 +1,12 @@ -# dotfiles Makefile +SHELL := /bin/bash # ---------------------------------------------------------------------------- # -# Local target commands (warning: affects local environment) +# Local commands # ---------------------------------------------------------------------------- # .PHONY: clean -# Install dotfiles locally all: ./bootstrap.sh -# Clean up after install clean: rm -f .dotlock @@ -21,9 +19,12 @@ clean: build: docker build . -t dotfiles:latest -# Run tests in docker container (args to specify test) +# Run tests in docker container +# @arg $TARGET binary to install and test test: - docker run dotfiles:latest + docker build . -t dotfiles:localtest \ + --build-arg TARGET=$$TARGET \ + && docker run dotfiles:localtest # Launch bash in docker container start: diff --git a/bash/.profile b/bash/.profile index b2bfe50..c85e0e3 100644 --- a/bash/.profile +++ b/bash/.profile @@ -1,14 +1,22 @@ # set PATH so it includes user's private bin if it exists -if [ -d "$HOME/bin" ] ; then +if [ -d "$HOME/bin" ]; then PATH="$HOME/bin:$PATH" fi # config -export XDG_DATA_HOME="$HOME/.local/share" -export XDG_CONFIG_HOME="$HOME/.config" +if [ -z "$XDG_DATA_HOME" ]; then + export XDG_DATA_HOME="$HOME/.local/share" + mkdir -p "$XDG_DATA_HOME" +fi +if [ -z "$XDG_CONFIG_HOME" ]; then + export XDG_CONFIG_HOME="$HOME/.config" + mkdir -p "$XDG_CONFIG_HOME" +fi # workspace -export WORKSPACE="$HOME/workspace" +if [ -z "$WORKSPACE" ]; then + export WORKSPACE="$HOME/workspace" +fi # .local export PATH="$HOME/.local/bin:$PATH" @@ -24,6 +32,6 @@ export POETRY_ROOT="$HOME/.poetry" export PATH="$POETRY_ROOT/bin:$PATH" # nvm -export NVM_DIR="$HOME/.nvm" +export NVM_DIR="$XDG_CONFIG_HOME/nvm" export PATH="$NVM_DIR/bin:$PATH" [ -s "$NVM_DIR/nvm.sh" ] && source "$NVM_DIR/nvm.sh" diff --git a/bootstrap.sh b/bootstrap.sh index 24781eb..45e8421 100755 --- a/bootstrap.sh +++ b/bootstrap.sh @@ -1,35 +1,35 @@ #!/usr/bin/env bash +set -o pipefail + +# Script to set up dependencies and run installer # -# Script to set up and run dotfiles installer +# 1. Install git using `apt-get` if not already in $PATH +# * see $FAST_MODE # -# Installs git using `apt-get` if not in $PATH -# step may be skipped, -# @see $FAST_MODE +# 2. Create workspace folder if one doesn't already exist +# * see $WORKSPACE # -# Pulls latest target repository using git -# @see $REPOSITORY +# 3. Pull latest target repository using `git` +# * see $REPOSITORY, $FAST_MODE # -# Creates workspace if one doesn't already exist -# @see $WORKSPACE -# -# Runs installer -# @see $INSTALLER +# 4. Run installer +# * see $INSTALLER # # # Usage # # i. Run script # -# $ ./bootstrap.sh -# $ /path/to/bootstrap.sh +# * $ ./bootstrap.sh +# * $ /path/to/bootstrap.sh # # ii. Download and run script # # a. non-interactively -# $ wget path.to/bootstrap.sh -qO - | bash +# * $ wget path.to/bootstrap.sh -qO - | bash # # b. interactively -# $ bash <(wget -qO- path.to/bootstrap.sh) +# * $ bash <(wget -qO- path.to/bootstrap.sh) # # # Configuration @@ -45,46 +45,38 @@ # # $FAST_MODE - whether to skip git (and speed up install steps) # @defualt false -# -# -set -o pipefail + echo "setting up..." -# Variables: $REPOSITORY -if [ -z "$REPOSITORY" ]; then - export REPOSITORY="andrejusk/dotfiles" -fi -export repository_url="https://github.com/$REPOSITORY.git" -echo "using repository: $repository_url" - -# Variables: $WORKSPACE +# Inistialise variables if [ -z "$WORKSPACE" ]; then export WORKSPACE="$HOME/workspace" fi export dotfiles_dir="$WORKSPACE/dotfiles" echo "using dir: $dotfiles_dir" -# Variables: $INSTALLER -if [ -z "$INSTALLER" ]; then - export INSTALLER="install.sh"; +if [ -z "$REPOSITORY" ]; then + export REPOSITORY="andrejusk/dotfiles" fi -export installer="$dotfiles_dir/$INSTALLER" +repository_url="git@github.com:$REPOSITORY.git" +echo "using repository: $repository_url" + +if [ -z "$INSTALLER" ]; then + INSTALLER="install.sh"; +fi +installer="$dotfiles_dir/$INSTALLER" echo "using installer: $installer" -# Pull latest git if not skipped +# Ensure repo is available if [ -z "$FAST_MODE" ]; then - - # Set to falsy variable export FAST_MODE=false - # Ensure git is installed if ! [ -x "$(command -v git)" ]; then echo "installing git..." sudo apt-get update -qqy sudo apt-get install git -qqy fi - # Ensure latest is pulled echo "pulling latest..." if ! [ -d "$dotfiles_dir" ]; then mkdir -p "$dotfiles_dir" @@ -96,9 +88,10 @@ if [ -z "$FAST_MODE" ]; then fi -# Install dotfiles +# Run installer echo "installing..." -cd "$dotfiles_dir" +source "$dotfiles_dir/bash/.profile" chmod +x "$installer" "$installer" + echo "done!" diff --git a/install.sh b/install.sh index 0052e50..6465156 100755 --- a/install.sh +++ b/install.sh @@ -1,9 +1,8 @@ #!/usr/bin/env bash -# -# Invokes all install scripts. -# set -euo pipefail -source "$dotfiles_dir/utils.sh" + +export install_dir="$dotfiles_dir/install" +source "$install_dir/utils.sh" printf "\nInstalling ${C_CYAN}$REPOSITORY${C_NC}" printf " as ${C_YELLOW}$USER${C_NC}\n" @@ -21,24 +20,26 @@ if [ -f "$install_lock_file" ]; then printf "Please wait for script to exit or ${C_YELLOW}make clean${C_NC}\n" exit 1 fi -touch "$install_lock_file" # Requires clean +touch "$install_lock_file" -# Run all install scripts -export install_dir="$dotfiles_dir/install" -readonly script_filter="$install_dir/*.sh" # Don't escape to unwrap glob -for script in $script_filter; do - [ -e "$script" ] || continue +# Install all scripts by default +if [ -z "$TARGET" ]; then + TARGET="all" +fi - # Get script name, split by dash - script_name="$(basename "$script" ".sh")" - IFS='-' read -a script_fields <<< "$script_name" +if [ "$TARGET" == "all" ]; then + scripts=($install_dir/*.sh) +else + scripts=($install_dir/*-{apt,bash,$TARGET}.sh) +fi +for script in "${scripts[@]}"; do + + script_name="$(basename $script .sh)" + IFS='-' read -a script_fields <<<"$script_name" script_number=${script_fields[0]} script_target=${script_fields[1]} - # Log execution printf "\nRunning #$script_number ${C_YELLOW}$script_target${C_NC}...\n${C_DGRAY}" - - # Run and indent output chmod +x "$script" source "$HOME/.bashrc" && "$script" | indent printf "${C_NC}" @@ -46,7 +47,6 @@ for script in $script_filter; do # Clean up if fails done || make clean -# Clean up and exit printf "\nDone! Cleaning up...\n${C_DGRAY}" make clean printf "${C_NC}\n" diff --git a/install/00-apt.sh b/install/00-apt.sh index 3219fd5..459f580 100755 --- a/install/00-apt.sh +++ b/install/00-apt.sh @@ -1,20 +1,13 @@ #!/usr/bin/env bash -# -# apt update and upgrade -# -# Install list of packages in 00-apt-pkglist -# -# pre clean +# apt clean, update, upgrade clean - -# apt update, upgrade update upgrade -# Package installs +# Install list of packages in 00-apt-pkglist package_list_file="$install_dir/00-apt-pkglist" install_file "$package_list_file" -# Log version +# Log OS version cat /etc/os-release diff --git a/install/01-bash.sh b/install/01-bash.sh index eb716c4..b5fb21b 100755 --- a/install/01-bash.sh +++ b/install/01-bash.sh @@ -1,11 +1,8 @@ #!/usr/bin/env bash -# -# After running this script: -# 1. bash dotfiles are symlinked -# -# 1. bash dotfiles are symlinked +# bash dotfiles are symlinked bash_source="$dotfiles_dir/bash" bash_target="$HOME" link_folder "$bash_source" "$bash_target" -printf "bash dotfiles are linked\n" +echo "bash dotfiles are linked" +bash --version diff --git a/install/02-fish.sh b/install/02-fish.sh index b47e2c0..d2c49a7 100755 --- a/install/02-fish.sh +++ b/install/02-fish.sh @@ -1,53 +1,39 @@ #!/usr/bin/env bash -# -# After running this script: -# 1. fish shell is installed -# 2. fish shell is default login shell -# 3. fish dotfiles are symlinked -# 4. fisher is installed -# -# 1. fish shell is installed +# fish shell is installed if not_installed "fish"; then + echo "Installing fish..." - printf "Installing fish...\n" - - # Add fish repository add_ppa "fish-shell/release-3" update - - # Install fish install fish fi -printf "fish is installed\n" +echo "fish is installed" fish --version -# 2. fish shell is default login shell +# fish shell is default login shell current_shell="$(getent passwd $USER | cut -d: -f7)" fish_path="$(which fish)" if [ "$current_shell" != "$fish_path" ]; then + echo "setting fish as default, current shell was $current_shell" - printf "setting fish as default, current shell was $current_shell\n" - - # Update default login shell sudo chsh -s "$fish_path" "$USER" sudo usermod -s "$fish_path" "$USER" - fi -printf "fish is default login shell\n" +echo "fish is default login shell" -# 3. fish dotfiles are symlinked +# fish dotfiles are symlinked fish_source="$dotfiles_dir/fish" fish_target="$XDG_CONFIG_HOME/fish" link_folder "$fish_source" "$fish_target" -printf "fish dotfiles linked\n" +echo "fish dotfiles linked" -# 4. fisher is installed +# fisher is installed fisher_location="$XDG_CONFIG_HOME/fish/functions/fisher.fish" if ! [ -f "$fisher_location" ]; then - printf "Installing fisher...\n" + echo "Installing fisher..." # Install fisher curl https://git.io/fisher --create-dirs -sLo "$fisher_location" diff --git a/install/03-ssh.sh b/install/03-ssh.sh index 9932025..fe7bfe0 100755 --- a/install/03-ssh.sh +++ b/install/03-ssh.sh @@ -1,22 +1,17 @@ #!/usr/bin/env bash -# -# After running this script: -# 1. ssh key exists -# 2. ssh dotfiles are symlinked -# # 1. ssh key exists ssh_target="$HOME/.ssh" ssh_key="$ssh_target/id_rsa" ssh_pub="$ssh_key.pub" if [ ! -f "$ssh_key" ]; then - printf "generating ssh key...\n" + echo "generating ssh key..." ssh-keygen -t rsa -b 4096 -f "$ssh_key" fi -printf "ssh key exists\n" +echo "ssh key exists" # 2. ssh dotfiles are symlinked ssh_source="$dotfiles_dir/ssh" link_folder "$ssh_source" "$ssh_target" -printf "ssh dotfiles are symlinked\n" +echo "ssh dotfiles are symlinked" cat "$ssh_pub" diff --git a/install/04-git.sh b/install/04-git.sh index 5d64ac8..7922b35 100755 --- a/install/04-git.sh +++ b/install/04-git.sh @@ -1,8 +1,4 @@ #!/usr/bin/env bash -# -# After running this script: -# 1. git dotfiles are symlinked -# # 1. git dotfiles are symlinked git_source="$dotfiles_dir/git" diff --git a/install/10-pyenv.sh b/install/10-pyenv.sh index 00d8522..3c1b7a6 100755 --- a/install/10-pyenv.sh +++ b/install/10-pyenv.sh @@ -1,13 +1,9 @@ #!/usr/bin/env bash -# -# After running this script: -# 1. pyenv is installed -# # 1. pyenv is installed if not_installed "pyenv"; then - printf "Installing pyenv...\n" + echo "Installing pyenv..." # Install pyenv prerequisites # see https://github.com/pyenv/pyenv/wiki/common-build-problems @@ -20,6 +16,6 @@ if not_installed "pyenv"; then "bash" fi -printf "pyenv is installed, upgrading...\n" +echo "pyenv is installed, upgrading..." git --git-dir="$PYENV_ROOT/.git" pull pyenv --version diff --git a/install/11-python.sh b/install/11-python.sh index bc4024e..783c62f 100755 --- a/install/11-python.sh +++ b/install/11-python.sh @@ -1,19 +1,15 @@ #!/usr/bin/env bash -# -# After running this script: -# 1. python3 and pip3 are installed -# # 1. python3 and pip3 are installed if not_installed "pip3"; then - printf "Installing python3 and pip3...\n" + echo "Installing python3 and pip3..." pyenv install 3.7.0 pyenv global 3.7.0 fi -printf "python3 and pip3 are installed, upgrading...\n" +echo "python3 and pip3 are installed, upgrading..." pip3 install --upgrade pip python3 --version pip3 --version diff --git a/install/12-poetry.sh b/install/12-poetry.sh index b703bb4..6a0e632 100755 --- a/install/12-poetry.sh +++ b/install/12-poetry.sh @@ -1,8 +1,4 @@ #!/usr/bin/env bash -# -# After running this script: -# 1. poetry is installed -# # 1. poetry is installed if not_installed "poetry"; then diff --git a/install/20-nvm.sh b/install/20-nvm.sh index c75dde7..8658be7 100755 --- a/install/20-nvm.sh +++ b/install/20-nvm.sh @@ -1,8 +1,4 @@ #!/usr/bin/env bash -# -# After running this script: -# 1. nvm is installed -# # 1. nvm is installed if not_installed "nvm"; then @@ -10,10 +6,12 @@ if not_installed "nvm"; then printf "Installing nvm...\n" # Install nvm - curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.35.2/install.sh | bash - refresh + run "https://raw.githubusercontent.com/nvm-sh/nvm/v0.35.2/install.sh" \ + "bash" + source "$NVM_DIR/nvm.sh" fi + printf "nvm is installed, upgrading...\n" git --git-dir="$NVM_DIR/.git" pull nvm update --lts node diff --git a/install/30-docker.sh b/install/30-docker.sh index 6e2655c..dbe780a 100755 --- a/install/30-docker.sh +++ b/install/30-docker.sh @@ -1,11 +1,4 @@ #!/usr/bin/env bash -# -# After running this script: -# 1. docker is installed -# 2. docker-compose if installed -# 3. docker group exists -# 4. user is in docker group -# # 1. docker is installed DOCKER_FOLDER="$HOME/.docker" diff --git a/install/31-keybase.sh b/install/31-keybase.sh index ed67c4b..c14a88e 100755 --- a/install/31-keybase.sh +++ b/install/31-keybase.sh @@ -1,8 +1,4 @@ #!/usr/bin/env bash -# -# After running this script: -# 1. keybase is installed -# # 1.keybase is installed if not_installed "keybase"; then diff --git a/utils.sh b/install/utils.sh similarity index 90% rename from utils.sh rename to install/utils.sh index 32254e6..cae83f5 100644 --- a/utils.sh +++ b/install/utils.sh @@ -1,8 +1,4 @@ #!/usr/bin/env bash -# -# Alias commands and utilities. -# - # ---------------------------------------------------------------------------- # # Helper functions # ---------------------------------------------------------------------------- # @@ -83,10 +79,6 @@ add_path() { refresh } -# ---------------------------------------------------------------------------- # -# Function exports -# ---------------------------------------------------------------------------- # - export -f clean update upgrade install install_file add_ppa add_key run \ link_folder indent not_installed refresh add_path diff --git a/tests/Makefile b/tests/Makefile index b133a97..25e5223 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -1,6 +1,4 @@ -# dotfiles tests Makefile SHELL := /bin/bash all: - source ${HOME}/.bashrc poetry install poetry run pytest