further cleanup

update docs and tests
This commit is contained in:
Andrejus
2020-03-03 00:05:41 +00:00
parent 1c7586139f
commit 638c907c06
17 changed files with 266 additions and 68 deletions

12
.github/workflows/main.yml vendored Normal file
View File

@@ -0,0 +1,12 @@
on: [push]
jobs:
build:
runs-on: ubuntu-latest
name:
steps:
- uses: actions/checkout@v2
- name: Build Docker image
run: make build
- name: Test Docker image
run: make test

View File

@@ -26,18 +26,19 @@ RUN echo "$USER ALL=(ALL) NOPASSWD: ALL" \
# Filesystem copy steps
# ---------------------------------------------------------------------------- #
ADD --chown=test-user . "$WORKSPACE/dotfiles"
WORKDIR "$WORKSPACE/dotfiles"
ADD --chown=test-user . .
USER test-user
# ---------------------------------------------------------------------------- #
# Install steps
# ---------------------------------------------------------------------------- #
USER test-user
RUN make install
RUN make
# ---------------------------------------------------------------------------- #
# Test steps
# ---------------------------------------------------------------------------- #
CMD ["cd", "tests", "&&", "make"]
WORKDIR "$WORKSPACE/dotfiles/tests"
ENTRYPOINT ["make"]

View File

@@ -2,10 +2,10 @@
# ---------------------------------------------------------------------------- #
# Local target commands (warning: affects local environment)
# ---------------------------------------------------------------------------- #
.PHONY: install clean
.PHONY: clean
# Install dotfiles locally
install:
all:
./bootstrap.sh
# Clean up after install
@@ -15,16 +15,17 @@ clean:
# ---------------------------------------------------------------------------- #
# Docker commands
# ---------------------------------------------------------------------------- #
.PHONY: build run use
.PHONY: build test start
# Build and tag docker image
build:
docker build . -t dotfiles
docker build . -t dotfiles --build-arg
# Run tests in docker container
run:
# Run tests in docker container (args to specify test)
test:
docker build . -t dotfiles --build-args
docker run dotfiles
# Launch bash in docker container
use:
start:
docker run -it dotfiles /bin/bash

View File

@@ -2,7 +2,7 @@
Collection of tracked dotfiles and supporting install scripts.
Tested on and compatible with:
* Ubuntu 19.04
* Ubuntu 18.04
## Install

View File

@@ -1,3 +1,13 @@
# ---------------------------------------------------------------------------- #
# Cross-shell
# ---------------------------------------------------------------------------- #
# config
XDG_CONFIG_HOME="$HOME/.config"
# workspace
WORKSPACE="$HOME/workspace"
# .local
export PATH="$HOME/.local/bin:$PATH"
@@ -5,7 +15,100 @@ export PATH="$HOME/.local/bin:$PATH"
PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/bin:$PATH"
export PATH="$PYENV_ROOT/shims:$PATH"
[ -x "$(command -v pyenv)" ] && eval "$(pyenv init -)"
# poetry
POETRY_ROOT="$HOME/.poetry"
export PATH="$POETRY_ROOT/bin:$PATH"
# nvm
NVM_DIR="$HOME/.nvm"
export PATH="$NVM_DIR/bin:$PATH"
[ -s "$NVM_DIR/nvm.sh" ] && source "$NVM_DIR/nvm.sh"
[ -s "$NVM_DIR/bash_completion" ] && source "$NVM_DIR/bash_completion"
# ---------------------------------------------------------------------------- #
# Bash specific
# ---------------------------------------------------------------------------- #
# set a fancy prompt (non-color, unless we know we "want" color)
case "$TERM" in
xterm-color|*-256color) color_prompt=yes;;
esac
# uncomment for a colored prompt, if the terminal has the capability; turned
# off by default to not distract the user: the focus in a terminal window
# should be on the output of commands, not on the prompt
force_color_prompt=yes
if [ -n "$force_color_prompt" ]; then
if [ -x /usr/bin/tput ] && tput setaf 1 >&/dev/null; then
# We have color support; assume it's compliant with Ecma-48
# (ISO/IEC-6429). (Lack of such support is extremely rare, and such
# a case would tend to support setf rather than setaf.)
color_prompt=yes
else
color_prompt=
fi
fi
if [ "$color_prompt" = yes ]; then
PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '
else
PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ '
fi
unset color_prompt force_color_prompt
# If this is an xterm set the title to user@host:dir
case "$TERM" in
xterm*|rxvt*)
PS1="\[\e]0;${debian_chroot:+($debian_chroot)}\u@\h: \w\a\]$PS1"
;;
*)
;;
esac
# enable color support of ls and also add handy aliases
if [ -x /usr/bin/dircolors ]; then
test -r ~/.dircolors && eval "$(dircolors -b ~/.dircolors)" || eval "$(dircolors -b)"
alias ls='ls --color=auto'
#alias dir='dir --color=auto'
#alias vdir='vdir --color=auto'
alias grep='grep --color=auto'
alias fgrep='fgrep --color=auto'
alias egrep='egrep --color=auto'
fi
# colored GCC warnings and errors
#export GCC_COLORS='error=01;31:warning=01;35:note=01;36:caret=01;32:locus=01:quote=01'
# some more ls aliases
alias ll='ls -alF'
alias la='ls -A'
alias l='ls -CF'
# Add an "alert" alias for long running commands. Use like so:
# sleep 10; alert
alias alert='notify-send --urgency=low -i "$([ $? = 0 ] && echo terminal || echo error)" "$(history|tail -n1|sed -e '\''s/^\s*[0-9]\+\s*//;s/[;&|]\s*alert$//'\'')"'
# Alias definitions.
# You may want to put all your additions into a separate file like
# ~/.bash_aliases, instead of adding them here directly.
# See /usr/share/doc/bash-doc/examples in the bash-doc package.
if [ -f ~/.bash_aliases ]; then
. ~/.bash_aliases
fi
# enable programmable completion features (you don't need to enable
# this, if it's already enabled in /etc/bash.bashrc and /etc/profile
# sources /etc/bash.bashrc).
if ! shopt -oq posix; then
if [ -f /usr/share/bash-completion/bash_completion ]; then
. /usr/share/bash-completion/bash_completion
elif [ -f /etc/bash_completion ]; then
. /etc/bash_completion
fi
fi

View File

@@ -1,33 +1,38 @@
#!/usr/bin/env bash
#
# Script to set up dotfiles repository and run installer.
# Script to set up and run dotfiles installer
#
# Installs git using apt-get if not in $PATH.
# Pulls latest dotfiles repository.
# Installs git using `apt-get` if not in $PATH
# step may be skipped,
# @see $FAST_MODE
#
# Pulls latest target repository using git
# @see $REPOSITORY
#
# Creates workspace if one doesn't already exist
# @see $WORKSPACE
#
# Runs installer
# @see $INSTALLER
#
#
# Usage:
# Usage
#
# i. Run script.
# i. Run script
#
# $ bash bootstrap.sh
# $ bash /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
#
# ii. Run explicitly in a bash shell.
#
# $ bash bootstrap.sh
# $ bash /path/to/bootstrap.sh
# $ wget path.to/bootstrap.sh -qO - | bash
#
# iii. Source into existing shell.
#
# $ source bootstrap.sh
# $ source /path/to/bootstrap.sh
# $ source <(wget -q path.to/bootstrap.sh)
# b. interactively
# $ bash <(wget -qO- path.to/bootstrap.sh)
#
#
# Configuration:
# Configuration
#
# $REPOSITORY - GitHub repository to clone
# @default "andrejusk/dotfiles"
@@ -39,7 +44,7 @@
# @default "install.sh"
#
# $FAST_MODE - whether to skip git (and speed up install steps)
# @defualt unset, i.e. false
# @defualt false
#
#
set -o pipefail
@@ -81,7 +86,7 @@ if [ -z "$FAST_MODE" ]; then
# Ensure latest is pulled
echo "pulling latest..."
if [[ ! -d $dotfiles_dir ]]; then
if ! [ -d "$dotfiles_dir" ]; then
mkdir -p "$dotfiles_dir"
git clone -q "$repository_url" "$dotfiles_dir"
else

View File

@@ -1,3 +1,13 @@
# ---------------------------------------------------------------------------- #
# Cross-shell
# ---------------------------------------------------------------------------- #
# config
set XDG_CONFIG_HOME $HOME/.config
# workspace
set WORKSPACE $HOME/workspace
# .local
set -x PATH $HOME/.local/bin $PATH
@@ -5,10 +15,22 @@ set -x PATH $HOME/.local/bin $PATH
set PYENV_ROOT $HOME/.pyenv
set -x PATH $PYENV_ROOT/bin $PATH
set -x PATH $PYENV_ROOT/shims $PATH
type -q pyenv && pyenv init - | source
# poetry
set PYENV_ROOT $HOME/.pyenv
set -x PATH $PYENV_ROOT/bin $PATH
set POETRY_ROOT $HOME/.poetry
set -x PATH $POETRY_ROOT/bin $PATH
# nvm
# set NVM_ROOT $HOME/.nvm
# set -x PATH $NVM_ROOT/bin $PATH
#
#
# ---------------------------------------------------------------------------- #
# Fish specific
# ---------------------------------------------------------------------------- #
# Wipe greeting
set fish_greeting

View File

@@ -0,0 +1,3 @@
function update -d 'run dotfiles install'
make --directory="$WORKSPACE/dotfiles"
end

View File

@@ -27,13 +27,16 @@ touch "$install_lock_file" # Requires clean
export install_dir="$dotfiles_dir/install"
readonly script_filter="$install_dir/*.sh" # Don't escape to unwrap glob
for script in $script_filter; do
# Avoid pattern matching self
[ -e "$script" ] || continue
# Log execution
# Get script name, split by dash
script_name="$(basename "$script" ".sh")"
printf "\nRunning ${C_YELLOW}$script_name${C_NC}...\n${C_DGRAY}"
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"

View File

@@ -2,7 +2,7 @@
#
# apt update and upgrade
#
# Install list of packages in ./00-apt-pkglist
# Install list of packages in 00-apt-pkglist
#
# pre clean

View File

@@ -39,12 +39,11 @@ printf "fish is default login shell\n"
# 3. fish dotfiles are symlinked
fish_source="$dotfiles_dir/fish"
fish_target="$HOME/.config/fish"
fish_target="$XDG_CONFIG_HOME/fish"
link_folder "$fish_source" "$fish_target"
printf "fish dotfiles linked\n"
# 4. fisher is installed
XDG_CONFIG_HOME="$HOME/.config"
fisher_location="$XDG_CONFIG_HOME/fish/functions/fisher.fish"
if ! [ -f "$fisher_location" ]; then
@@ -57,5 +56,3 @@ fi
printf "fisher is installed, updating...\n"
fish -c "fisher"
fish -c "fisher --version"
export XDG_CONFIG_HOME

View File

@@ -5,7 +5,6 @@
#
# 1. pyenv is installed
export PYENV_ROOT="$HOME/.pyenv"
if not_installed "pyenv"; then
printf "Installing pyenv...\n"

24
install/20-nvm.sh Executable file
View File

@@ -0,0 +1,24 @@
#!/usr/bin/env bash
#
# After running this script:
# 1. nvm is installed
#
# 1. nvm is installed
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
fi
printf "nvm is installed, upgrading...\n"
git --git-dir="$NVM_DIR/.git" pull
nvm update --lts node
nvm update node
nvm update npm
nvm --version
node --version
npm --version

View File

@@ -10,8 +10,8 @@ if not_installed "keybase"; then
printf "Installing keybase...\n"
curl --remote-name https://prerelease.keybase.io/keybase_amd64.deb
install ./keybase_amd64.deb
rm ./keybase_amd64.deb
install keybase_amd64.deb
rm keybase_amd64.deb
fi
printf "keybase is installed\n"

View File

@@ -1,6 +1,6 @@
# dotfiles tests Makefile
all: SHELL:=/bin/bash
SHELL := /bin/bash
all:
source ~/.bashrc
source ${HOME}/.bashrc
poetry install
poetry run pytest

View File

@@ -1,17 +1,45 @@
#!/usr/bin/env python3
#
# Verifies dotfiles install
# Verifies dotfiles installed binaries correctly
#
from distutils.spawn import find_executable
from typing import List
from subprocess import run, CalledProcessError
import pytest
# List of binaries to test
# ---------------------------------------------------------------------------- #
# Helper functions
# ---------------------------------------------------------------------------- #
def in_path(binary: str) -> bool:
"""
Helper function to check whether `binary` is in PATH.
"""
return find_executable(binary) is not None
def in_shell_path(shell: str, binary: str) -> bool:
"""
Helper function to check whether `binary` is in interactive shell's PATH.
"""
command = "{0} -i -c 'command -v {1}'".format(shell, binary)
try:
result = run(command, shell=True)
return (result.returncode == 0)
except:
return False
# ---------------------------------------------------------------------------- #
# Test fixtures
# ---------------------------------------------------------------------------- #
shells: List[str] = [
'sh', 'bash', 'fish',
]
binaries: List[str] = [
# shells
"sh", "bash", "fish",
# extend shells
*shells,
# tools
"git",
@@ -19,25 +47,25 @@ binaries: List[str] = [
"docker", "docker-compose",
"screenfetch",
# languages
"pyenv",
"python3",
"poetry",
# language: python
"pyenv", "python3", "pip3", "poetry",
# langauge: node
"nvm", "node", "npm", "yarn",
]
def binary_in_path(binary: str) -> bool:
"""
Helper function to check whether `binary` is in PATH.
"""
return find_executable(binary) is not None
# ---------------------------------------------------------------------------- #
# Tests
# ---------------------------------------------------------------------------- #
@pytest.mark.parametrize("shell", shells)
def test_shells(shell: str):
""" Assert all shells we expect are in PATH. """
assert in_path(shell)
@pytest.mark.parametrize("binary", binaries)
def test_binaries(binary: str):
"""
Asserts all binaries are in PATH.
"""
assert binary_in_path(binary)
@pytest.mark.parametrize("shell", shells)
def test_binaries(shell: str, binary: str):
""" Asserts all binaries are in all shells. """
assert in_shell_path(shell, binary)