From a6ada90a939cb78e5fd1892a2372e4ad3ae02f85 Mon Sep 17 00:00:00 2001 From: Andrejus Kostarevas Date: Tue, 10 Oct 2023 00:41:11 +0100 Subject: [PATCH] feat: docs and script improvements --- .github/workflows/ci.yml | 2 +- .gitignore | 3 +- README.md | 29 ++++++------ script/install | 52 ++++++++++----------- script/setup | 84 ++++++++++++++++++++++++++-------- script/setup-git | 44 ++++++++++++++++++ script/run => tools/docker-run | 4 ++ {script => tools}/test | 5 ++ 8 files changed, 162 insertions(+), 61 deletions(-) create mode 100755 script/setup-git rename script/run => tools/docker-run (65%) rename {script => tools}/test (64%) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f1a4a73..c5bfdd3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -10,4 +10,4 @@ jobs: # Run the tests - name: 'Run tests' - run: ./script/test + run: ./tools/test diff --git a/.gitignore b/.gitignore index 154b195..0928316 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ # install artefacts -**/tmp +tmp +temp **/logs **/*.deb diff --git a/README.md b/README.md index 36a2c52..d3881ef 100644 --- a/README.md +++ b/README.md @@ -2,28 +2,29 @@ [![Dotfiles CI](https://github.com/andrejusk/dotfiles/actions/workflows/ci.yml/badge.svg)](https://github.com/andrejusk/dotfiles/actions/workflows/ci.yml) -Collection of dotfiles and supporting install scripts -to set up a reproducible development environment +My collection of dotfiles and install scripts +to set up reproducible dev environments -## Installer +## Usage -Each push to master publishes the setup script, allowing the repo -to be installed by running: +A local repository can be installed by running: - # Dependencies if running on Debian - sudo apt update && sudo apt install --no-install-recommends --yes \ - software-properties-common \ - wget + ./script/install + +### Automated install + +This repository can be installed without a local copy +by invoking the `setup` script directly via `curl`: # Inspect source - wget https://raw.githubusercontent.com/andrejusk/dotfiles/HEAD/script/setup -qO - | less + curl -s https://raw.githubusercontent.com/andrejusk/dotfiles/HEAD/script/setup | less - # One-liner install if running on Ubuntu - wget https://raw.githubusercontent.com/andrejusk/dotfiles/HEAD/script/setup -qO - | bash + # Run + curl -s https://raw.githubusercontent.com/andrejusk/dotfiles/HEAD/script/setup | bash -## The Stack +## Features -Tested and maintained against Debian bullseye +My dotfiles include configuration for the following tools: ### Shell diff --git a/script/install b/script/install index 065d857..86b033b 100755 --- a/script/install +++ b/script/install @@ -1,30 +1,28 @@ #!/usr/bin/env bash set -eo pipefail -# +# -------------------------------------------------------------------- # Script that installs system dependencies specified in a config, # and runs all post-install scripts contained in a subdirectory. # -TIME=${TIME:-$(date)} -UUID=${UUID:-$(cat /proc/sys/kernel/random/uuid)} -HOST=${HOST:-$(hostname)} +uuid=${UUID:-$(cat /proc/sys/kernel/random/uuid)} +dir=$(dirname "$0") +utils="${dir}/_utils.sh" +config="${dir}/install_config.json" +install_dir="${dir}/install.d" +log_dir="${dir}/logs" -NAME=$(basename "$0") -REL_DIR=$(dirname "$0") -ABS_DIR=$(readlink -f $REL_DIR/../) # Scripts are nested inside of /script - -UTILS="${REL_DIR}/_utils.sh" -CONFIG="${REL_DIR}/install_config.json" -INSTALL_DIR="${REL_DIR}/install.d" - -LOG_DIR="${ABS_DIR}/logs" -mkdir -p "$LOG_DIR" -LOG_TARGET=${LOG_TARGET:-"${LOG_DIR}/${UUID}.log"} +# Create log directory if it doesn't exist +# and the log path hasn't been overridden +if [[ -z "$LOG_TARGET" ]]; then + mkdir -p "$log_dir" +fi +log_target=${LOG_TARGET:-"${log_dir}/${uuid}.log"} install() { - echo "Running $NAME at $TIME" - echo "Running as $USER on $HOST" + echo "Running \"$(basename "$0")\" at \"$(date)\"" + echo "Running as \"$(whoami)\" on \"$(hostname)\"" # Prevent running as root if [[ $EUID -eq 0 ]]; then @@ -33,40 +31,40 @@ install() { fi # Load installer dependencies - source "$UTILS" + source "$utils" update install jq - for dep in $(jq -r ".apt_core_dependencies[]" "$CONFIG"); do + for dep in $(jq -r ".apt_core_dependencies[]" "$config"); do install "$dep" done # Add apt repositories - for i in $(jq ".apt_repositories | keys | .[]" "$CONFIG"); do - value=$(jq -r ".apt_repositories[$i]" "$CONFIG") + for i in $(jq ".apt_repositories | keys | .[]" "$config"); do + value=$(jq -r ".apt_repositories[$i]" "$config") add_repository "$value" done update # Install apt dependencies - for dep in $(jq -r ".apt_dependencies[]" "$CONFIG"); do + for dep in $(jq -r ".apt_dependencies[]" "$config"); do install "$dep" done # Install dotfiles on system and load them figlet -c "Stowing..." - for i in $(jq ".stow_packages | keys | .[]" "$CONFIG"); do - value=$(jq -r ".stow_packages[$i]" "$CONFIG") + for i in $(jq ".stow_packages | keys | .[]" "$config"); do + value=$(jq -r ".stow_packages[$i]" "$config") stow_package "$value" done source "$HOME/.profile" # Run custom installer scripts figlet -c "Installing..." - for script in $INSTALL_DIR/*.sh; do + for script in $install_dir/*.sh; do figlet -c "$(basename $script)" source $script done } -echo "install: Logging to $LOG_TARGET" -install 2>&1 | tee "$LOG_TARGET" +echo "install: Logging to \"$log_target\"" +install 2>&1 | tee "$log_target" diff --git a/script/setup b/script/setup index 93c3639..55b2931 100755 --- a/script/setup +++ b/script/setup @@ -1,34 +1,82 @@ #!/usr/bin/env bash set -eo pipefail +# -------------------------------------------------------------------- +# Summary: Script to checkout a compatible +# repository and run `script/install` # -# Script that checks out a compatible dotfiles repository -# and runs the installer to set up a new installation. +# Optional arguments: +# GITHUB_AUTHOR: GitHub author of repository +# Defaults to "andrejusk" +# GITHUB_REPOSITORY: GitHub repository name +# Defaults to "dotfiles" +# GITHUB_BRANCH: GitHub branch name +# Defaults to "master" +# DOTFILES_DIR: Directory to install dotfiles to +# Defaults to "$HOME/.dotfiles" +# DOTFILES_SKIP_INSTALL: Skip running `script/install` +# Defaults to false +# +# Required binaries: +# curl +# tar # -author=${GITHUB_AUTHOR:-andrejusk} -repository=${GITHUB_REPOSITORY:-dotfiles} -branch=${GITHUB_BRANCH:-master} -echo "Using repository $author/$repository at $branch" +echo "============================================================" +echo "Running \"$(basename "$0")\" at \"$(date)\"" +echo "Running as \"$(whoami)\" on \"$(hostname)\"" +echo "============================================================" -setup_dir=${DOTFILES_DIR:-$HOME/.dotfiles} - -# Prevent overwriting existing installation -mkdir -p $setup_dir -if [[ -z $(ls -A $setup_dir) ]]; then - echo "Setting up $setup_dir" -else - echo "Failed: Setup directory not empty $setup_dir" +# Exit if wget is not installed +if ! command -v curl &> /dev/null; then + echo "Failed: curl is not installed" exit 1 fi -# Download and untar repo +# Exit if tar is not installed +if ! command -v tar &> /dev/null; then + echo "Failed: tar is not installed" + exit 1 +fi + +# Read and check if setup directory is empty +setup_dir=${DOTFILES_DIR:-$HOME/.dotfiles} +mkdir -p $setup_dir +if [[ -z $(ls -A $setup_dir) ]]; then + echo "Setting up in directory \"$setup_dir\"" +else + echo "Failed: Setup directory not empty \"$setup_dir\"" + exit 1 +fi + +# Read GitHub repository and branch from environment variables +author=${GITHUB_AUTHOR:-andrejusk} +repository=${GITHUB_REPOSITORY:-dotfiles} +branch=${GITHUB_BRANCH:-master} + +# Check if repository and branch exists +if curl -s "https://api.github.com/repos/$author/$repository" | grep -q "Not Found"; then + echo "Failed: GitHub repository \"$author/$repository\" does not exist" + exit 1 +fi +if curl -s "https://api.github.com/repos/$author/$repository/branches/$branch" | grep -q "not found"; then + echo "Failed: Branch \"$branch\" does not exist in GitHub repository \"$author/$repository\"" + exit 1 +fi +echo "Using GitHub repository \"$author/$repository\" at \"$branch\"" + +# Download and extract repo tmp_dir=$(mktemp -d) tmp_dest="$tmp_dir/dotfiles.tar.gz" -wget "https://github.com/$author/$repository/archive/$branch.tar.gz" -qO $tmp_dest +checkout_url="https://github.com/$author/$repository/archive/$branch.tar.gz" +curl -sL $checkout_url -o $tmp_dest tar -C $tmp_dir -zxf $tmp_dest mv $tmp_dir/$repository-$branch/* $setup_dir rm -rf $tmp_dir -# Run installer -$setup_dir/script/install +# Run installer unless DOTFILES_SKIP_INSTALL is set +if [[ -z "$DOTFILES_SKIP_INSTALL" ]]; then + $setup_dir/script/install +else + echo "Skipping install" +fi diff --git a/script/setup-git b/script/setup-git new file mode 100755 index 0000000..caf251f --- /dev/null +++ b/script/setup-git @@ -0,0 +1,44 @@ +#!/usr/bin/env bash +set -eo pipefail + +# -------------------------------------------------------------------- +# Script that sets up git in dotfiles directory. +# +# Optional arguments: +# GITHUB_AUTHOR: GitHub author of repository +# Defaults to "andrejusk" +# GITHUB_REPOSITORY: GitHub repository name +# Defaults to "dotfiles" +# GITHUB_BRANCH: GitHub branch name +# Defaults to "master" +# DOTFILES_DIR: Directory where dotfiles are installed +# Defaults to parent directory of this script +# + +echo "============================================================" +echo "Running \"$(basename "$0")\" at \"$(date)\"" +echo "Running as \"$(whoami)\" on \"$(hostname)\"" +echo "============================================================" + +dir=${DOTFILES_DIR:-$(dirname "$0")} +dir=$(realpath "$dir/..") + +author=${GITHUB_AUTHOR:-andrejusk} +repository=${GITHUB_REPOSITORY:-dotfiles} +branch=${GITHUB_BRANCH:-master} + +echo "Using GitHub repository \"$author/$repository\" at \"$branch\"" +echo "Using dotfiles directory \"$dir\"" +echo "<<< git logs" +printf "\n" + +git -C $dir init +git -C $dir remote add origin "git@github.com:$author/$repository.git" +git -C $dir fetch origin $branch +git -C $dir reset --hard FETCH_HEAD +git -C $dir branch --set-upstream-to=origin/$branch $branch +git -C $dir pull --rebase + +printf "\n" +echo ">>> git logs" +echo "Done!" diff --git a/script/run b/tools/docker-run similarity index 65% rename from script/run rename to tools/docker-run index 3ddf244..45c796d 100755 --- a/script/run +++ b/tools/docker-run @@ -1,6 +1,10 @@ #!/usr/bin/env bash set -euo pipefail +# -------------------------------------------------------------------- +# This script is used to run the install script in a docker container. +# + tag=$(cat /proc/sys/kernel/random/uuid) docker build . \ --build-arg UUID=$tag \ diff --git a/script/test b/tools/test similarity index 64% rename from script/test rename to tools/test index c854cf4..d3f6499 100755 --- a/script/test +++ b/tools/test @@ -1,6 +1,11 @@ #!/usr/bin/env bash set -euo pipefail +# -------------------------------------------------------------------- +# This script is used to run the install script in a docker container +# and then run the test script. +# + IMAGE=${IMAGE:-"andrejusk/dotfiles"} tag=${TAG:-$(cat /proc/sys/kernel/random/uuid)}