further cleanup
update docs and tests
This commit is contained in:
12
.github/workflows/main.yml
vendored
Normal file
12
.github/workflows/main.yml
vendored
Normal 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
|
||||
@@ -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"]
|
||||
|
||||
15
Makefile
15
Makefile
@@ -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
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
Collection of tracked dotfiles and supporting install scripts.
|
||||
Tested on and compatible with:
|
||||
* Ubuntu 19.04
|
||||
* Ubuntu 18.04
|
||||
|
||||
## Install
|
||||
|
||||
|
||||
103
bash/.bashrc
103
bash/.bashrc
@@ -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
|
||||
|
||||
45
bootstrap.sh
45
bootstrap.sh
@@ -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
|
||||
# $ wget path.to/bootstrap.sh -qO - | bash
|
||||
# $ ./bootstrap.sh
|
||||
# $ /path/to/bootstrap.sh
|
||||
#
|
||||
# ii. Run explicitly in a bash shell.
|
||||
# ii. Download and run script
|
||||
#
|
||||
# $ bash bootstrap.sh
|
||||
# $ bash /path/to/bootstrap.sh
|
||||
# $ wget path.to/bootstrap.sh -qO - | bash
|
||||
# a. non-interactively
|
||||
# $ 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
|
||||
|
||||
@@ -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
|
||||
|
||||
3
fish/functions/update.fish
Normal file
3
fish/functions/update.fish
Normal file
@@ -0,0 +1,3 @@
|
||||
function update -d 'run dotfiles install'
|
||||
make --directory="$WORKSPACE/dotfiles"
|
||||
end
|
||||
11
install.sh
11
install.sh
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
24
install/20-nvm.sh
Executable 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
|
||||
@@ -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"
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user