Last active
August 29, 2023 09:54
-
-
Save architeacher/56d8359556c2ec3642189b4793f75280 to your computer and use it in GitHub Desktop.
First mac installation.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
# Install using | |
# bash <(curl -sSfL https://gist.githubusercontent.com/architeacher/56d8359556c2ec3642189b4793f75280/raw/aef18c031714bfb70b5b9db200ce8a5789b27a47/mac.sh) -e <YOUR_EMAIL> -n "<YOUR_NAME>" | |
set -eo pipefail | |
exit_status=0 | |
#--- Logging | |
readonly LOG_LEVEL_DEBUG=7 | |
readonly LOG_LEVEL_INFO=6 | |
readonly LOG_LEVEL_NOTICE=5 | |
readonly LOG_LEVEL_WARNING=4 | |
readonly LOG_LEVEL_ERROR=3 | |
readonly LOG_LEVEL_CRITICAL=2 | |
readonly LOG_LEVEL_ALERT=1 | |
readonly LOG_LEVEL_EMERGENCY=0 | |
_log_level="${LOG_LEVEL_INFO}" | |
# string formatters, True if go_file descriptor FD is open and refers to a terminal. | |
tty_escape() { :; } | |
if [[ -t 1 ]] | |
then | |
tty_escape() { printf "\x1b[%sm" "${1}"; } | |
fi | |
tty_4bit_mk() { tty_escape "${1}"; } | |
tty_8bit_mk() { tty_escape "38;5;${1}"; } | |
tty_4bit_mkbold() { tty_4bit_mk "${1};1"; } | |
tty_8bit_mkbold() { tty_8bit_mk "${1};1"; } | |
tty_bold="$(tty_4bit_mkbold 39)" | |
tty_underline="$(tty_escape "4;39")" | |
tty_reset="$(tty_escape 0)" | |
tty_blue="$(tty_4bit_mk 34)" | |
tty_corn="$(tty_8bit_mk 178)" | |
tty_cyan="$(tty_8bit_mk 45)" | |
tty_green="$(tty_8bit_mk 35)" | |
tty_imperial="$(tty_4bit_mk 91)" | |
tty_lime="$(tty_8bit_mk 113)" | |
tty_magenta="$(tty_8bit_mk 170)" | |
tty_move="$(tty_4bit_mk 35)" | |
tty_olive="$(tty_8bit_mk 64)" | |
tty_orange="$(tty_8bit_mk 208)" | |
tty_pink="$(tty_8bit_mk 198)" | |
tty_red="$(tty_8bit_mkbold 196)" | |
tty_teal="$(tty_4bit_mk 36)" | |
tty_yellow="$(tty_8bit_mk 227)" | |
log_set_level() { | |
_log_level="${1}" | |
} | |
log_priority() { | |
local log_level="${1}" | |
if test -z "${log_level}"; then | |
echo "${log_level}" | |
return | |
fi | |
[ "${log_level}" -le "${_log_level}" ] | |
} | |
display_message() { | |
echo -e "${@}" 1>&2 | |
} | |
log_color() { | |
local log_level="${1}" \ | |
tty_color="" | |
case "${log_level}" in | |
"${LOG_LEVEL_DEBUG}") | |
tty_color="${tty_cyan}" | |
;; | |
"${LOG_LEVEL_INFO}") | |
tty_color="${tty_olive}" | |
;; | |
"${LOG_LEVEL_NOTICE}") | |
tty_color="${tty_green}" | |
;; | |
"${LOG_LEVEL_WARNING}") | |
tty_color="${tty_corn}" | |
;; | |
"${LOG_LEVEL_ERROR}") | |
tty_color="${tty_magenta}" | |
;; | |
"${LOG_LEVEL_CRITICAL}") | |
tty_color="${tty_imperial}" | |
;; | |
"${LOG_LEVEL_ALERT}") | |
tty_color="${tty_pink}" | |
;; | |
"${LOG_LEVEL_EMERGENCY}") | |
tty_color="${tty_red}" | |
;; | |
*) | |
tty_color="${tty_bold}" | |
;; | |
esac | |
printf "%s" "${tty_color}" | |
} | |
log_tag() { | |
local log_level="${1}" \ | |
tag="" | |
case "${log_level}" in | |
"${LOG_LEVEL_DEBUG}") | |
tag="Debug" | |
;; | |
"${LOG_LEVEL_INFO}") | |
tag="Info" | |
;; | |
"${LOG_LEVEL_NOTICE}") | |
tag="Notice" | |
;; | |
"${LOG_LEVEL_WARNING}") | |
tag="Warning" | |
;; | |
"${LOG_LEVEL_ERROR}") | |
tag="Error" | |
;; | |
"${LOG_LEVEL_CRITICAL}") | |
tag="Critical" | |
;; | |
"${LOG_LEVEL_ALERT}") | |
tag="Alert" | |
;; | |
"${LOG_LEVEL_EMERGENCY}") | |
tag="Emergency" | |
;; | |
*) | |
tag="" | |
;; | |
esac | |
printf "%s" "${tag}" | |
} | |
log_prefix() { | |
echo "==>" | |
} | |
log() { | |
local log_level="${1}" \ | |
message="" \ | |
tty_color="" \ | |
tag="" | |
{ | |
read -r tty_color | |
} <<< "$(log_color "${log_level}")" | |
{ | |
read -r tag | |
} <<< "$(log_tag "${log_level}")" | |
shift | |
message="${*}" | |
if [ "${tty_color}" != "" ]; then | |
display_message "${tty_color}" "$(log_prefix)" "${tag}: " "${message}" "${tty_reset}" | |
else | |
printf "%s %b" "$(log_prefix)" "${message}" | |
fi | |
} | |
log_debug() { | |
log_priority "${LOG_LEVEL_DEBUG}" || return 0 | |
log "${LOG_LEVEL_DEBUG}" "${@}" | |
} | |
log_info() { | |
log_priority "${LOG_LEVEL_INFO}" || return 0 | |
log "${LOG_LEVEL_INFO}" "${@}" | |
} | |
log_notice() { | |
log_priority "${LOG_LEVEL_NOTICE}" || return 0 | |
log "${LOG_LEVEL_NOTICE}" "${@}" | |
} | |
log_warning() { | |
log_priority "${LOG_LEVEL_WARNING}" || return 0 | |
log "${LOG_LEVEL_WARNING}" "${@}" | |
} | |
log_error() { | |
log_priority "${LOG_LEVEL_ERROR}" || return 0 | |
log "${LOG_LEVEL_ERROR}" "${@}" | |
} | |
log_critical() { | |
log_priority "${LOG_LEVEL_CRITICAL}" || return 0 | |
log "${LOG_LEVEL_CRITICAL}" "${@}" | |
} | |
log_alert() { | |
log_priority "${LOG_LEVEL_ALERT}" || return 0 | |
log "${LOG_LEVEL_ALERT}" "${@}" | |
} | |
log_emergency() { | |
log_priority "${LOG_LEVEL_EMERGENCY}" || return 0 | |
log "${LOG_LEVEL_EMERGENCY}" "${@}" | |
} | |
parse_log_level() { | |
local log_input="${1}" \ | |
log_level="" | |
case "${log_input}" in | |
"debug") | |
log_level="${LOG_LEVEL_DEBUG}" | |
;; | |
"info") | |
log_level="${LOG_LEVEL_INFO}" | |
;; | |
"notice") | |
log_level="${LOG_LEVEL_NOTICE}" | |
;; | |
"warning") | |
log_level="${LOG_LEVEL_WARNING}" | |
;; | |
"error") | |
log_level="${LOG_LEVEL_ERROR}" | |
;; | |
"critical") | |
log_level="${LOG_LEVEL_CRITICAL}" | |
;; | |
"alert") | |
log_level="${LOG_LEVEL_ALERT}" | |
;; | |
"emergency") | |
log_level="${LOG_LEVEL_EMERGENCY}" | |
;; | |
*) | |
abort "Invalid log level: ${log_level}" | |
;; | |
esac | |
echo "${log_level}" | |
} | |
#--- | |
SUDO= | |
# abort with an error message. | |
abort() { | |
local message="${1}" | |
log_error "${message}" | |
exit 1 | |
} | |
is_command() { | |
command -v "${1}" 2> /dev/null | |
} | |
check_sudo() { | |
if [ "$(id -u)" -eq 0 ]; then | |
return | |
fi | |
SUDO=$(is_command "sudo") | |
[ ! -x "${SUDO}" ] && abort "This script must be executed as root." | |
} | |
get_profile() { | |
local shell_profile="${HOME}/.bash_profile" | |
case "${SHELL}" in | |
*/bash*) | |
if [[ -r "${HOME}/.bash_profile" ]] | |
then | |
shell_profile="${HOME}/.bash_profile" | |
else | |
shell_profile="${HOME}/.profile" | |
fi | |
;; | |
*/zsh*) | |
shell_profile="${HOME}/.zprofile" | |
;; | |
*) | |
shell_profile="${HOME}/.profile" | |
;; | |
esac | |
print "${shell_profile}" | |
} | |
get_random_string() { | |
print "$(export LC_CTYPE=C; cat </dev/urandom | tr -dc 'a-zA-Z0-9\.' | fold -w 32 | head -n 1)" | |
} | |
validate_bash() { | |
# Fail fast with a concise message when not using bash | |
# Single brackets are needed here for POSIX compatibility | |
# shellcheck disable=SC2292 | |
[ -z "${BASH_VERSION:-}" ] && abort "Bash is required to interpret this script." | |
# Check if running in a compatible bash version. | |
((BASH_VERSINFO[0] < 3)) && abort "Bash version 3 or above is required." | |
# Check if script is run in POSIX mode. | |
if [[ -n "${POSIXLY_CORRECT+1}" ]] | |
then | |
abort "Bash must not run in POSIX compatibility mode. Please disable by unsetting POSIXLY_CORRECT and try again." | |
fi | |
} | |
# -- | |
# Environment preparations. | |
prepare() { | |
log_info "Preparing..." | |
if [ -n "${HOMEBREW_GITHUB_API_TOKEN+z}" ]; then | |
log_err "\$HOMEBREW_GITHUB_API_TOKEN is set"; | |
return | |
fi | |
log_info "Please enter, Github api token https://github.com/settings/tokens: " && read -r github_api_token | |
# Github for homebrew installation. | |
export HOMEBREW_GITHUB_API_TOKEN="${github_api_token}" | |
printf "# Homebrew github token:\nHOMEBREW_GITHUB_API_TOKEN=\"%s\"" "${HOMEBREW_GITHUB_API_TOKEN}" > "$(get_profile)" | |
} | |
# Creating .netrc file https://www.gnu.org/software/inetutils/manual/html_node/The-_002enetrc-file.html | |
create_netrc() { | |
log_info "Creating .netrc file..." | |
touch "${HOME}/.netrc" 2>&1 | |
{ | |
echo "# Configuration example, please uncomment the following lines." | |
echo "# machine host_name" | |
echo "# login ahmed.kamal" | |
echo "# password secret-$(get_random_string)" | |
} >> "${HOME}/.netrc" | |
${SUDO} chmod 600 "${HOME}/.netrc" | |
} | |
# SSH configurations | |
configure_ssh() { | |
log_info "Configuring SSH..." | |
cat <<'EOF' >"${HOME}/.ssh/config" | |
Host * | |
AddKeysToAgent yes | |
Ciphers aes128-ctr,aes192-ctr,aes256-ctr,aes128-cbc,3des-cbc | |
ForwardAgent yes | |
HashKnownHosts no | |
# IdentitiesOnly yes | |
IdentityFile ~/.ssh/id_rsa | |
IPQoS=throughput | |
LogLevel ERROR | |
ServerAliveCountMax 3 | |
ServerAliveInterval 10 # 600 | |
StrictHostKeyChecking no | |
TCPKeepAlive yes | |
User ahka | |
UseKeychain yes # <--- mac only | |
UserKnownHostsFile /dev/null | |
EOF | |
} | |
# SSH keys generation. | |
generate_ssh_keys() { | |
log_info "Generating SSH Keys..." | |
ssh-keygen -t rsa | |
printf "pbcopy < ~/.ssh/id_rsa.pub\n" | |
} | |
# Homebrew installation. | |
install_brew() { | |
log_info "Installing Homebrew..." | |
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" | |
printf "\n\neval \"\$(/opt/homebrew/bin/brew shellenv)\"" | tee -a "$(get_profile)" > /dev/null | |
eval "$(/opt/homebrew/bin/brew shellenv)" | |
brew up | |
brew upgrade | |
} | |
install_browsers() { | |
log_info "Installing Browsers..." | |
brew install -f \ | |
arc \ | |
brave-browser \ | |
google-chrome | |
} | |
install_dev_tools() { | |
log_info "Installing Dev Tools..." | |
brew install -f \ | |
graphviz \ | |
iterm2 \ | |
jetbrains-toolbox \ | |
medis \ | |
postman \ | |
visual-studio-code | |
} | |
# Docker installation | |
install_docker() { | |
log_info "Installing Docker..." | |
brew install -f \ | |
Caskroom/cask/docker \ | |
ctop \ | |
dive \ | |
lazydocker | |
# Add cleaning commands to .profile only as a reference. | |
cat <<'EOF' >~/.profile | |
# Docker cleaning configuration: | |
docker images -aqf dangling=true | |
docker image prune | |
docker ps -aqf status=exited -f status=dead | |
docker container prune | |
docker volume ls -qf dangling=true | |
docker volume prune | |
docker system prune | |
docker container ls -a --format "table {{.ID}} {{.Names}} {{json .Ports}}" | |
EOF | |
} | |
# Git installation | |
install_git() { | |
log_info "Installing GIT..." | |
brew install -f \ | |
git \ | |
gpg | |
local git_username="${1}" \ | |
git_email="${2}" | |
if [ -z "${git_username}" ]; then | |
echo "Git config user.name: " && read -r git_username | |
fi | |
if [ -z "${git_email}" ]; then | |
echo "Git config user.email: " && read -r git_email | |
fi | |
git config --global user.name "${git_username}" | |
git config --global user.email "${git_email}" | |
# Colored branch names. | |
git config --global color.ui auto | |
git config --global color.diff-highlight.oldNormal "red bold" | |
git config --global color.diff-highlight.oldHighlight "red bold 52" | |
git config --global color.diff-highlight.newNormal "green bold" | |
git config --global color.diff-highlight.newHighlight "green bold 22" | |
git config --global color.diff.meta "11" | |
git config --global color.diff.frag "magenta bold" | |
git config --global color.diff.func "146 bold" | |
git config --global color.diff.commit "yellow bold" | |
git config --global color.diff.old "red bold" | |
git config --global color.diff.new "green bold" | |
git config --global color.diff.whitespace "red reverse" | |
# Disable auto-converting CRLF line endings into LF. | |
git config --global core.autocrlf false | |
# Working with Unix line endings (LF). | |
git config --global core.eol LF | |
# Ignoring file mode changes for git calculation of file-is-modified. | |
git config --global core.filemode false | |
# Making directories and file names case insensitive. | |
git config --global core.ignorecase true | |
# Setting the default branch for new repositories. | |
git config --global init.defaultBranch main | |
# Prevent pushing all locally modified branches if the branch to push is not specified while 'git push'. | |
git config --global push.default nothing | |
# If you are too lazy for typing "git checkout", "git status" or "git branch" all the time, it might be useful for you. | |
git config --global alias.co checkout | |
git config --global alias.ci commit | |
git config --global alias.st status | |
git config --global alias.br branch | |
git config --global alias.hist 'log --pretty=format:"%h %ad | %s%d [%an]" --graph --date=short' | |
# Example git count-lines "Ahmed Kamal" | |
git config --global alias.count-lines "! git log --author=\"\$1\" --pretty=tformat: --numstat | awk '{ add += \$1; subs += \$2; loc += \$1 - \$2 } END { printf \"added lines: %s, removed lines: %s, total lines: %s\n\", add, subs, loc }' #" | |
# Example git count-commits "Ahmed Kamal" | |
git config --global alias.count-commits "! git shortlog --author=\"\$1\" -s -n --all --no-merges #" | |
# Signing commits. | |
gpg --gen-key | |
# git config --global gpg.program gpg | |
local gpg_key_id | |
gpg_key_id=$(gpg --list-secret-keys --keyid-format 0xLONG | \ | |
grep -B 2 "<${git_email}>" | \ | |
grep -Eiom 1 '0x([0-9a-zA-Z]+)' | \ | |
sed -r 's|0x([0-9a-zA-Z]+)|\1|g') | |
git config --global user.signingkey "${gpg_key_id}" | |
printf "\ngpg --armor --export %s | pbcopy\n" "${gpg_key_id}" | |
} | |
install_golang() { | |
log_info "Installing Golang..." | |
brew install -f \ | |
go | |
local go_path="${HOME}/go" | |
mkdir -p "${go_path}/"{bin,pkg,src} | |
cat <<-EOF >>"$(get_profile)" | |
# Go configurations: | |
go_bin=\$(which go) | |
go_bin_dir=\$(dirname "\${go_bin}") | |
go_relative_bin_dir=\$(dirname \`readlink "\${go_bin}"\`) | |
export GOROOT=\$(cd "\${go_bin_dir}/\${go_relative_bin_dir}/../libexec"; pwd) | |
export GOPATH="${go_path}" | |
export PATH="\${PATH}:\${GOPATH}/bin:/usr/local/sbin" | |
EOF | |
} | |
install_go_tools() { | |
# Open API code generation tool. | |
go install github.com/deepmap/oapi-codegen/cmd/oapi-codegen@latest | |
} | |
install_grpc() { | |
log_info "Installing GRPC..." | |
brew install -f \ | |
bufbuild/buf/buf \ | |
grpcui \ | |
grpcurl \ | |
protoc-gen-go \ | |
protoc-gen-go-grpc | |
go install github.com/envoyproxy/protoc-gen-validate@latest | |
} | |
# Kubernetes installation | |
install_k8s() { | |
log_info "Installing Kubernetes..." | |
brew install -f \ | |
helm \ | |
kind \ | |
kustomize \ | |
k9s | |
#k3d \ | |
#minikube | |
#minikube start --driver=virtualbox | |
} | |
install_tools() { | |
log_info "Installing Tools..." | |
#xcode-select --install | |
brew install -f \ | |
ag \ | |
bat \ | |
bpytop \ | |
broot \ | |
cheat \ | |
delta \ | |
dog \ | |
duf \ | |
dust \ | |
exa \ | |
fd \ | |
fig \ | |
fx \ | |
fzf \ | |
glow \ | |
gping \ | |
hexyl \ | |
htop-osx \ | |
hyperfine \ | |
jq \ | |
lsd \ | |
midnight-commander \ | |
mkcert \ | |
procs \ | |
ripgrep \ | |
teleport \ | |
tldr \ | |
travis \ | |
tree \ | |
watch \ | |
wget \ | |
xh \ | |
yq | |
mkcert -install | |
} | |
# Software | |
install_warez() { | |
log_info "Installing Software..." | |
brew install -f \ | |
dropbox \ | |
kindle \ | |
notion \ | |
signal \ | |
slack \ | |
vlc \ | |
wpsoffice | |
} | |
install_zsh_terminal() { | |
log_info "Installing ZSH Terminal..." | |
brew install -f \ | |
zsh \ | |
zsh-autosuggestions \ | |
zsh-completions \ | |
zsh-syntax-highlighting | |
# Install oh-my-zsh | |
sh -c "$(curl -fsSL "https://raw.github.com/ohmyzsh/ohmyzsh/master/tools/install.sh")" | |
local brew_prefix | |
brew_prefix=$(brew --prefix) | |
# Fix to the prompt of new terminal window. | |
# ${SUDO} chmod 0775 "${brew_prefix}/share" | |
cat >> ~/.zshrc <<-EOF | |
# Auto suggestion | |
source "${brew_prefix}/share/zsh-autosuggestions/zsh-autosuggestions.zsh" | |
# Auto completion | |
if type brew &>/dev/null; then | |
FPATH="${brew_prefix}/share/zsh-completions:\${FPATH}" | |
autoload -Uz compinit | |
compinit | |
fi | |
# Syntax highlighting | |
source "${brew_prefix}/share/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh" | |
EOF | |
# Switching terminal. | |
zsh | |
} | |
install_zsh_theme() { | |
log_info "Installing ZSH Theme..." | |
brew install -f \ | |
romkatv/powerlevel10k/powerlevel10k | |
local theme_name="powerlevel10k" \ | |
theme_path | |
theme_path=$(brew --prefix "${theme_name}") | |
# Randomizing the default theme. | |
sed -ie "s|ZSH_THEME=.*|ZSH_THEME=\"random\"|g" ~/.zshrc | |
# Import powerlevel10k theme. | |
cat >> ~/.zshrc <<-EOF | |
# Path to ${theme_name} theme | |
source "${theme_path}/${theme_name}.zsh-theme" | |
EOF | |
p10k configure | |
local theme_config_path="${HOME}/.p10k.zsh" | |
# Enabling some icons | |
sed -ie "s|.*# load # CPU load.*| load # CPU load|g" "${theme_config_path}" | |
sed -ie "s|.*# disk_usage # disk usage.*| disk_usage # disk usage|g" "${theme_config_path}" | |
sed -ie "s|.*# ram # free RAM.*| ram # free RAM|g" "${theme_config_path}" | |
sed -ie "s|.*# battery # internal battery.*| battery # internal battery|g" "${theme_config_path}" | |
# Disabling error prompt. | |
sed -ie "s|.*POWERLEVEL9K_INSTANT_PROMPT=.*|typeset -g POWERLEVEL9K_INSTANT_PROMPT=quiet|g" "${theme_config_path}" | |
# Changing date and time format. | |
sed -ie "s|.*POWERLEVEL9K_TIME_FORMAT=.*|typeset -g POWERLEVEL9K_TIME_FORMAT='%D{\\\UF133 %d %b %H:%M:%S%z}'|g" "${theme_config_path}" | |
source "${HOME}/.zshrc" | |
} | |
iterm2_fonts() { | |
log_info "Installing iTerm2 Fonts..." | |
local fonts_path="/tmp/fonts" | |
git clone "https://github.com/powerline/fonts.git" --depth=1 "${fonts_path}" | |
"${fonts_path}"/install.sh | |
rm -rf "${fonts_path}" | |
} | |
iterm2_colors() { | |
log_info "Installing iTerm2 Colors..." | |
local colors_path="/tmp/iTerm2-Color-Schemes" | |
git clone "[email protected]:mbadolato/iTerm2-Color-Schemes.git" --depth=1 "${colors_path}" | |
# Import all color schemes (verbose mode). | |
"${colors_path}"/tools/import-scheme.sh -v "${colors_path}/schemes/*" | |
rm -rf "${colors_path}" | |
} | |
validate_args() { | |
if [ -z "${NAME:-}" ]; then | |
log_err 'Missing -n {{NAME}}' | |
exit 1 | |
fi | |
if [ -z "${EMAIL:-}" ]; then | |
log_err 'Missing -e {{EMAIL}}' | |
exit 1 | |
fi | |
} | |
parse_args() { | |
local opts_string="e:n:h?x" | |
while getopts "${opts_string}" arg; do | |
case "${arg}" in | |
e) EMAIL="${OPTARG}" ;; | |
n) NAME="${OPTARG}" ;; | |
h | \?) usage "${0}" ;; | |
x) set -x ;; | |
esac | |
done | |
shift $((OPTIND - 1)) | |
} | |
# Computer wisdom | |
say_wisdom() { | |
log_info "Installing Say Wisdom..." | |
brew install -f \ | |
cowsay \ | |
fortune \ | |
lolcat | |
printf "\n# Computer wisdom\nfortune -s computers | cowsay -f dragon | lolcat" >> "$(get_profile)" | |
} | |
script_cleanup() { | |
brew cleanup | |
} | |
usage() { | |
local this="${1}" | |
cat <<EOF | |
${this}: install Mac software for the first time | |
Usage: ${this} [-e] email [-l] log level [-n] name | |
-e sets user email. | |
-h to get help about the usage. | |
-l sets the log priority: 2 => critical, 3 => error, 6 => info, 7 => debug. | |
-n sets the full name. | |
-x to see the executed statements. | |
EOF | |
exit 2 | |
} | |
main() { | |
validate_bash | |
check_sudo | |
trap 'script_cleanup; exit ${exit_status}' EXIT | |
parse_args "$@" | |
validate_args | |
log_info "Welcome ${NAME}<${EMAIL}>!" | |
prepare | |
configure_ssh | |
create_netrc | |
generate_ssh_keys | |
install_brew | |
install_browsers | |
install_dev_tools | |
install_docker | |
install_git "${NAME}" "${EMAIL}" | |
install_golang | |
install_go_tools | |
install_grpc | |
install_k8s | |
install_tools | |
install_warez | |
install_zsh_terminal | |
install_zsh_theme | |
iterm2_fonts | |
iterm2_colors | |
say_wisdom | |
} | |
main "$@" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment