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 # Filesystem copy steps
# ---------------------------------------------------------------------------- # # ---------------------------------------------------------------------------- #
ADD --chown=test-user . "$WORKSPACE/dotfiles"
WORKDIR "$WORKSPACE/dotfiles" WORKDIR "$WORKSPACE/dotfiles"
ADD --chown=test-user . .
USER test-user
# ---------------------------------------------------------------------------- # # ---------------------------------------------------------------------------- #
# Install steps # Install steps
# ---------------------------------------------------------------------------- # # ---------------------------------------------------------------------------- #
USER test-user RUN make
RUN make install
# ---------------------------------------------------------------------------- # # ---------------------------------------------------------------------------- #
# Test steps # 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) # Local target commands (warning: affects local environment)
# ---------------------------------------------------------------------------- # # ---------------------------------------------------------------------------- #
.PHONY: install clean .PHONY: clean
# Install dotfiles locally # Install dotfiles locally
install: all:
./bootstrap.sh ./bootstrap.sh
# Clean up after install # Clean up after install
@@ -15,16 +15,17 @@ clean:
# ---------------------------------------------------------------------------- # # ---------------------------------------------------------------------------- #
# Docker commands # Docker commands
# ---------------------------------------------------------------------------- # # ---------------------------------------------------------------------------- #
.PHONY: build run use .PHONY: build test start
# Build and tag docker image # Build and tag docker image
build: build:
docker build . -t dotfiles docker build . -t dotfiles --build-arg
# Run tests in docker container # Run tests in docker container (args to specify test)
run: test:
docker build . -t dotfiles --build-args
docker run dotfiles docker run dotfiles
# Launch bash in docker container # Launch bash in docker container
use: start:
docker run -it dotfiles /bin/bash docker run -it dotfiles /bin/bash

View File

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

View File

@@ -1,3 +1,13 @@
# ---------------------------------------------------------------------------- #
# Cross-shell
# ---------------------------------------------------------------------------- #
# config
XDG_CONFIG_HOME="$HOME/.config"
# workspace
WORKSPACE="$HOME/workspace"
# .local # .local
export PATH="$HOME/.local/bin:$PATH" export PATH="$HOME/.local/bin:$PATH"
@@ -5,7 +15,100 @@ export PATH="$HOME/.local/bin:$PATH"
PYENV_ROOT="$HOME/.pyenv" PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/bin:$PATH" export PATH="$PYENV_ROOT/bin:$PATH"
export PATH="$PYENV_ROOT/shims:$PATH" export PATH="$PYENV_ROOT/shims:$PATH"
[ -x "$(command -v pyenv)" ] && eval "$(pyenv init -)"
# poetry # poetry
POETRY_ROOT="$HOME/.poetry" POETRY_ROOT="$HOME/.poetry"
export PATH="$POETRY_ROOT/bin:$PATH" 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 #!/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. # Installs git using `apt-get` if not in $PATH
# Pulls latest dotfiles repository. # 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 # $ ./bootstrap.sh
# $ bash /path/to/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
# #
# ii. Run explicitly in a bash shell. # b. interactively
# # $ bash <(wget -qO- path.to/bootstrap.sh)
# $ 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)
# #
# #
# Configuration: # Configuration
# #
# $REPOSITORY - GitHub repository to clone # $REPOSITORY - GitHub repository to clone
# @default "andrejusk/dotfiles" # @default "andrejusk/dotfiles"
@@ -39,7 +44,7 @@
# @default "install.sh" # @default "install.sh"
# #
# $FAST_MODE - whether to skip git (and speed up install steps) # $FAST_MODE - whether to skip git (and speed up install steps)
# @defualt unset, i.e. false # @defualt false
# #
# #
set -o pipefail set -o pipefail
@@ -81,7 +86,7 @@ if [ -z "$FAST_MODE" ]; then
# Ensure latest is pulled # Ensure latest is pulled
echo "pulling latest..." echo "pulling latest..."
if [[ ! -d $dotfiles_dir ]]; then if ! [ -d "$dotfiles_dir" ]; then
mkdir -p "$dotfiles_dir" mkdir -p "$dotfiles_dir"
git clone -q "$repository_url" "$dotfiles_dir" git clone -q "$repository_url" "$dotfiles_dir"
else else

View File

@@ -1,3 +1,13 @@
# ---------------------------------------------------------------------------- #
# Cross-shell
# ---------------------------------------------------------------------------- #
# config
set XDG_CONFIG_HOME $HOME/.config
# workspace
set WORKSPACE $HOME/workspace
# .local # .local
set -x PATH $HOME/.local/bin $PATH set -x PATH $HOME/.local/bin $PATH
@@ -5,10 +15,22 @@ set -x PATH $HOME/.local/bin $PATH
set PYENV_ROOT $HOME/.pyenv set PYENV_ROOT $HOME/.pyenv
set -x PATH $PYENV_ROOT/bin $PATH set -x PATH $PYENV_ROOT/bin $PATH
set -x PATH $PYENV_ROOT/shims $PATH set -x PATH $PYENV_ROOT/shims $PATH
type -q pyenv && pyenv init - | source
# poetry # poetry
set PYENV_ROOT $HOME/.pyenv set POETRY_ROOT $HOME/.poetry
set -x PATH $PYENV_ROOT/bin $PATH set -x PATH $POETRY_ROOT/bin $PATH
# nvm
# set NVM_ROOT $HOME/.nvm
# set -x PATH $NVM_ROOT/bin $PATH
#
#
# ---------------------------------------------------------------------------- #
# Fish specific
# ---------------------------------------------------------------------------- #
# Wipe greeting # Wipe greeting
set fish_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" export install_dir="$dotfiles_dir/install"
readonly script_filter="$install_dir/*.sh" # Don't escape to unwrap glob readonly script_filter="$install_dir/*.sh" # Don't escape to unwrap glob
for script in $script_filter; do for script in $script_filter; do
# Avoid pattern matching self
[ -e "$script" ] || continue [ -e "$script" ] || continue
# Log execution # Get script name, split by dash
script_name="$(basename "$script" ".sh")" 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 # Run and indent output
chmod +x "$script" chmod +x "$script"

View File

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

View File

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

View File

@@ -5,7 +5,6 @@
# #
# 1. pyenv is installed # 1. pyenv is installed
export PYENV_ROOT="$HOME/.pyenv"
if not_installed "pyenv"; then if not_installed "pyenv"; then
printf "Installing pyenv...\n" 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" printf "Installing keybase...\n"
curl --remote-name https://prerelease.keybase.io/keybase_amd64.deb curl --remote-name https://prerelease.keybase.io/keybase_amd64.deb
install ./keybase_amd64.deb install keybase_amd64.deb
rm ./keybase_amd64.deb rm keybase_amd64.deb
fi fi
printf "keybase is installed\n" printf "keybase is installed\n"

View File

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

View File

@@ -1,17 +1,45 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# #
# Verifies dotfiles install # Verifies dotfiles installed binaries correctly
# #
from distutils.spawn import find_executable from distutils.spawn import find_executable
from typing import List from typing import List
from subprocess import run, CalledProcessError
import pytest 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] = [ binaries: List[str] = [
# shells # extend shells
"sh", "bash", "fish", *shells,
# tools # tools
"git", "git",
@@ -19,25 +47,25 @@ binaries: List[str] = [
"docker", "docker-compose", "docker", "docker-compose",
"screenfetch", "screenfetch",
# languages # language: python
"pyenv", "pyenv", "python3", "pip3", "poetry",
"python3",
"poetry", # langauge: node
"nvm", "node", "npm", "yarn",
] ]
def binary_in_path(binary: str) -> bool: # ---------------------------------------------------------------------------- #
""" # Tests
Helper function to check whether `binary` is in PATH. # ---------------------------------------------------------------------------- #
""" @pytest.mark.parametrize("shell", shells)
def test_shells(shell: str):
return find_executable(binary) is not None """ Assert all shells we expect are in PATH. """
assert in_path(shell)
@pytest.mark.parametrize("binary", binaries) @pytest.mark.parametrize("binary", binaries)
def test_binaries(binary: str): @pytest.mark.parametrize("shell", shells)
""" def test_binaries(shell: str, binary: str):
Asserts all binaries are in PATH. """ Asserts all binaries are in all shells. """
""" assert in_shell_path(shell, binary)
assert binary_in_path(binary)