diff --git a/.gitignore b/.gitignore index 4aa84dc..86bcc74 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1 @@ -install/*.lock -install.lock \ No newline at end of file +*.dotlock diff --git a/Makefile b/Makefile index 03721d3..729b793 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,3 @@ .PHONY: clean clean: - rm -f install.lock install/*.lock - -.PHONY: clear -clear: - rm -f install.lock + rm -f .dotlock diff --git a/README.md b/README.md index 83aa7d3..ed71511 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,17 @@ # dotfiles.andrejus.uk -☁ + +Collection of tracked dotfiles and supporting install scripts. ## Install -``` -git clone https://github.com/andrejusk/dotfiles.git ~/workspace/dotfiles -sudo sh ~/workspace/dotfiles/setup.sh -``` -## About -* zsh -* oh-my-zsh -* spaceman + source <(wget https://raw.githubusercontent.com/andrejusk/dotfiles/master/bootstrap.sh) -* brew +## Stack + +Shell: 🐟 fish (+ fisher) + +Devops: +* docker (+ docker-compose) + +Languages: +* python (+ poetry, pyenv) diff --git a/bootstrap.sh b/bootstrap.sh new file mode 100644 index 0000000..8f57c53 --- /dev/null +++ b/bootstrap.sh @@ -0,0 +1,36 @@ +#!/bin/bash +# +# Script to set up and install dotfiles repository. +# +# Usage: +# `source path/to/bootstrap.sh` +# `source <(wget path/to/bootstrap.sh)` +# +set -euf -o pipefail + +# Set up variables and imports +repository="andrejusk/dotfiles" +repository_url="https://github.com/$repository.git" +workspace_dir="$HOME/workspace" +dotfiles_dir="$workspace_dir/dotfiles" +lock_extension="dotlock" +source "${dotfiles_dir}/utils.sh" + +# Ensure git is installed +if ! hash git 2>/dev/null; then + sudo apt-get update -yqq + sudo apt-get install -yqq git +fi + +# Ensure repository is cloned +if [[ ! -d $dotfiles_dir ]]; then + mkdir -p $workspace_dir + git clone $repository_url $dotfiles_dir +fi + +# Ensure repository is up to date +cd $dotfiles_dir +# git pull origin master + +# Install dotfiles +source $dotfiles_dir/install.sh diff --git a/fish/config.fish b/fish/config.fish new file mode 100644 index 0000000..e127afe --- /dev/null +++ b/fish/config.fish @@ -0,0 +1,12 @@ +# 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 + +# Poetry +set -gx PATH $HOME/.poetry/bin $PATH + +# Wipe greeting +set fish_greeting diff --git a/fish/fishfile b/fish/fishfile new file mode 100644 index 0000000..69245b2 --- /dev/null +++ b/fish/fishfile @@ -0,0 +1,2 @@ +rafaelrinaldi/pure +jorgebucaran/fish-nvm diff --git a/git/.gitconfig b/git/.gitconfig new file mode 100644 index 0000000..63d72be --- /dev/null +++ b/git/.gitconfig @@ -0,0 +1,6 @@ +[user] + name = Andrejus + email = hi@andrejus.uk + +[github] + user = andrejusk diff --git a/git/.gitignore_global b/git/.gitignore_global new file mode 100644 index 0000000..e69de29 diff --git a/install.sh b/install.sh index 82281d6..28c4f29 100755 --- a/install.sh +++ b/install.sh @@ -1,47 +1,48 @@ #!/bin/bash # -# Runs all install scripts +# Invokes all install scripts. +# -# set -xv -set -o pipefail +# Log execution +printf "Installing ${C_CYAN}$repository${C_NC}" +printf " as ${C_YELLOW}$USER${C_NC}\n\n" -dir=`dirname $0` -name=`basename $0 ".sh"` -source $dir/utils.sh -printf "${C_CYAN}andrejusk/dotfiles${C_NC}\n\n" - -# Check if running -lock_file=$dir/$name.lock -if [ -f $lock_file ]; then - printf "${C_RED}Script already running${C_NC}\n" - exit 1 -else - touch $lock_file # Requires clear -fi - -# Check for root -if [[ $EUID -ne 0 ]]; then - printf "${C_RED}Called without sudo, run:${C_NC}\n" - printf "sudo !!\n\n" - make clear +# Prevent running as root +if [ "$USER" == "root" ]; then + printf "Failed: ${C_RED}Running as $USER${C_NC}\n" + printf "Please run as user, not ${C_YELLOW}sudo${C_NC}\n" exit 1 fi +# Prevent concurrent scripts +lock_file="$dotfiles_dir/.$lock_extension" +if [ -f "$lock_file" ]; then + printf "Failed: ${C_RED}Script already running${C_NC}\n" + printf "Please wait for script to exit or ${C_YELLOW}make clean${C_NC}\n" + exit 1 +fi +touch $lock_file # Requires clear + # Run all install scripts -install_dir="$dir/install" -for script in $install_dir/*.sh; -do - script_name=`basename $script ".sh"` - script_lock="$install_dir/$script_name.lock" - if [ -f $script_lock ]; then - printf "skipping $script_name\n" - else - printf "running $script_name\n" - touch $script_lock - bash -o pipefail $script | indent - fi +for script in "$dotfiles_dir/install/*.sh"; do + + printf "$script\n\n" + + # Avoid pattern matching self + [ -e "$script" ] || continue + + # Log execution + script_name=$(basename "$script" ".sh") + printf "Running ${C_YELLOW}$script_name${C_NC}...\n${C_DGRAY}" + + # Run and indent output + source "$script" | indent + printf "${C_NC}\n" + done -# Exit -make clear +# Clean up and exit +printf "Done! Cleaning up...\n${C_DGRAY}" +make clean +printf "${C_NC}\n" exit 0 diff --git a/install/00-apt-pkglist b/install/00-apt-pkglist new file mode 100644 index 0000000..e330084 --- /dev/null +++ b/install/00-apt-pkglist @@ -0,0 +1,3 @@ +curl +net-tools +openssh-server diff --git a/install/00-apt.sh b/install/00-apt.sh index d6dcdac..c1065f2 100644 --- a/install/00-apt.sh +++ b/install/00-apt.sh @@ -1,8 +1,14 @@ #!/bin/bash +# +# Always updates apt, upgrades apt, and installes 00-apt-pkglist +# -apt-get -y update -DEBIAN_FRONTEND=noninteractive apt-get -y \ +# apt update and upgrade non-interactively +sudo apt-get update -y +DEBIAN_FRONTEND=noninteractive sudo apt-get \ -o Dpkg::Options::="--force-confdef" \ - -o Dpkg::Options::="--force-confold" upgrade -apt-get -y autoremove -apt-get -y autoclean + -o Dpkg::Options::="--force-confold" upgrade -y + +# Package installs +pkglist=$(cat $install_dir/00-apt-pkglist) +sudo apt-get install -y $pkglist diff --git a/install/01-fish.sh b/install/01-fish.sh index a6db4de..5900987 100644 --- a/install/01-fish.sh +++ b/install/01-fish.sh @@ -1,6 +1,44 @@ #!/bin/bash +# +# After running this script: +# 1. fish shell is installed +# 2. fish shell is default login shell +# 3. fish dotfiles are symlinked +# -apt-add-repository -y ppa:fish-shell/release-3 -apt update -apt-get -y install fish -chsh -s `which fish` +# 1. fish shell is installed +if [ ! hash fish ] 2>/dev/null; then + + printf "Installing fish...\n" + + # Add fish repository + sudo apt-add-repository -y ppa:fish-shell/release-3 + sudo apt-get -y update + + # Install fish + sudo apt-get -y install fish + +fi +printf "fish is installed\n" + +# 2. fish shell is default login shell +fish_path=$(which fish) +if [ $SHELL != fish_path ]; then + + printf "Setting fish as default...\n" + + # Update default login shell + chsh -s $fish_path $USER + usermod -s $fish_path $USER + +fi +printf "fish is default login shell\n" + +# 3. fish dotfiles are symlinked +target="$HOME/.config/fish" +for file in $(ls -d $script_dir/fish/*); do + rel_path=$(realpath --relative-to="$target" "$file") + printf "Linking $file to $target as $rel_path...\n" + ln -sv $rel_path $target +done +printf "fish dotfiles linked\n" diff --git a/install/10-git.sh b/install/10-git.sh new file mode 100644 index 0000000..93707c4 --- /dev/null +++ b/install/10-git.sh @@ -0,0 +1,14 @@ +#!/bin/bash +# +# After running this script: +# 1. git dotfiles are symlinked +# + +# 1. git dotfiles are symlinked +target="$HOME" +for file in $(ls -d $script_dir/git/*); do + rel_path=$(realpath --relative-to="$target" "$file") + printf "Linking $file to $target as $rel_path...\n" + ln -sv $rel_path $target +done +printf "git dotfiles linked\n" diff --git a/install/11-docker.sh b/install/11-docker.sh deleted file mode 100644 index b382972..0000000 --- a/install/11-docker.sh +++ /dev/null @@ -1,23 +0,0 @@ -#!/bin/bash - -apt-get -y install \ - apt-transport-https \ - ca-certificates \ - curl \ - gnupg-agent \ - software-properties-common - -curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - -apt-key fingerprint 0EBFCD88 - -add-apt-repository -y \ - "deb [arch=amd64] https://download.docker.com/linux/ubuntu \ - $(lsb_release -cs) \ - stable" -apt update -apt install -y docker-ce -systemctl status docker - -curl -L https://github.com/docker/compose/releases/download/1.21.2/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose -chmod +x /usr/local/bin/docker-compose -docker-compose --version diff --git a/install/11-keybase.sh b/install/11-keybase.sh new file mode 100644 index 0000000..e01f0a4 --- /dev/null +++ b/install/11-keybase.sh @@ -0,0 +1,16 @@ +#!/bin/bash +# +# After running this script: +# 1. keybase is installed +# + +# 1.keybase is installed +if [ ! hash fish ] 2>/dev/null; then + + printf "Installing keybase...\n" + + curl --remote-name https://prerelease.keybase.io/keybase_amd64.deb + sudo apt install ./keybase_amd64.deb + run_keybase + +fi diff --git a/install/12-docker.sh b/install/12-docker.sh new file mode 100644 index 0000000..2e7ac66 --- /dev/null +++ b/install/12-docker.sh @@ -0,0 +1,58 @@ +#!/bin/bash +# +# After running this script: +# 1. docker is installed +# 2. docker-compose if installed +# 3. docker group exists +# 4. user is in docker group +# + +# 1. docker is installed +if ! hash docker 2>/dev/null; then + + printf "Installing docker...\n" + + # Requirements + sudo apt-get -y install \ + apt-transport-https \ + ca-certificates \ + curl \ + gnupg-agent \ + software-properties-common + + # Add repository + curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - + sudo add-apt-repository -y \ + "deb [arch=amd64] https://download.docker.com/linux/ubuntu \ + $(lsb_release -cs) \ + stable" + sudo apt-get -y update + +fi +printf "docker is installed\n" + +# 2. docker-compose if installed +if ! hash docker-compose 2>/dev/null; then + + printf "Installing docker-compose...\n" + + # Docker-compose + curl -L https://github.com/docker/compose/releases/download/1.21.2/docker-compose-$(uname -s)-$(uname -m) -o /usr/local/bin/docker-compose + sudo chmod +x /usr/local/bin/docker-compose + docker-compose --version + +fi +printf "docker-compose is installed\n" + +# 3. docker group exists +group='docker' +if ! grep -q $group /etc/group; then + sudo groupadd docker +fi +printf "group '$group' is created\n" + +# 4. user is in docker group +if ! groups $USER | grep -q "\b$group\b"; then + sudo usermod -aG docker $USER +fi +printf "user '$USER' is in '$group' group\n" diff --git a/install/20-pyenv.sh b/install/20-pyenv.sh new file mode 100644 index 0000000..453b39c --- /dev/null +++ b/install/20-pyenv.sh @@ -0,0 +1,23 @@ +#!/bin/bash +# +# After running this script: +# 1. pyenv is installed +# + +# 1. pyenv is installed +if ! hash pyenv 2>/dev/null; then + + printf "Installing pyenv...\n" + + # Install pyenv prerequisites + # see https://github.com/pyenv/pyenv/wiki/common-build-problems + sudo apt-get install -y make build-essential libssl-dev zlib1g-dev libbz2-dev \ +libreadline-dev libsqlite3-dev wget curl llvm libncurses5-dev libncursesw5-dev \ +xz-utils tk-dev libffi-dev liblzma-dev python-openssl git + + # Install pyenv + # see https://github.com/pyenv/pyenv-installer + curl -L https://github.com/pyenv/pyenv-installer/raw/master/bin/pyenv-installer | bash + +fi +printf "pyenv is installed\n" diff --git a/install/21-python.sh b/install/21-python.sh new file mode 100644 index 0000000..2999081 --- /dev/null +++ b/install/21-python.sh @@ -0,0 +1,16 @@ +#!/bin/bash +# +# After running this script: +# 1. python is installed +# + +# 1. python is installed +if ! hash python 2>/dev/null; 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/22-poetry.sh b/install/22-poetry.sh new file mode 100644 index 0000000..2a5fcd7 --- /dev/null +++ b/install/22-poetry.sh @@ -0,0 +1,16 @@ +#!/bin/bash +# +# After running this script: +# 1. poetry is installed +# + +# 1. poetry is installed +if ! hash poetry 2>/dev/null; then + + printf "Installing poetry...\n" + + # Install poetry + curl -sSL https://raw.githubusercontent.com/python-poetry/poetry/master/get-poetry.py | python3 + +fi +printf "poetry is installed\n" diff --git a/install/99-apt-clean.sh b/install/99-apt-clean.sh new file mode 100644 index 0000000..091af14 --- /dev/null +++ b/install/99-apt-clean.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +# Clean up +sudo apt-get -y autoremove +sudo apt-get -y autoclean