From 9f133469e034a08c599acc927a02d5f6a3e005c5 Mon Sep 17 00:00:00 2001 From: Ismo Vuorinen Date: Fri, 10 Mar 2023 15:07:44 +0200 Subject: [PATCH] linux: fixes to everything when using linux --- bashrc | 21 ++++-- config/alias | 52 +++++++------- config/git/config | 6 ++ host-tunkki/bash_logout | 7 ++ host-tunkki/bashrc | 117 +++++++++++++++++++++++++++++++ local/bin/dfm | 77 ++++++++++---------- scripts/install-gh-extensions.sh | 91 ++++++++++++------------ scripts/install-go-packages.sh | 43 ++++++------ scripts/install-npm-packages.sh | 65 +++++++++-------- scripts/set-macos-defaults.sh | 2 + zshrc | 15 ++-- 11 files changed, 315 insertions(+), 181 deletions(-) create mode 100644 host-tunkki/bash_logout create mode 100644 host-tunkki/bashrc diff --git a/bashrc b/bashrc index a1a6722..a20758c 100644 --- a/bashrc +++ b/bashrc @@ -1,14 +1,21 @@ -# Fig pre block. Keep at the top of this file. -[[ -f "$HOME/.fig/shell/bashrc.pre.bash" ]] && builtin source "$HOME/.fig/shell/bashrc.pre.bash" # shellcheck shell=bash -PHP_PATH=$(brew --prefix php)/bin +# Fig pre block. Keep at the top of this file. +[[ -f "$HOME/.fig/shell/bashrc.pre.bash" ]] && builtin source "$HOME/.fig/shell/bashrc.pre.bash" + +if command -v brew &> /dev/null; then + PHP_PATH=$(brew --prefix php)/bin + export PATH="$PHP_PATH:$HOME/.composer/vendor/bin/:/usr/local/sbin:$PATH" +fi + +if command -v nvm &> /dev/null; then + 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.d/nvm" ] && . "/usr/local/opt/nvm/etc/bash_completion.d/nvm" # This loads nvm bash_completion +fi -export PATH="$PHP_PATH:$HOME/.composer/vendor/bin/:/usr/local/opt/ruby/bin:/usr/local/sbin:$PATH" -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.d/nvm" ] && . "/usr/local/opt/nvm/etc/bash_completion.d/nvm" # This loads nvm bash_completion # Fig post block. Keep at the bottom of this file. [[ -f "$HOME/.fig/shell/bashrc.post.bash" ]] && builtin source "$HOME/.fig/shell/bashrc.post.bash" +[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" # This loads nvm bash_completion diff --git a/config/alias b/config/alias index 57eb1b7..f5a6464 100644 --- a/config/alias +++ b/config/alias @@ -4,36 +4,38 @@ # Get installed php versions from brew and setup aliases function x-set-php-aliases { - local php_versions=() - while IFS="" read -r line; do php_versions+=("$line"); done < <(brew list | grep '^php') + if command -v brew &> /dev/null; then + local php_versions=() + while IFS="" read -r line; do php_versions+=("$line"); done < <(brew list | grep '^php') - php_error_reporting='-d error_reporting=22527' + php_error_reporting='-d error_reporting=22527' - for version in "${php_versions[@]}"; do - # drop the dot from version (8.0 -> 80) - local php_abbr="${version//\./}" - # replace "php@" with "p" so "php@80" becomes "p80" - local php_alias="${php_abbr//php@/p}" + for version in "${php_versions[@]}"; do + # drop the dot from version (8.0 -> 80) + local php_abbr="${version//\./}" + # replace "php@" with "p" so "php@80" becomes "p80" + local php_alias="${php_abbr//php@/p}" - # Skip php = php aliasing - # if [[ "$php_abbr" == "$php_alias" ]]; then continue; fi; + # Skip php = php aliasing + # if [[ "$php_abbr" == "$php_alias" ]]; then continue; fi; - # Fetch the exec path once - php_exec="$(brew --prefix "$version")/bin/php" + # Fetch the exec path once + php_exec="$(brew --prefix "$version")/bin/php" - # Raw PHP without error_reporting flag. - # shellcheck disable=SC2139 - alias ${php_alias}r="$php_exec" - # PHP with error_reporting flag. - # shellcheck disable=SC2139 - alias $php_alias="$php_exec $php_error_reporting" - # Local PHP Server. - # shellcheck disable=SC2139 - alias ${php_alias}s="$php_exec -S localhost:9000" - # Use composer with specific PHP and error_reporting flag on. - # shellcheck disable=SC2139 - alias ${php_alias}c="$php_exec $php_error_reporting $(which composer)" - done + # Raw PHP without error_reporting flag. + # shellcheck disable=SC2139 + alias "${php_alias}"r="$php_exec" + # PHP with error_reporting flag. + # shellcheck disable=SC2139 + alias "$php_alias"="$php_exec $php_error_reporting" + # Local PHP Server. + # shellcheck disable=SC2139 + alias "${php_alias}"s="$php_exec -S localhost:9000" + # Use composer with specific PHP and error_reporting flag on. + # shellcheck disable=SC2139 + alias "${php_alias}"c="$php_exec $php_error_reporting $(which composer)" + done + fi } if [[ $(uname) == 'Darwin' ]]; then diff --git a/config/git/config b/config/git/config index db7dde8..4fcf108 100644 --- a/config/git/config +++ b/config/git/config @@ -53,3 +53,9 @@ [submodule] recurse = true +[credential "https://github.com"] + helper = + helper = !/usr/bin/gh auth git-credential +[credential "https://gist.github.com"] + helper = + helper = !/usr/bin/gh auth git-credential diff --git a/host-tunkki/bash_logout b/host-tunkki/bash_logout new file mode 100644 index 0000000..de4f5f7 --- /dev/null +++ b/host-tunkki/bash_logout @@ -0,0 +1,7 @@ +# ~/.bash_logout: executed by bash(1) when login shell exits. + +# when leaving the console clear the screen to increase privacy + +if [ "$SHLVL" = 1 ]; then + [ -x /usr/bin/clear_console ] && /usr/bin/clear_console -q +fi diff --git a/host-tunkki/bashrc b/host-tunkki/bashrc new file mode 100644 index 0000000..b488fcc --- /dev/null +++ b/host-tunkki/bashrc @@ -0,0 +1,117 @@ +# ~/.bashrc: executed by bash(1) for non-login shells. +# see /usr/share/doc/bash/examples/startup-files (in the package bash-doc) +# for examples + +# If not running interactively, don't do anything +case $- in + *i*) ;; + *) return;; +esac + +# don't put duplicate lines or lines starting with space in the history. +# See bash(1) for more options +HISTCONTROL=ignoreboth + +# append to the history file, don't overwrite it +shopt -s histappend + +# for setting history length see HISTSIZE and HISTFILESIZE in bash(1) +HISTSIZE=1000 +HISTFILESIZE=2000 + +# check the window size after each command and, if necessary, +# update the values of LINES and COLUMNS. +shopt -s checkwinsize + +# If set, the pattern "**" used in a pathname expansion context will +# match all files and zero or more directories and subdirectories. +#shopt -s globstar + +# make less more friendly for non-text input files, see lesspipe(1) +[ -x /usr/bin/lesspipe ] && eval "$(SHELL=/bin/sh lesspipe)" + +# set variable identifying the chroot you work in (used in the prompt below) +if [ -z "${debian_chroot:-}" ] && [ -r /etc/debian_chroot ]; then + debian_chroot=$(cat /etc/debian_chroot) +fi + +# set a fancy prompt (non-color, unless we know we "want" color) +case "$TERM" in + xterm-color|*-256color) color_prompt=yes;; +esac + +# uncomment for a colored prompt, if the terminal has the capability; turned +# off by default to not distract the user: the focus in a terminal window +# should be on the output of commands, not on the prompt +#force_color_prompt=yes + +if [ -n "$force_color_prompt" ]; then + if [ -x /usr/bin/tput ] && tput setaf 1 >&/dev/null; then + # We have color support; assume it's compliant with Ecma-48 + # (ISO/IEC-6429). (Lack of such support is extremely rare, and such + # a case would tend to support setf rather than setaf.) + color_prompt=yes + else + color_prompt= + fi +fi + +if [ "$color_prompt" = yes ]; then + PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ ' +else + PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ ' +fi +unset color_prompt force_color_prompt + +# If this is an xterm set the title to user@host:dir +case "$TERM" in +xterm*|rxvt*) + PS1="\[\e]0;${debian_chroot:+($debian_chroot)}\u@\h: \w\a\]$PS1" + ;; +*) + ;; +esac + +# enable color support of ls and also add handy aliases +if [ -x /usr/bin/dircolors ]; then + test -r ~/.dircolors && eval "$(dircolors -b ~/.dircolors)" || eval "$(dircolors -b)" + alias ls='ls --color=auto' + #alias dir='dir --color=auto' + #alias vdir='vdir --color=auto' + + alias grep='grep --color=auto' + alias fgrep='fgrep --color=auto' + alias egrep='egrep --color=auto' +fi + +# colored GCC warnings and errors +#export GCC_COLORS='error=01;31:warning=01;35:note=01;36:caret=01;32:locus=01:quote=01' + +# some more ls aliases +alias ll='ls -alF' +alias la='ls -A' +alias l='ls -CF' + +# Add an "alert" alias for long running commands. Use like so: +# sleep 10; alert +alias alert='notify-send --urgency=low -i "$([ $? = 0 ] && echo terminal || echo error)" "$(history|tail -n1|sed -e '\''s/^\s*[0-9]\+\s*//;s/[;&|]\s*alert$//'\'')"' + +# Alias definitions. +# You may want to put all your additions into a separate file like +# ~/.bash_aliases, instead of adding them here directly. +# See /usr/share/doc/bash-doc/examples in the bash-doc package. + +if [ -f ~/.bash_aliases ]; then + . ~/.bash_aliases +fi + +# enable programmable completion features (you don't need to enable +# this, if it's already enabled in /etc/bash.bashrc and /etc/profile +# sources /etc/bash.bashrc). +if ! shopt -oq posix; then + if [ -f /usr/share/bash-completion/bash_completion ]; then + . /usr/share/bash-completion/bash_completion + elif [ -f /etc/bash_completion ]; then + . /etc/bash_completion + fi +fi diff --git a/local/bin/dfm b/local/bin/dfm index c42669c..816ec93 100755 --- a/local/bin/dfm +++ b/local/bin/dfm @@ -14,6 +14,7 @@ SCRIPT=$(basename "$0") +# shellcheck source=./../../scripts/shared.sh source "$DOTFILES/scripts/shared.sh" function section_reset @@ -30,10 +31,10 @@ function section_reset ln -s ~/.dotfiles/config/astronvim ~/.config/astronvim ln -s ~/.dotfiles/config/nvim ~/.config/nvim msg_ok "Linked nvim and astronvim" - $0 install brew - $0 install ext_go - $0 install ext_npm - msg_ok "Installed brew, and packages for go and npm" + hash brew 2>/dev/null && $0 install brew + hash go 2>/dev/null && $0 install ext_go + hash npm 2>/dev/null && $0 install ext_npm + msg_ok "Installed packages" msg_done "...and we are done!" ;; *) @@ -52,16 +53,12 @@ function section_install all) $0 install antigen $0 install macos - $0 install brew $0 install ext_gh $0 install ext_go ;; antigen) curl -L git.io/antigen > "$DOTFILES/local/bin/antigen.zsh" && msg_done "🎉 New antigen installed!" ;; - brew) - brew bundle install --file="$BREWFILE" && msg_done "🎉 macOS Defaults set!" - ;; macos) bash "$DOTFILES/scripts/set-macos-defaults.sh" && msg_done "🎉 Brewfile defined apps has been installed!" ;; @@ -78,10 +75,9 @@ function section_install bash "$DOTFILES/scripts/settler.sh" && msg_done "🎉 Settler has been run!" ;; *) - menu_section "$USAGE_PREFIX" "all | antigen | brew | ext_gh | ext_go | ext_npm | macos | settler" + menu_section "$USAGE_PREFIX" "all | antigen | ext_gh | ext_go | ext_npm | macos | settler" menu_item "all" "Installs antigen, macos, brew, ext_gh and ext_go" menu_item "antigen" "Updates the antigen.zsh file" - menu_item "brew" "Install Brewfile contents" menu_item "ext_gh" "Install GitHub CLI Extensions" menu_item "ext_go" "Install Go Packages" menu_item "ext_npm" "Install NPM Packages" @@ -96,37 +92,36 @@ function section_brew USAGE_PREFIX="$SCRIPT brew" if ! command -v brew &> /dev/null; then - echo "brew could not be found, please install it first" - exit + menu_section "$USAGE_PREFIX" "brew not available on this system" + else + case "$1" in + install) + brew bundle install --file="$BREWFILE" && msg_done "🎉 Done!" + ;; + update) + brew update && brew outdated && brew upgrade && brew cleanup + msg_done "🎉 Done!" + ;; + updatebundle) + # Updates .dotfiles/Brewfile with descriptions + brew bundle dump \ + --force \ + --file="$BREWFILE" \ + --describe && msg_done "🎉 Done!" + ;; + autoupdate) + brew autoupdate delete + brew autoupdate start 43200 --upgrade --cleanup --immediate + ;; + *) + menu_section "$USAGE_PREFIX" "install | update | updatebundle | autoupdate" + menu_item "install" "Installs items defined in Brewfile" + menu_item "update" "Updates and upgrades brew packages" + menu_item "updatebundle" "Updates Brewfile with descriptions" + menu_item "autoupdate" "Setups brew auto-update and runs it immediately" + ;; + esac fi - - case "$1" in - install) - brew bundle install --file="$BREWFILE" && msg_done "🎉 Done!" - ;; - update) - brew update && brew outdated && brew upgrade && brew cleanup - msg_done "🎉 Done!" - ;; - updatebundle) - # Updates .dotfiles/Brewfile with descriptions - brew bundle dump \ - --force \ - --file="$BREWFILE" \ - --describe && msg_done "🎉 Done!" - ;; - autoupdate) - brew autoupdate delete - brew autoupdate start 43200 --upgrade --cleanup --immediate - ;; - *) - menu_section "$USAGE_PREFIX" "install | update | updatebundle | autoupdate" - menu_item "install" "Installs items defined in Brewfile" - menu_item "update" "Updates and upgrades brew packages" - menu_item "updatebundle" "Updates Brewfile with descriptions" - menu_item "autoupdate" "Setups brew auto-update and runs it immediately" - ;; - esac } function section_dotfiles @@ -210,5 +205,5 @@ case "$1" in brew) section_brew "$2" ;; dotfiles) section_dotfiles "$2" ;; tests) section_tests "$2" ;; - *) usage && exit 1 ;; + *) usage && exit 0 ;; esac diff --git a/scripts/install-gh-extensions.sh b/scripts/install-gh-extensions.sh index edf5976..d00b32b 100755 --- a/scripts/install-gh-extensions.sh +++ b/scripts/install-gh-extensions.sh @@ -1,54 +1,53 @@ #!/usr/bin/env bash # Install GitHub CLI extensions - +# # shellcheck source="shared.sh" source "$HOME/.dotfiles/scripts/shared.sh" if ! command -v gh &> /dev/null; then msg_run "gh (GitHub Client) could not be found, please install it first" - exit 1 +else + extensions=( + # GitHub CLI extension for reviewing Dependabot PRs. + einride/gh-dependabot + # A GitHub CLI extension that provides summary pull request metrics. + hectcastro/gh-metrics + # being an extension to view the overall health of an organization's use of actions + rsese/gh-actions-status + # GitHub CLI extension for label management + heaths/gh-label + # An opinionated GitHub Cli extension for creating + # changelogs that adhere to the keep a changelog specification. + chelnak/gh-changelog + # Safely deletes local branches with no upstream and no un-pushed commits + davidraviv/gh-clean-branches + # A beautiful CLI dashboard for GitHub 🚀 + dlvhdr/gh-dash + # A github-cli extension script to clone all repositories + # in an organization, optionally filtering by topic. + matt-bartel/gh-clone-org + # GitHub CLI extension to generate montage from GitHub user avatars + andyfeller/gh-montage + # Organisation specific extension for gh cli to retrieve different statistics + VildMedPap/gh-orgstats + # GitHub CLI extension for generating a report on repository dependencies. + andyfeller/gh-dependency-report + # gh cli extension to generate account/organization/enterprise reports + stoe/gh-report + ) + + msg "Starting to install GitHub CLI extensions..." + + for ext in "${extensions[@]}"; do + # Trim spaces + ext=${ext// /} + # Skip comments + if [[ ${ext:0:1} == "#" ]]; then continue; fi + + msg_run "Installing $ext" + gh extensions install "$ext" + echo "" + done + + msg_ok "Done" fi - -extensions=( - # GitHub CLI extension for reviewing Dependabot PRs. - einride/gh-dependabot - # A GitHub CLI extension that provides summary pull request metrics. - hectcastro/gh-metrics - # being an extension to view the overall health of an organization's use of actions - rsese/gh-actions-status - # GitHub CLI extension for label management - heaths/gh-label - # An opinionated GitHub Cli extension for creating - # changelogs that adhere to the keep a changelog specification. - chelnak/gh-changelog - # Safely deletes local branches with no upstream and no un-pushed commits - davidraviv/gh-clean-branches - # A beautiful CLI dashboard for GitHub 🚀 - dlvhdr/gh-dash - # A github-cli extension script to clone all repositories - # in an organization, optionally filtering by topic. - matt-bartel/gh-clone-org - # GitHub CLI extension to generate montage from GitHub user avatars - andyfeller/gh-montage - # Organisation specific extension for gh cli to retrieve different statistics - VildMedPap/gh-orgstats - # GitHub CLI extension for generating a report on repository dependencies. - andyfeller/gh-dependency-report - # gh cli extension to generate account/organization/enterprise reports - stoe/gh-report -) - -msg "Starting to install GitHub CLI extensions..." - -for ext in "${extensions[@]}"; do - # Trim spaces - ext=${ext// /} - # Skip comments - if [[ ${ext:0:1} == "#" ]]; then continue; fi - - msg_run "Installing $ext" - gh extensions install "$ext" - echo "" -done - -msg_ok "Done" diff --git a/scripts/install-go-packages.sh b/scripts/install-go-packages.sh index 719f4a7..a67138c 100755 --- a/scripts/install-go-packages.sh +++ b/scripts/install-go-packages.sh @@ -1,27 +1,28 @@ -#!/usr/bin/env zsh +#!/usr/bin/env bash # Install Go packages - +# +# shellcheck source=shared.sh source "$HOME/.dotfiles/scripts/shared.sh" if ! command -v go &> /dev/null; then msg "go hasn't been installed yet." - exit 0 +else + packages=( + # sysadmin/scripting utilities, distributed as a single binary + github.com/skx/sysbox@latest + ) + + for pkg in "${packages[@]}"; do + # Trim spaces + pkg=${pkg// /} + # Skip comments + if [[ ${pkg:0:1} == "#" ]]; then continue; fi + + msg_run "Installing go package:" "$pkg" + go install "$pkg" + echo "" + done + + msg_ok "Done" + fi - -packages=( - # sysadmin/scripting utilities, distributed as a single binary - github.com/skx/sysbox@latest -) - -for pkg in "${packages[@]}"; do - # Trim spaces - pkg=${pkg// /} - # Skip comments - if [[ ${pkg:0:1} == "#" ]]; then continue; fi - - msg_run "Installing go package:" "$pkg" - go install "$pkg" - echo "" -done - -msg_ok "Done" diff --git a/scripts/install-npm-packages.sh b/scripts/install-npm-packages.sh index d782d2a..8a38aac 100755 --- a/scripts/install-npm-packages.sh +++ b/scripts/install-npm-packages.sh @@ -1,39 +1,38 @@ -#!/usr/bin/env zsh +#!/usr/bin/env bash # Install npm packages globally. - +# +# shellcheck source=shared.sh source "$HOME/.dotfiles/scripts/shared.sh" if ! command -v npm &> /dev/null; then msg_err "npm could not be found." - exit 1 +else + packages=( + # This is a tool to check if your files consider your .editorconfig rules. + "editorconfig-checker" + # Node module to create a release or a changelog from + # a tag and uses issues or commits to creating the release notes. + "github-release-notes" + "neovim" + "prettier" + "@bchatard/alfred-jetbrains" + "@johnnymorganz/stylua-bin" + "js-debug" + "stylelint-lsp" + "blade-formatter" + "@loopback/cli" + "corepack" + "standardjs" + ) + + for pkg in "${packages[@]}"; do + # Trim spaces + pkg=${pkg// /} + # Skip comments + if [[ ${pkg:0:1} == "#" ]]; then continue; fi + + msg_run "Installing npm package:" "$pkg" + npm install -g --no-fund --no-progress --no-timing "$pkg" + echo "" + done fi - -packages=( - # This is a tool to check if your files consider your .editorconfig rules. - "editorconfig-checker" - # Node module to create a release or a changelog from - # a tag and uses issues or commits to creating the release notes. - "github-release-notes" - "neovim" - "prettier" - "@bchatard/alfred-jetbrains" - "@johnnymorganz/stylua-bin" - "js-debug" - "stylelint-lsp" - "blade-formatter" - "@loopback/cli" - "corepack" - "standardjs" -) - -for pkg in "${packages[@]}"; do - # Trim spaces - pkg=${pkg// /} - # Skip comments - if [[ ${pkg:0:1} == "#" ]]; then continue; fi - - msg_run "Installing npm package:" "$pkg" - npm install -g --no-fund --no-progress --no-timing "$pkg" - echo "" -done - diff --git a/scripts/set-macos-defaults.sh b/scripts/set-macos-defaults.sh index ac7f54a..9798b76 100755 --- a/scripts/set-macos-defaults.sh +++ b/scripts/set-macos-defaults.sh @@ -6,6 +6,8 @@ # - https://github.com/freekmurze/dotfiles/blob/main/macos/set-defaults.sh # +[ "$(uname)" != "Darwin" ] && echo "Not a macOS system" && exit 0; + # Ask for the administrator password upfront sudo -v diff --git a/zshrc b/zshrc index 5e1afcf..e3797ea 100644 --- a/zshrc +++ b/zshrc @@ -35,6 +35,13 @@ if [ command -v brew &> /dev/null ]; then export PATH="$BREW_PYTHON:$GNUBIN_DIR:$BREW_GEMS:$BREW_RUBY:$BREW_BIN:$BREW_SBIN:$PATH" fi +# nvm, the node version manager +export NVM_LAZY_LOAD=true +export NVM_COMPLETION=true +export NVM_AUTO_USE=true +export NVM_DIR="$([ -z "${XDG_CONFIG_HOME-}" ] && printf %s "${HOME}/.nvm" || printf %s "${XDG_CONFIG_HOME}/nvm")" +[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm + # If we have go packages, include them to the PATH if command -v go &> /dev/null; then export GOPATH=$(go env GOPATH); @@ -63,13 +70,6 @@ if command -v gem &>/dev/null; then export GEM_PATH="$XDG_STATE_HOME/gem" fi -# nvm, the node version manager -export NVM_DIR="$XDG_STATE_HOME/nvm" -export NVM_LAZY_LOAD=true -export NVM_COMPLETION=true -export NVM_AUTO_USE=true -[ -s "$HOMEBREW_PKG/nvm/nvm.sh" ] && \. "$HOMEBREW_PKG/nvm/nvm.sh" -[ -s "$HOMEBREW_PKG/nvm/etc/bash_completion.d/nvm" ] && \. "$HOMEBREW_PKG/nvm/etc/bash_completion.d/nvm" # wakatime, https://github.com/wakatime/wakatime-cli export WAKATIME_HOME="$XDG_STATE_HOME/wakatime" @@ -115,7 +115,6 @@ if command -v antigen &> /dev/null; then hash php 2>/dev/null && antigen bundle php hash nvm 2>/dev/null && antigen bundle nvm hash docker 2>/dev/null && antigen bundle docker - # hash ruby 2>/dev/null && antigen bundle ruby hash python 2>/dev/null && antigen bundle MichaelAquilina/zsh-autoswitch-virtualenv hash jq 2>/dev/null && antigen bundle reegnz/jq-zsh-plugin hash docker-compose 2>/dev/null && antigen bundle sroze/docker-compose-zsh-plugin