Foxables Open ZSHRC - Your New Enhanced DevOps Workflow

We’ve produced an auto updating .zshrc file with cool intuitive commands and aliases designed to enhance your DevOps and Software Engineering Workflows, it’s completely free to use, easy as pie to install, and will continue to be maintained. Designed by a Software Architect for the open source world

Foxables Open ZSHRC - Your New Enhanced DevOps Workflow
Photo by Jean Gerber / Unsplash

What is a .zshrc File?

ZSH is a popular shell wraper for posix/unix based operating systems such as Mac OSX, Ubuntu, and Linux. It provides customisability to one’s shell environment enabling and facilitating visual shell extensions. The .zshrc file was introduced to provide a location whereby one could house all of their ZSH customisations such as; aliases and functions, and configuration settings for ZSH.

Why use a .zshrc File?

The power of aliases and custom functions allows you to reduce the overall complexity of your CLI workflows. By leveraging aliases to power long command names or command chains, or custom functions to handle more complex steps, you can quickly and easily reduce the complexity of your CLI Workflow saving you hours of wasted time each month.

How do I use .zshrc?

I spend most of my day in a shell environment running on Mac OSX for regular day-to-day operations and development, or in Ubuntu / AmazonLinux 2 for remote server management.

Simplifying SSH

Different environments I connect to might use different key pairs or different usernames... So I have a shell function called c, this is short for connectToSSH the command syntax is c <ip/hostname> user privateKey. When I do not provide a value for user, my default user is set to ec2-user and for privateKey, when not set my default will be ~/.ssh/id_rsa.pem.

This allows me to run the command c 10.0.1.19 to SSH directly into an AWS EC2 instance with the IP Address 10.0.1.19 with the user ec2-user and the private key ~/.ssh/id_rsa.pemby executing the transposed command; ssh -i ~/.ssh/id_rsa.pem ec2-user@10.0.1.19 on port 22.

I could create a subnet to key map, perform a scan of the file and automatically use the correctly maped private key based on the IP I’m trying to connect to if I wish, but most of the time I do not need to change the value for user or privateKey.

In addition to this, we can test common usernames if the one we provide doesn’t work, that allows us to automatically fall-back onto the correct username for the host we are trying to connect to.

Finally, if your ~/.ssh/config file contains a key to IP value for the host you’re connecting to our c command will automatically use this key.

Simplifying Git

When working with git source control, my command flow tends to look something like this;

gs && gco master && gip && gco -b feature/branch && gsp

This command chain performs the following actions;

  1. Git Stash
  2. Git Checkout to the master trunking branch.
  3. Git Pull the latest changes from origin.
  4. Git checkout to the new feature/branch.
  5. Git stash pop.

Or in human language;

  1. Hold all current uncommitted changes.
  2. Switch to the master branch.
  3. Get the latest changes for the master branch.
  4. Create a new branch called feature/branch
  5. Release and apply the most recently held uncommitted changes and remove the holding record.

This might seem arbitrary, why not just use the commands themselves? Ok, sure, here’s the commands;

git stash && git checkout master && git pull origin master && git checkout -b feature/branch && git stash pop

The full chain of commands is almost double the amount of typing required to do literally the exact same thing... Now I know I know, don’t be lazy right?

Well, let’s apply the multiplier affect to this. 🥹

In any given day, I’m running these command chains upwards of 30 times. That means by using the short command chain, I’m saving 1,620 letters from being typed repeatedly. Multiply this by how many days in a year (I do source code work every day of the week), by using short chain commands I’m saving a staggering 591,300 superfluous characters from being typed. This translates to a tangibly considerable increase to time efficiency and reduction of wastage.

Aliases are extremely powerful tools for productivity, create functions for complex aliases (I could condense the entire chain to gits new master feature/branch which would execute the entire command chain in sequence using new as the keyword for which chain to execute, master denoting the source trunking branch, and feature/branch as the expected branch to create.)

Without further adieu, I give you a snapshot of the current version of the Foxables Open .zshrc file. 😁

#FOXABLES
# If you come from bash you might have to change your $PATH.
ME=$(whoami)
# export PATH=$HOME/bin:/usr/local/bin:$PATH
export GPG_TTY=$(tty)

export ZSH="/Users/$ME/.oh-my-zsh"

# Set name of the theme to load --- if set to "random", it will
# load a random theme each time oh-my-zsh is loaded, in which case,
# to know which specific one was loaded, run: echo $RANDOM_THEME
# See https://github.com/robbyrussell/oh-my-zsh/wiki/Themes
ZSH_THEME="robbyrussell"

ENABLE_CORRECTION="true"
COMPLETION_WAITING_DOTS="true"

CMD_TIMER_COLOR="magenta"
CMD_TIMER="true"

DEFAULT_SSH_USER="root"
DEFAULT_SSH_KEY="~/.ssh/id_rsa"

plugins=(git rails ruby gem emoji encode64 git-extras)

source $ZSH/oh-my-zsh.sh


#############################################
# Aliases
#############################################

# General
alias 7zip="~/Scripts/7zz"
alias hist="history -i"

# IaC
alias terraform="~/Applications/terraform"
alias tfp="~/Applications/terraform plan"
alias tfi="~/Applications/terraform init"
alias tfa="~/Applications/terraform apply"
alias tfd="~/Applications/terraform destroy"

# SVC
alias ga="git add"
alias gc="git commit -s"
alias gp="git push"
alias gs="git stash"
alias gsp="git stash pop"
alias gip="git pull"
alias gco="git checkout"
alias gfo="git fetch origin"
alias gsync="git pull origin/master"
alias gitfucked="git rm -rf . --cached"

#############################################
# Functions
#############################################
function gits() {
  if [[ ! -z "$1" ]] && [[ ! -z "$2" ]] && [[ -z "$3" ]];
  then
    if [[ "$1" == "delete" ]] || [[ "$1" == "d" ]];
    then
      git branch -D "$2" && git push origin -d "$2"
    elif [[ "$1" == "tag" ]] || [[ "$1" == "t" ]];
    then
      git tag "$2" && git push origin "$2"
    elif [[ "$1" == "switch" ]] || [[ "$1" == "s" ]];
    then
      gco "$2" && gip -f
    fi
  elif [[ ! -z "$1" ]] && [[ ! -z "$2" ]] && [[ ! -z "$3" ]];
  then
    if [[ "$1" == "new" ]] || [[ "$1" == "n" ]];
    then
      gs && gco "$2" && gip && gco -b "$3" && gsp
    fi
  fi
}

function checkForOpenZSHRCUpdate() {
  local FOXABLES_PATH=$(head -n 1 "$HOME/.foxables-zshrc.path")
  local FOXABLES_UPDATED=$(tail -n 1 "$HOME/.foxables-zshrc.path")
  local NOW=$(date +%s)
  local EXPIRE=$(expr $FOXABLES_UPDATED + 604800)
  if [[ $NOW -lt $EXPIRE ]];
  then
    return
  fi

  stat=$(git -C "$FOXABLES_PATH" fetch origin 2>&1)
  if [[ ! -z "$stat" ]] && [[ ! "$stat" =~ "fatal" ]] && [[ ! "$stat" =~ "not found" ]];
  then
    read -p "A new update for Foxables Open-ZSHRC is available. Would you like to update? [y/N] " -n 1 -r

    if [[ $REPLY =~ ^[Yy]$ ]];
    then
      git -C "$FOXABLES_PATH" pull origin master
      echo "Updated! Please run 'source ~/.zshrc' again."
    else
      echo "$FOXABLES_PATH" > "$HOME/.foxables-zshrc.path"
      echo "$NOW" >> "$HOME/.foxables-zshrc.path"
    fi
  fi
}

function getCMDTimerMagnitudeModifier() {
  if [[ "$CMD_TIMER_MAGNITUDE" == "ms" ]];
  then
  # Milisecond, or 1 thousandth of a second.
    echo 1000000
    return
  elif [[ "$CMD_TIMER_MAGNITUDE" == "us" ]] || [[ "$CMD_TIMER_MAGNITUDE" == "µs" ]];
  then
  # Microsecond, or 1 millionth of a second.
    echo 1000
    return
  fi
  # Default is Nanosecond, or 1 billionth of a second.
  echo 1
}

function systime() {
  local time=$(date $@)
  if [[ "${time: -1}" == "N" ]];
  then
    local gtime=$(gdate $@ 2>&1)
    if [[ ! "$gtime" =~ "not found" ]];
    then
      echo "$gtime"
      return
    else
      # Mac OS X, if gdate is not installed you can't get nanoseconds.
      echo "${time:0:-1}000000000"
      return
    fi
  fi

  echo "$time"
}

function formatFromNS() {
  local delta=$1
  # Days
  p1=$(expr $delta / 1000000000 / 60 / 60 / 24)
  # Hours
  p2=$(expr $delta / 1000000000 / 60 / 60 % 24)
  # Minutes
  p3=$(expr $delta / 1000000000 / 60 % 60 % 24)
  # Seconds
  p4=$(expr $delta % 10000000000 / 1000000000)
  # Miliseconds
  p5=$(expr $delta % 1000000000 / 1000 / 1000 % 1000)
  # Microseconds
  p6=$(expr $delta % 1000000000 / 1000 % 1000)
  # Nanoseconds
  p7=$(expr $delta % 1000000000 % 1000)

  opt=""
  count=0
  vals=($p1 $p2 $p3 $p4 $p5 $p6 $p7)
  for i in "${vals[@]}"
  do
    if [[ $i -gt 0 ]];
    then
      if [[ -z "$opt" ]];
      then
        opt="$i"
      else
        opt="$opt $i"
      fi
      if [[ $count -eq 0 ]];
      then
        opt="${opt}d"
      elif [[ $count -eq 1 ]];
      then
        opt="${opt}h"
      elif [[ $count -eq 2 ]];
      then
        opt="${opt}m"
      elif [[ $count -eq 3 ]];
      then
        opt="${opt}s"
      elif [[ $count -eq 4 ]];
      then
        opt="${opt}ms"
      elif [[ $count -eq 5 ]];
      then
        opt="${opt}µs"
      elif [[ $count -eq 6 ]];
      then
        opt="${opt}ns"
      fi
    fi

    count=$((count+1))
  done
  echo "$opt"
}

function preexec() {
  if [[ -z "$CMD_TIMER" ]] || [[ "$CMD_TIMER" != "true" ]];
  then
    return
  fi

  cur=$(systime +%s%0N)
  if [[ "$cur" =~ "not found" ]] || [[ "${cur: -1}" == "N" ]];
  then
    timerStart=0
    return
  fi

  timerStart=$cur
}

function c() {
  # SSH Connections.
  local USER="$DEFAULT_SSH_USER"
  FALLBACK_USERS=( ec2-user ubnt ubuntu root $(whoami) )

  if [[ -z "$1" ]];
  then
    echo "Usage: c <host> [user] [key]"
    exit 1
  fi
  local HOST="$1"

  if [[ ! -z "$2" ]];
  then
    USER="$2"
  fi

  local KEY=""
  if [[ ! -z "$DEFAULT_SSH_KEY" ]] && [[ -f "$DEFAULT_SSH_KEY" ]];
  then
    KEY="-i '$DEFAULT_SSH_KEY'"
  fi

  if [[ ! -z "$3" ]] && [[ -f "$3" ]];
  then
    KEY="-i $3"
  fi

  local RES=$(ssh $USER@"$HOST" $KEY "uname -mrs")
  if [[ "$RES" =~ "Permission denied" ]];
  then
    for i in "${FALLBACK_USERS[@]}"
    do
      RES=$(ssh $i@"$HOST" $KEY "uname -mrs")
      if [[ ! "$RES" =~ "Permission denied" ]];
      then
        USER="$i"
        break
      fi
    done
  fi
  ssh $USER@"$HOST" $KEY
}

function precmd() {
  if [[ -z "$CMD_TIMER" ]] || [[ "$CMD_TIMER" != "true" ]];
  then
    if [[ ! -z "$RPROMPT" ]];
    then
      export RPROMPT=""
      unset timerStart
    fi
    return
  fi

  if [ $timerStart ] && [ $timerStart -ne 0 ]; then
    cur=$(systime +%s%0N)
    delta=$(($cur-$timerStart))

    elapsedPretty=$(formatFromNS $delta)
    export RPROMPT="%F{$CMD_TIMER_COLOR}${elapsedPretty} %{$reset_color%}"
    unset timerStart
  else
    export RPROMPT="%F{$CMD_TIMER_COLOR}%{$reset_color%}"
  fi
}

# Disable mouse accelleration on mac.
defaults write .GlobalPreferences com.apple.mouse.scaling -1

# NVM
export NVM_DIR="$HOME/.nvm"
  [ -s "/usr/local/opt/nvm/nvm.sh" ] && . "/usr/local/opt/nvm/nvm.sh"  # This loads nvm
  [ -s "/usr/local/opt/nvm/etc/bash_completion" ] && . "/usr/local/opt/nvm/etc/bash_completion"  # This loads nvm bash_completion

checkForOpenZSHRCUpdate

Source: Foxables Open .ZSHRC Raw File

How to Install?

Run the command curl -s https://raw.githubusercontent.com/Foxables/Open-zshrc/master/install.sh > install.sh && bash install.sh && rm -f install.sh && source ~/.zshrc

Foxables Open ZSHRC Repository

GitHub - Foxables/Open-zshrc
Contribute to Foxables/Open-zshrc development by creating an account on GitHub.
Foxables Open .zshrc Public Repository