diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..1870bf8 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,4 @@ +.gitignore +.dockerignore +Dockerfile +README.md diff --git a/.gitignore b/.gitignore index 4fc0043..87c32f0 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,7 @@ +# install .dotlock -*.deb \ No newline at end of file +*.deb + +# pytest +**/__pycache__ +**/.pytest_cache diff --git a/.python-version b/.python-version new file mode 100644 index 0000000..7c69a55 --- /dev/null +++ b/.python-version @@ -0,0 +1 @@ +3.7.0 diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..167ae2e --- /dev/null +++ b/Dockerfile @@ -0,0 +1,47 @@ +from ubuntu:bionic + +# ---------------------------------------------------------------------------- # +# (usually) Cached steps +# ---------------------------------------------------------------------------- # + +# Set variables up, FAST_MODE to prevent git and upgrade +ENV FAST_MODE="true" +ENV WORKSPACE="$HOME/workspace" + +# Install sudo for compatibility, git since it is skipped, make +# Triple quiet mode (-qq implies -y, pipe to /dev/null) +RUN apt-get -qq update && \ + apt-get -qq install sudo git make \ + < /dev/null > /dev/null + +# Create user with sudo priviledge +ENV USER="test-user" +RUN useradd --create-home -m $USER && \ + adduser $USER sudo +RUN echo "$USER ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers + +# ---------------------------------------------------------------------------- # +# Filesystem copy steps +# ---------------------------------------------------------------------------- # + +# Copy dotfiles in +ADD --chown=test-user . "$WORKSPACE/dotfiles" +WORKDIR "$WORKSPACE/dotfiles" + +# Allow execution +RUN chmod +x ./bootstrap.sh + +# ---------------------------------------------------------------------------- # +# Install steps +# ---------------------------------------------------------------------------- # + +# Run installer +USER test-user +RUN make install + +# ---------------------------------------------------------------------------- # +# Test steps +# ---------------------------------------------------------------------------- # + +# Run tests +RUN make test || true diff --git a/Makefile b/Makefile index a95d7a2..7c5f042 100644 --- a/Makefile +++ b/Makefile @@ -2,6 +2,18 @@ clean: rm -f .dotlock +.PHONY: install +install: + bash bootstrap.sh + +.PHONY: test +test: + bash test.sh + +.PHONY: build +build: + docker build . -t dotfiles:latest + .PHONY: run run: - bash bootstrap.sh + docker run -it dotfiles:latest /bin/bash diff --git a/README.md b/README.md index 9dd745f..0324df7 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,7 @@ Shell: 🐟 fish (+ fisher) Tools: * docker (+ docker-compose) * keybase +* screenfetch Languages: * python (+ poetry, pyenv) diff --git a/bash/.bashrc b/bash/.bashrc new file mode 100644 index 0000000..fd3e09d --- /dev/null +++ b/bash/.bashrc @@ -0,0 +1,7 @@ +# pyenv +export PATH="$HOME/.pyenv/bin:$PATH" +eval "$(pyenv init -)" +eval "$(pyenv virtualenv-init -)" + +# poetry +export PATH="$HOME/.poetry/bin:$PATH" diff --git a/bootstrap.sh b/bootstrap.sh index b8e5c6a..c2e4d67 100644 --- a/bootstrap.sh +++ b/bootstrap.sh @@ -24,25 +24,32 @@ # Configuration: # # $REPOSITORY - GitHub repository to clone -# @default "andrejusk/dotfiles" +# @default "andrejusk/dotfiles" # # $WORKSPACE - parent directory to clone repository into -# @default "$HOME/workspace" +# @default "$HOME/workspace" # # $INSTALLER - installer file name -# @default "install.sh" +# @default "install.sh" +# +# $FAST_MODE - whether to skip git (and speed up install steps) +# @defualt unset # # set -o pipefail echo "setting up..." # Variables: $REPOSITORY -if [ -z "$REPOSITORY" ]; then REPOSITORY="andrejusk/dotfiles"; fi +if [ -z "$REPOSITORY" ]; then + REPOSITORY="andrejusk/dotfiles" +fi readonly repository_url="git@github.com:$REPOSITORY.git" echo "using repository: $repository_url" # Variables: $WORKSPACE -if [ -z "$WORKSPACE" ]; then WORKSPACE="$HOME/workspace"; fi +if [ -z "$WORKSPACE" ]; then + WORKSPACE="$HOME/workspace" +fi readonly dotfiles_dir="$WORKSPACE/dotfiles" echo "using dir: $dotfiles_dir" @@ -51,23 +58,29 @@ if [ -z "$INSTALLER" ]; then INSTALLER="install.sh"; fi readonly installer="$dotfiles_dir/$INSTALLER" echo "using installer: $installer" -# 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 +# Pull latest git if not skipped +if [ -z "$FAST_MODE" ]; then + + # 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" + git clone -q "$repository_url" "$dotfiles_dir" + else + git --git-dir="$dotfiles_dir/.git" fetch -q + git --git-dir="$dotfiles_dir/.git" rebase -q --autostash FETCH_HEAD + fi -# Ensure repository is up to date -echo "pulling latest..." -if [[ ! -d $dotfiles_dir ]]; then - mkdir -p "$dotfiles_dir" - git clone -q "$repository_url" "$dotfiles_dir" -else - git --git-dir="$dotfiles_dir/.git" fetch -q - git --git-dir="$dotfiles_dir/.git" rebase -q --autostash FETCH_HEAD fi # Install dotfiles cd "$dotfiles_dir" source "$installer" +echo "done!" diff --git a/fish/config.fish b/fish/config.fish index e127afe..16e5907 100644 --- a/fish/config.fish +++ b/fish/config.fish @@ -1,9 +1,7 @@ -# Ensure fisher is installed -if not functions -q fisher - set -q XDG_CONFIG_HOME; or set XDG_CONFIG_HOME ~/.config - curl https://git.io/fisher --create-dirs -sLo $XDG_CONFIG_HOME/fish/functions/fisher.fish - fish -c fisher -end +# Pyenv +export PATH="$HOME/.pyenv/bin:$PATH" +eval (pyenv init -) +eval (pyenv virtualenv-init -) # Poetry set -gx PATH $HOME/.poetry/bin $PATH diff --git a/install/00-apt-pkglist b/install/00-apt-pkglist index 4226899..6f9a05c 100644 --- a/install/00-apt-pkglist +++ b/install/00-apt-pkglist @@ -1,5 +1,7 @@ curl make net-tools +openssh-client openssh-server screenfetch +software-properties-common diff --git a/install/00-apt.sh b/install/00-apt.sh index d17065c..0a39079 100644 --- a/install/00-apt.sh +++ b/install/00-apt.sh @@ -4,15 +4,16 @@ # # Install list of packages in ./00-apt-pkglist # -readonly package_list_file="00-apt-pkglist" -# apt update and upgrade non-interactively +# apt update, upgrade if not fast update -upgrade +if [ -z "$FAST_MODE" ]; then + upgrade +fi # Package installs -readonly package_list=$(cat $install_dir/$package_list_file) # Don't escape list -install $package_list +readonly package_list_file="$install_dir/00-apt-pkglist" +install_file $package_list_file # Log version -cat /etc/os-release \ No newline at end of file +cat /etc/os-release diff --git a/install/01-bash.sh b/install/01-bash.sh new file mode 100644 index 0000000..b9dd090 --- /dev/null +++ b/install/01-bash.sh @@ -0,0 +1,11 @@ +#!/usr/bin/env bash +# +# After running this script: +# 1. bash dotfiles are symlinked +# + +# 1. bash dotfiles are symlinked +readonly bash_source="$dotfiles_dir/bash" +readonly bash_target="$HOME" +link_folder "$bash_source" "$bash_target" +printf "bash dotfiles are linked\n" diff --git a/install/01-fish.sh b/install/02-fish.sh similarity index 81% rename from install/01-fish.sh rename to install/02-fish.sh index e3cedc8..8d47f09 100644 --- a/install/01-fish.sh +++ b/install/02-fish.sh @@ -18,6 +18,11 @@ if not_installed "fish"; then # Install fish install fish + # Install fisher + set -q XDG_CONFIG_HOME; or set XDG_CONFIG_HOME ~/.config + curl https://git.io/fisher --create-dirs -sLo $XDG_CONFIG_HOME/fish/functions/fisher.fish + fish -c fisher + fi printf "fish is installed\n" fish --version diff --git a/install/02-ssh.sh b/install/03-ssh.sh similarity index 100% rename from install/02-ssh.sh rename to install/03-ssh.sh diff --git a/install/10-git.sh b/install/04-git.sh similarity index 100% rename from install/10-git.sh rename to install/04-git.sh diff --git a/install/20-pyenv.sh b/install/10-pyenv.sh similarity index 69% rename from install/20-pyenv.sh rename to install/10-pyenv.sh index 3ed3e16..6a7ba49 100644 --- a/install/20-pyenv.sh +++ b/install/10-pyenv.sh @@ -15,14 +15,20 @@ if not_installed "pyenv"; then libreadline-dev libsqlite3-dev wget curl llvm libncurses5-dev libncursesw5-dev \ xz-utils tk-dev libffi-dev liblzma-dev python-openssl git + # Add to install path + add_path "$HOME/.pyenv/bin" + # Install pyenv # see https://github.com/pyenv/pyenv-installer - run "https://github.com/pyenv/pyenv-installer/raw/master/bin/pyenv-installer" bash + run "https://github.com/pyenv/pyenv-installer/raw/master/bin/pyenv-installer" \ + "bash" + refresh - # Add to install path and refresh - export PATH="$HOME/.pyenv/bin:$PATH" - hash -r + eval "$(pyenv init -)" + eval "$(pyenv virtualenv-init -)" fi -printf "pyenv is installed\n" +printf "pyenv is installed, upgrading...\n" +readonly pyenv_root=$(pyenv root) +git --git-dir="$pyenv_root" pull pyenv --version diff --git a/install/11-python.sh b/install/11-python.sh new file mode 100644 index 0000000..41c9dd4 --- /dev/null +++ b/install/11-python.sh @@ -0,0 +1,20 @@ +#!/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" + + pyenv install 3.7.0 + pyenv global 3.7.0 + pyenv local 3.7.0 + +fi +printf "python3 and pip3 are installed, upgrading...\n" +pip3 install --upgrade pip +python3 --version +pip3 --version diff --git a/install/22-poetry.sh b/install/12-poetry.sh similarity index 61% rename from install/22-poetry.sh rename to install/12-poetry.sh index cfc3212..b703bb4 100644 --- a/install/22-poetry.sh +++ b/install/12-poetry.sh @@ -10,7 +10,9 @@ if not_installed "poetry"; then printf "Installing poetry...\n" # Install poetry - run "https://raw.githubusercontent.com/python-poetry/poetry/master/get-poetry.py" "python" + pip3 install --user poetry fi -printf "poetry is installed\n" +printf "poetry is installed, upgrading...\n" +pip3 install --upgrade poetry +poetry --version diff --git a/install/12-docker.sh b/install/20-docker.sh similarity index 81% rename from install/12-docker.sh rename to install/20-docker.sh index f5aa72a..f1b5551 100644 --- a/install/12-docker.sh +++ b/install/20-docker.sh @@ -27,6 +27,10 @@ if not_installed "docker"; then # Install install docker-ce + # Chown + sudo chown "$USER":"$USER" "$HOME/.docker" -R + sudo chmod g+rwx "$HOME/.docker" -R + fi printf "docker is installed\n" docker --version @@ -37,12 +41,12 @@ if not_installed "docker-compose"; then printf "Installing docker-compose...\n" # Docker-compose - readonly docker_compose_url="https://github.com/docker/compose/releases/download/1.21.2/docker-compose-$(uname -s)-$(uname -m)" - sudo curl -L "$docker_compose_url" -o /usr/local/bin/docker-compose - sudo chmod +x /usr/local/bin/docker-compose + pip3 install --user docker-compose + fi -printf "docker-compose is installed\n" +printf "docker-compose is installed, upgrading\n" +pip3 install --upgrade docker-compose docker-compose --version # 3. docker group exists diff --git a/install/11-keybase.sh b/install/21-keybase.sh similarity index 100% rename from install/11-keybase.sh rename to install/21-keybase.sh diff --git a/install/21-python.sh b/install/21-python.sh deleted file mode 100644 index f6fc84b..0000000 --- a/install/21-python.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/usr/bin/env bash -# -# After running this script: -# 1. python is installed -# - -# 1. python is installed -if not_installed "python"; then - - printf "Installing python...\n" - - pyenv install -s 3.7.0 - pyenv global 3.7.0 - -fi -printf "python is installed\n" diff --git a/install/99-apt-clean.sh b/install/99-apt-clean.sh index f59f349..10af6e3 100644 --- a/install/99-apt-clean.sh +++ b/install/99-apt-clean.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash # Clean up -sudo apt-get -qqy autoremove -sudo apt-get -qqy autoclean +sudo apt-get -y autoremove +sudo apt-get -y autoclean diff --git a/ssh/config b/ssh/config index bda6558..fef79b8 100644 --- a/ssh/config +++ b/ssh/config @@ -2,4 +2,4 @@ Host * IgnoreUnknown UseKeychain UseKeychain yes AddKeysToAgent yes - IdentityFile ~/.ssh/id_rsa \ No newline at end of file + IdentityFile ~/.ssh/id_rsa diff --git a/test.sh b/test.sh new file mode 100644 index 0000000..0092d91 --- /dev/null +++ b/test.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash +# +# Invokes all test scripts. +# +set -euo pipefail + +cd ./tests +poetry install +poetry run pytest diff --git a/tests/poetry.lock b/tests/poetry.lock new file mode 100644 index 0000000..d926550 --- /dev/null +++ b/tests/poetry.lock @@ -0,0 +1,212 @@ +[[package]] +category = "dev" +description = "Atomic file writes." +marker = "sys_platform == \"win32\"" +name = "atomicwrites" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +version = "1.3.0" + +[[package]] +category = "dev" +description = "Classes Without Boilerplate" +name = "attrs" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +version = "19.3.0" + +[package.extras] +azure-pipelines = ["coverage", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "zope.interface", "pytest-azurepipelines"] +dev = ["coverage", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "zope.interface", "sphinx", "pre-commit"] +docs = ["sphinx", "zope.interface"] +tests = ["coverage", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "zope.interface"] + +[[package]] +category = "dev" +description = "Cross-platform colored terminal text." +marker = "sys_platform == \"win32\"" +name = "colorama" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +version = "0.4.3" + +[[package]] +category = "dev" +description = "Read metadata from Python packages" +marker = "python_version < \"3.8\"" +name = "importlib-metadata" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" +version = "1.5.0" + +[package.dependencies] +zipp = ">=0.5" + +[package.extras] +docs = ["sphinx", "rst.linker"] +testing = ["packaging", "importlib-resources"] + +[[package]] +category = "dev" +description = "More routines for operating on iterables, beyond itertools" +name = "more-itertools" +optional = false +python-versions = ">=3.5" +version = "8.2.0" + +[[package]] +category = "dev" +description = "Core utilities for Python packages" +name = "packaging" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +version = "20.1" + +[package.dependencies] +pyparsing = ">=2.0.2" +six = "*" + +[[package]] +category = "dev" +description = "plugin and hook calling mechanisms for python" +name = "pluggy" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +version = "0.13.1" + +[package.dependencies] +[package.dependencies.importlib-metadata] +python = "<3.8" +version = ">=0.12" + +[package.extras] +dev = ["pre-commit", "tox"] + +[[package]] +category = "dev" +description = "library with cross-python path, ini-parsing, io, code, log facilities" +name = "py" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +version = "1.8.1" + +[[package]] +category = "dev" +description = "Python parsing module" +name = "pyparsing" +optional = false +python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" +version = "2.4.6" + +[[package]] +category = "dev" +description = "pytest: simple powerful testing with Python" +name = "pytest" +optional = false +python-versions = ">=3.5" +version = "5.3.5" + +[package.dependencies] +atomicwrites = ">=1.0" +attrs = ">=17.4.0" +colorama = "*" +more-itertools = ">=4.0.0" +packaging = "*" +pluggy = ">=0.12,<1.0" +py = ">=1.5.0" +wcwidth = "*" + +[package.dependencies.importlib-metadata] +python = "<3.8" +version = ">=0.12" + +[package.extras] +checkqa-mypy = ["mypy (v0.761)"] +testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "requests", "xmlschema"] + +[[package]] +category = "dev" +description = "Python 2 and 3 compatibility utilities" +name = "six" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +version = "1.14.0" + +[[package]] +category = "dev" +description = "Measures number of Terminal column cells of wide-character codes" +name = "wcwidth" +optional = false +python-versions = "*" +version = "0.1.8" + +[[package]] +category = "dev" +description = "Backport of pathlib-compatible object wrapper for zip files" +marker = "python_version < \"3.8\"" +name = "zipp" +optional = false +python-versions = ">=3.6" +version = "3.0.0" + +[package.extras] +docs = ["sphinx", "jaraco.packaging (>=3.2)", "rst.linker (>=1.9)"] +testing = ["jaraco.itertools", "func-timeout"] + +[metadata] +content-hash = "76f248e0ec62688089444c71c5e62af7c3ca83978a893d09e6592e3621985fab" +python-versions = "^3.7" + +[metadata.files] +atomicwrites = [ + {file = "atomicwrites-1.3.0-py2.py3-none-any.whl", hash = "sha256:03472c30eb2c5d1ba9227e4c2ca66ab8287fbfbbda3888aa93dc2e28fc6811b4"}, + {file = "atomicwrites-1.3.0.tar.gz", hash = "sha256:75a9445bac02d8d058d5e1fe689654ba5a6556a1dfd8ce6ec55a0ed79866cfa6"}, +] +attrs = [ + {file = "attrs-19.3.0-py2.py3-none-any.whl", hash = "sha256:08a96c641c3a74e44eb59afb61a24f2cb9f4d7188748e76ba4bb5edfa3cb7d1c"}, + {file = "attrs-19.3.0.tar.gz", hash = "sha256:f7b7ce16570fe9965acd6d30101a28f62fb4a7f9e926b3bbc9b61f8b04247e72"}, +] +colorama = [ + {file = "colorama-0.4.3-py2.py3-none-any.whl", hash = "sha256:7d73d2a99753107a36ac6b455ee49046802e59d9d076ef8e47b61499fa29afff"}, + {file = "colorama-0.4.3.tar.gz", hash = "sha256:e96da0d330793e2cb9485e9ddfd918d456036c7149416295932478192f4436a1"}, +] +importlib-metadata = [ + {file = "importlib_metadata-1.5.0-py2.py3-none-any.whl", hash = "sha256:b97607a1a18a5100839aec1dc26a1ea17ee0d93b20b0f008d80a5a050afb200b"}, + {file = "importlib_metadata-1.5.0.tar.gz", hash = "sha256:06f5b3a99029c7134207dd882428a66992a9de2bef7c2b699b5641f9886c3302"}, +] +more-itertools = [ + {file = "more-itertools-8.2.0.tar.gz", hash = "sha256:b1ddb932186d8a6ac451e1d95844b382f55e12686d51ca0c68b6f61f2ab7a507"}, + {file = "more_itertools-8.2.0-py3-none-any.whl", hash = "sha256:5dd8bcf33e5f9513ffa06d5ad33d78f31e1931ac9a18f33d37e77a180d393a7c"}, +] +packaging = [ + {file = "packaging-20.1-py2.py3-none-any.whl", hash = "sha256:170748228214b70b672c581a3dd610ee51f733018650740e98c7df862a583f73"}, + {file = "packaging-20.1.tar.gz", hash = "sha256:e665345f9eef0c621aa0bf2f8d78cf6d21904eef16a93f020240b704a57f1334"}, +] +pluggy = [ + {file = "pluggy-0.13.1-py2.py3-none-any.whl", hash = "sha256:966c145cd83c96502c3c3868f50408687b38434af77734af1e9ca461a4081d2d"}, + {file = "pluggy-0.13.1.tar.gz", hash = "sha256:15b2acde666561e1298d71b523007ed7364de07029219b604cf808bfa1c765b0"}, +] +py = [ + {file = "py-1.8.1-py2.py3-none-any.whl", hash = "sha256:c20fdd83a5dbc0af9efd622bee9a5564e278f6380fffcacc43ba6f43db2813b0"}, + {file = "py-1.8.1.tar.gz", hash = "sha256:5e27081401262157467ad6e7f851b7aa402c5852dbcb3dae06768434de5752aa"}, +] +pyparsing = [ + {file = "pyparsing-2.4.6-py2.py3-none-any.whl", hash = "sha256:c342dccb5250c08d45fd6f8b4a559613ca603b57498511740e65cd11a2e7dcec"}, + {file = "pyparsing-2.4.6.tar.gz", hash = "sha256:4c830582a84fb022400b85429791bc551f1f4871c33f23e44f353119e92f969f"}, +] +pytest = [ + {file = "pytest-5.3.5-py3-none-any.whl", hash = "sha256:ff615c761e25eb25df19edddc0b970302d2a9091fbce0e7213298d85fb61fef6"}, + {file = "pytest-5.3.5.tar.gz", hash = "sha256:0d5fe9189a148acc3c3eb2ac8e1ac0742cb7618c084f3d228baaec0c254b318d"}, +] +six = [ + {file = "six-1.14.0-py2.py3-none-any.whl", hash = "sha256:8f3cd2e254d8f793e7f3d6d9df77b92252b52637291d0f0da013c76ea2724b6c"}, + {file = "six-1.14.0.tar.gz", hash = "sha256:236bdbdce46e6e6a3d61a337c0f8b763ca1e8717c03b369e87a7ec7ce1319c0a"}, +] +wcwidth = [ + {file = "wcwidth-0.1.8-py2.py3-none-any.whl", hash = "sha256:8fd29383f539be45b20bd4df0dc29c20ba48654a41e661925e612311e9f3c603"}, + {file = "wcwidth-0.1.8.tar.gz", hash = "sha256:f28b3e8a6483e5d49e7f8949ac1a78314e740333ae305b4ba5defd3e74fb37a8"}, +] +zipp = [ + {file = "zipp-3.0.0-py3-none-any.whl", hash = "sha256:12248a63bbdf7548f89cb4c7cda4681e537031eda29c02ea29674bc6854460c2"}, + {file = "zipp-3.0.0.tar.gz", hash = "sha256:7c0f8e91abc0dc07a5068f315c52cb30c66bfbc581e5b50704c8a2f6ebae794a"}, +] diff --git a/tests/pyproject.toml b/tests/pyproject.toml new file mode 100644 index 0000000..4ef3159 --- /dev/null +++ b/tests/pyproject.toml @@ -0,0 +1,15 @@ +[tool.poetry] +name = "dotfiles-test" +version = "0.0.0" +description = "Verifies dotfiles install" +authors = ["andrejus "] + +[tool.poetry.dependencies] +python = "^3.7" + +[tool.poetry.dev-dependencies] +pytest = "^5.3.5" + +[build-system] +requires = ["poetry>=0.12"] +build-backend = "poetry.masonry.api" diff --git a/tests/test_binaries.py b/tests/test_binaries.py new file mode 100644 index 0000000..d811f9a --- /dev/null +++ b/tests/test_binaries.py @@ -0,0 +1,43 @@ +#!/usr/bin/env python3 +# +# Verifies dotfiles install +# +from distutils.spawn import find_executable +from typing import List +import pytest + + +# List of binaries to test +binaries: List[str] = [ + + # shells + "sh", "bash", "fish", + + # tools + "git", + "keybase", + "docker", "docker-compose", + "screenfetch", + + # languages + "pyenv", + "python3", + "poetry", + +] + + +def binary_in_path(binary: str) -> bool: + """ + Helper function to check whether `binary` is in PATH. + """ + + return find_executable(binary) is not None + + +@pytest.mark.parametrize("binary", binaries) +def test_binaries(binary: str): + """ + Asserts all binaries are in PATH. + """ + assert binary_in_path(binary) diff --git a/utils.sh b/utils.sh index d907abe..85c1c97 100644 --- a/utils.sh +++ b/utils.sh @@ -4,20 +4,27 @@ # update() { - sudo apt-get update -y + sudo apt-get update -qq } # Non-interactive upgrade upgrade() { DEBIAN_FRONTEND=noninteractive \ - sudo apt-get dist-upgrade -y \ + sudo apt-get dist-upgrade -qq \ -o Dpkg::Options::="--force-confdef" \ -o Dpkg::Options::="--force-confold" } # @arg $1 packages to install install() { - sudo apt-get install -y $1 + sudo apt-get install -qq $1 + refresh +} + +# @arg $1 package list file to install +install_file() { + sudo apt-get install -qq $(cat $1) + refresh } # @arg $1 repository to add @@ -41,6 +48,7 @@ run() { # @arg $1 source folder # @arg $2 target folder link_folder() { + mkdir -p $2 cp -srf $1/. $2 } @@ -51,6 +59,18 @@ not_installed() { ! [ -x "$(command -v $1)" ] } +# Refreshes PATH +refresh() { + hash -r +} + +# Add to PATH and refresh +# @arg $1 path to add to PATH +add_path() { + export PATH="$1:$PATH" + refresh +} + # Colors C_BLACK='\033[0;30m' C_DGRAY='\033[1;30m'