diff --git a/README.md b/README.md index f42b9e4..277920f 100644 --- a/README.md +++ b/README.md @@ -12,14 +12,6 @@ git clone https://git.desu.ltd/salt/bootstrap ./bootstrap/bootstrap.sh $HOME ``` -In the event that you want to simply test `bootstrap.sh`, simply pass a different argument to it: - -``` -./bootstrap/bootstrap.sh -d /path/to/directory -``` - -See `bootstrap.sh -h` for more usage information. - ## Building a Gentoo Install First, partition out the system and build a filesystem tree in `/mnt`. @@ -35,13 +27,3 @@ sudo ./bootstrap/gentoostrap.sh The script supports a fair few arguments, so it's worth looking into `gentoostrap.sh -h` if you need to customize the system. Note that this is highly specific to my environment. Most of the configuration management is done in Ansible, but this will create a user with my own personal setup. - -## Older Versions - -`build-home.sh` is an older version of the script kept here for legacy compatibility. Do not use it; use `bootstrap.sh`. - -## Notes - -* By default, the user's home directory will be bootstrapped. Passing `-d` and a different path will cause a different path to be bootstrapped. - -* By default, the repository will be cloned over SSH. Either generate some keys and add them to your remote server or change the repository URI to HTTP. diff --git a/bootstrap-old.sh b/bootstrap-old.sh new file mode 100755 index 0000000..5609a39 --- /dev/null +++ b/bootstrap-old.sh @@ -0,0 +1,177 @@ +#! /bin/bash +# +# bootstrap +# General-purpose home directory bootstrap script +# Copyright (C) 2020 Vintage Salt +# +# Distributed under terms of the MIT license. +# +set -e + +# Read-only set-once variables +declare -r _name="$(basename -- "$0")" +# Options +declare -i _opthelp +declare -i _optverbose +declare _optdest="$HOME" +declare _optgitdir=".dotfiles" +declare _optrepo="git@git.9iron.club:salt/home" +# Working variables +declare -a _args +declare _return + +# Helper functions +log() { + # Print a line to the terminal if _optverbose is greater than $2 + # $2 defaults to 0 + # loglevel 0: Daily-use messages + # loglevel 1: Detailed but not quite debugging + # loglevel 2: Definitely debugging + [ -z "$1" ] && return 1 + if (( _optverbose >= ${2:-0} )); then + printf "%s\\n" "$1" + fi +} +warn() { + # Print a yellow line to the terminal, respecting _optverbose + [ -z "$1" ] && return 1 + if (( _optverbose >= ${2:-0} )); then + if [ -t 1 ]; then + printf "\\e[33m%s\\e[0m\\n" "$1" + else + printf "WARN: %s\\n" "$1" + fi + fi +} +error() { + # Print a red line to the terminal, exit if $2 is specified + [ -z "$1" ] && return 1 + if [ -t 2 ]; then + printf "\\e[31m%s\\e[0m\\n" "$1" 1>&2 + else + printf "ERROR: %s\\n" "$1" 1>&2 + fi + [ -z "$2" ] && return + exit "${2:-1}" +} +has() { + # Parse out all arguments and try to find them in path + # If an argument cannot be found, set _return and fail + for prog in "$@"; do + if ! command -v "$prog" > /dev/null 2>&1; then + _return="$prog" + return 1 + fi + done + return 0 +} + +# Helper functions +cleanup() { + [ -z "$1" ] && warn "No argument passed to cleanup" + rm -rf "$1" || warn "Failed to remove $1: $?" +} + +# Core program functions +printhelp() { + cat << EOF +Usage: $_name [OPTION]... + + -d Bootstrap directory. Defaults to ~ + -h Print this help text + -r Repository. Defaults to git@git.9iron.club:salt/home + -v Print more status messages. Stacks + +Copyright (c) 2020 rehashedsalt@cock.li +Licensed under the MIT license +EOF +} +build-home() { + # Build a home directory + local repo="$_optrepo" + local dest="$_optdest" + log "Using remote repository $repo" 2 + log "Using destination $dest" 2 + + # Build a skeleton folder layout + log "Building skeleton folder layout" + pushd "$dest" > /dev/null 2>&1 + mkdir Desktop Documents Downloads Music Pictures Projects Public Templates Videos || warn "Error creating skeleton folder layout" + chmod 775 Public || warn "Error making directory Public world-accessible" + popd > /dev/null 2>&1 + + # Clone our repo into a temporary directory + log "Cloning repository into temporary directory" + local tmpdir="$(mktemp -d "tmp.$USER.$_name.XXXXXXXX" -p "/tmp")" + trap "cleanup $tmpdir" EXIT + pushd "$tmpdir" > /dev/null 2>&1 + log "Cloning into temporary directory: $tmpdir" 2 + git clone \ + --recursive \ + --depth 50 \ + --separate-git-dir="./$_optgitdir" \ + "$repo" \ + "$tmpdir" > /dev/null 2>&1 + git config \ + status.showUntrackedFiles no \ + --git-dir="./$_optgitdir" + popd > /dev/null 2>&1 + + # Sync the temporary directory over + log "Moving cloned repository into destination" + log "Moving from $tmpdor to $dest" + rsync -rl "$tmpdir/" "$dest/" +} + +# Main +main() { + # Parse out arguments + while [ -n "$1" ]; do + # Parse out flags + while getopts ":c:d:hr:v" opt; do + case $opt in + d) + _optdest="$OPTARG" + ;; + h) + _opthelp=1 + ;; + r) + _optrepo="$OPTARG" + ;; + v) + _optverbose+=1 + ;; + :) + error "Option requires argument: -$OPTARG" 2 + ;; + *) + error "Invalid option: -$OPTARG" 2 + ;; + esac + done + # Store arguments + shift $((OPTIND - 1)) + if [ -n "$1" ]; then + _args+=("$1") + shift + fi + unset OPTIND + done + # Early hook for help + [ -n "$_opthelp" ] && printhelp && exit 0 + # Validate critical options + # TODO: That + # Validate core program dependencies + log "Validating dependencies" 2 + if ! has basename git mktemp rsync; then + error "Failed to find program: $_return" 1 + fi + + # Do the do + build-home + exit 0 +} + +main "$@" + diff --git a/bootstrap.sh b/bootstrap.sh index 5609a39..78aa230 100755 --- a/bootstrap.sh +++ b/bootstrap.sh @@ -1,177 +1,10 @@ #! /bin/bash -# -# bootstrap -# General-purpose home directory bootstrap script -# Copyright (C) 2020 Vintage Salt -# -# Distributed under terms of the MIT license. -# +destdir="$HOME/.dotfiles" set -e - -# Read-only set-once variables -declare -r _name="$(basename -- "$0")" -# Options -declare -i _opthelp -declare -i _optverbose -declare _optdest="$HOME" -declare _optgitdir=".dotfiles" -declare _optrepo="git@git.9iron.club:salt/home" -# Working variables -declare -a _args -declare _return - -# Helper functions -log() { - # Print a line to the terminal if _optverbose is greater than $2 - # $2 defaults to 0 - # loglevel 0: Daily-use messages - # loglevel 1: Detailed but not quite debugging - # loglevel 2: Definitely debugging - [ -z "$1" ] && return 1 - if (( _optverbose >= ${2:-0} )); then - printf "%s\\n" "$1" - fi -} -warn() { - # Print a yellow line to the terminal, respecting _optverbose - [ -z "$1" ] && return 1 - if (( _optverbose >= ${2:-0} )); then - if [ -t 1 ]; then - printf "\\e[33m%s\\e[0m\\n" "$1" - else - printf "WARN: %s\\n" "$1" - fi - fi -} -error() { - # Print a red line to the terminal, exit if $2 is specified - [ -z "$1" ] && return 1 - if [ -t 2 ]; then - printf "\\e[31m%s\\e[0m\\n" "$1" 1>&2 - else - printf "ERROR: %s\\n" "$1" 1>&2 - fi - [ -z "$2" ] && return - exit "${2:-1}" -} -has() { - # Parse out all arguments and try to find them in path - # If an argument cannot be found, set _return and fail - for prog in "$@"; do - if ! command -v "$prog" > /dev/null 2>&1; then - _return="$prog" - return 1 - fi - done - return 0 -} - -# Helper functions -cleanup() { - [ -z "$1" ] && warn "No argument passed to cleanup" - rm -rf "$1" || warn "Failed to remove $1: $?" -} - -# Core program functions -printhelp() { - cat << EOF -Usage: $_name [OPTION]... - - -d Bootstrap directory. Defaults to ~ - -h Print this help text - -r Repository. Defaults to git@git.9iron.club:salt/home - -v Print more status messages. Stacks - -Copyright (c) 2020 rehashedsalt@cock.li -Licensed under the MIT license -EOF -} -build-home() { - # Build a home directory - local repo="$_optrepo" - local dest="$_optdest" - log "Using remote repository $repo" 2 - log "Using destination $dest" 2 - - # Build a skeleton folder layout - log "Building skeleton folder layout" - pushd "$dest" > /dev/null 2>&1 - mkdir Desktop Documents Downloads Music Pictures Projects Public Templates Videos || warn "Error creating skeleton folder layout" - chmod 775 Public || warn "Error making directory Public world-accessible" - popd > /dev/null 2>&1 - - # Clone our repo into a temporary directory - log "Cloning repository into temporary directory" - local tmpdir="$(mktemp -d "tmp.$USER.$_name.XXXXXXXX" -p "/tmp")" - trap "cleanup $tmpdir" EXIT - pushd "$tmpdir" > /dev/null 2>&1 - log "Cloning into temporary directory: $tmpdir" 2 - git clone \ - --recursive \ - --depth 50 \ - --separate-git-dir="./$_optgitdir" \ - "$repo" \ - "$tmpdir" > /dev/null 2>&1 - git config \ - status.showUntrackedFiles no \ - --git-dir="./$_optgitdir" - popd > /dev/null 2>&1 - - # Sync the temporary directory over - log "Moving cloned repository into destination" - log "Moving from $tmpdor to $dest" - rsync -rl "$tmpdir/" "$dest/" -} - -# Main -main() { - # Parse out arguments - while [ -n "$1" ]; do - # Parse out flags - while getopts ":c:d:hr:v" opt; do - case $opt in - d) - _optdest="$OPTARG" - ;; - h) - _opthelp=1 - ;; - r) - _optrepo="$OPTARG" - ;; - v) - _optverbose+=1 - ;; - :) - error "Option requires argument: -$OPTARG" 2 - ;; - *) - error "Invalid option: -$OPTARG" 2 - ;; - esac - done - # Store arguments - shift $((OPTIND - 1)) - if [ -n "$1" ]; then - _args+=("$1") - shift - fi - unset OPTIND - done - # Early hook for help - [ -n "$_opthelp" ] && printhelp && exit 0 - # Validate critical options - # TODO: That - # Validate core program dependencies - log "Validating dependencies" 2 - if ! has basename git mktemp rsync; then - error "Failed to find program: $_return" 1 - fi - - # Do the do - build-home - exit 0 -} - -main "$@" - +git clone git@git.desu.ltd:salt/dotfiles \ + --recurse-submodules \ + "$destdir" +pushd "$destdir" +stow --adopt base +git checkout -- . +popd diff --git a/build-home.sh b/build-home.sh deleted file mode 100755 index 878f7b8..0000000 --- a/build-home.sh +++ /dev/null @@ -1,164 +0,0 @@ -#! /usr/bin/env bash -# -# Home directory bootstrap script -# Copyritght (C) 2018-2020 Salt -# -# Distributed under terms of the MIT license -# - -# shellcheck disable=1117 - -## Helper functions -log() { - [ -z ${1+x} ] && return 1 - out=1 - [ -z ${2+x} ] || out="$2" - col_message="\e[39m" - [ "$out" -gt "1" ] && col_message="\e[31m" - [ "$out" -lt "1" ] && out=1 && col_message="\e[37m" - printf "\e[94m%s\e[0m: %b%s\e[0m\n" \ - "$name" \ - "$col_message" \ - "$1" >&${out} -} -validatedep() { - if ! command -v "$1" > /dev/null 2>&1; then - return 1 - fi - return 0 -} -help() { - cat << EOF -Usage: $name [OPTION] -Bootstrap a git repository as a bare repo, also perform some bootstrap tasks. - -d DIRECTORY Bootstrap directory. Defaults to ~. - -r REPOSITORY Target repository. Defaults to - git@git.9iron.club:salt/home - -l FILE File to log command output to. Defaults to - $name.log -EOF -} -cleanup() { - [ -z ${tmpdir+x} ] || rm -rf -- "$tmpdir" -} - -## Core functions -step_validate_logs() { - # Rotate the logfile, if necessary - if [ -f "$logfile" ]; then - log "Found old logfile. Rotating" 0 - mv "$logfile" "$logfile.old" - fi -} -step_validate_deps() { - # Ensure we have the proper dependencies - log "Validating dependencies" - local nodeps=0 - for dep in $deps; do - if ! validatedep "$dep"; then - log "Could not find critical dependency \"$dep\"" 2 - nodeps=1 - fi - done - if [ "$nodeps" == "1" ]; then - return 1 - fi -} -step_make_skeleton() { - # Build Home folder skeleton - log "Building skeleton folder layout" - pushd "$bootstrapdir" - if ! mkdir Desktop Documents Downloads Games Music Pictures Projects Public ROMs System Templates Videos > /dev/null 2>&1; then - log "Failed to build skeleton layout" 2 - return 1 - fi - popd - return 0 -} -step_repo_clone() { - # Clone the dotfiles - log "Cloning repository into \"$tmpdir\"" - git clone --recursive --depth 50 --separate-git-dir="$gitdir" "$repo" "$tmpdir" >> "$logfile" 2>&1 - error="$?" - if ! [ "$error" -eq "0" ]; then - log "Failed cloning repository \"$repo\": git returned $error" 2 - log "See $logfile for details" - return 1 - fi -} -step_repo_move() { - # Move them to where they should be - log "Moving cloned repo from \"$tmpdir\" into \"$bootstrapdir\"" - if ! rsync -rvl --exclude ".git" "$tmpdir/" "$bootstrapdir/" >> "$logfile"; then - log "Failed to move from temp directory to bootstrap directory" 2 - return 1 - fi -} - -## Main -main() { - # Set up some non-controlled variables - name="$(basename "$0" .sh)" # Name of the program, used in logging - deps="git rsync mktemp basename" # Critical dependencies - tmpdir="$(mktemp -d "tmp.$USER.$name.XXXXXXXX" --tmpdir)" - gitdir="$PWD/.dotfiles" - - # Parse out arguments - while getopts ":d:r:lh\?" opt; do - case $opt in - d) - if [ "$OPTARG" == "" ]; then - log "Option -d requires an argument" 2 - exit 1 - fi - bootstrapdir="$OPTARG" - ;; - r) - if [ "$OPTARG" == "" ]; then - log "Option -r requires an argument" 2 - exit 1 - fi - repo="$OPTARG" - ;; - l) - if [ "$OPTARG" == "" ]; then - log "Option -l requires an argument" 2 - exit 1 - fi - logfile="$OPTARG" - ;; - \?|h) - help - ;; - *) - log "Invalid option: \"$opt\"" 2 - exit 1 - ;; - esac - done - # Set up some user-controllable variables - if [ -z ${bootstrapdir+x} ]; then - bootstrapdir="$PWD" - log "Using default bootstrap dir \"$bootstrapdir\"" 0 - fi - if [ -z ${repo+x} ]; then - repo='git@git.9iron.club:salt/home.git' - log "Using default repository \"$repo\"" 0 - fi - if [ -z ${logfile+x} ]; then - logfile="${PWD}/${name}.log" # Log file - fi - - # Do the do - trap cleanup EXIT - step_validate_logs || exit $? - step_validate_deps || exit $? - step_make_skeleton - step_repo_clone || exit $? - step_repo_move || exit $? - log "Dotfiles set up successfully" - exit 0 -} - -main "$@" -