Skip to content

Instantly share code, notes, and snippets.

@ajcwebdev
Last active April 13, 2024 05:43
Show Gist options
  • Save ajcwebdev/69872bc66c2a480aaeea51469d730c4f to your computer and use it in GitHub Desktop.
Save ajcwebdev/69872bc66c2a480aaeea51469d730c4f to your computer and use it in GitHub Desktop.
Useful Snippets for MacOS Ventura with Apple M1 Pro Chip

Outline

Introduction and Other Resources

If you are not on a machine with an Apple M1 Chip be aware that there will be a few extraneous steps and commands throughout this gist. But for the most part if you ignore those commands and leave them out then mostly everything else should be fairly agnostic to Apple M1, Apple x86, or Linux.

Unfortunately, if you're on Windows you'll be hard pressed to find a single section of this gist that isn't broken or incompatible. On the bright side, that means you can write your own Useful Snippets gist for Windows users and you'll save a couple million people a few billion headaches.

Other good resources:

Install Developer Applications

Configure CLI

Install Homebrew and Brew Packages

Install and Configure Homebrew

After running the install script, we'll run a handful of commands to create a .zprofile file which will set the Homebrew path with shellenv. I also turn off analytics with the final command but that is not a required step.

/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"  # Install Homebrew
(echo; echo 'eval "$(/opt/homebrew/bin/brew shellenv)"') >> $HOME/.zprofile                      # Create .zprofile shell startup file with command to setup a Homebrew environment
cat $HOME/.zprofile                                                                              # Display contents of .zprofile
eval "$(/opt/homebrew/bin/brew shellenv)"                                                        # Setup Homebrew environment in current terminal session
brew analytics off                                                                               # Turn off data collection for analytics
brew -v     # Check Homebrew version
brew -h     # Homebrew help command
brew config # Check Homebrew config
Install CLIs and Utility Packages with Homebrew
brew install deno ffmpeg gh httpstat pnpm railway tree webp yt-dlp jq

There are many ways to see what has been installed with Homebrew, here is a sequence of increasingly useful ways to do so:

ls /opt/homebrew/bin                          # List all binaries installed by Homebrew, too noisy to be useful
brew list --versions                          # List all installed Homebrew packages and their version number, better but still includes peer dependencies
brew deps --installed --direct                # List only the direct dependencies of the installed Homebrew packages
brew deps --tree --installed --direct         # List only the direct dependencies of the installed Homebrew packages but in a tree format this time
brew leaves | xargs -n1 brew desc --eval-all  # List top level brew packages and descriptions, the thing you actually want to know

Install Volta and Node Packages

Install Volta and Node
curl https://get.volta.sh -s | bash  # Install Volta
source .profile                      # Initialize Volta environment for current terminal session
volta install node@20                # Install Node 20
node -v                              # Verify correct version of Node has been installed

With Node v20, a server or script can be run without nodemon or dotenv.

node --env-file=.env --watch index.js
Install Node CLIs with Volta
volta install netlify-cli vercel wrangler yarn@1

List all tools installed with Volta:

volta list

Other ways to inspect your Volta/Node/npm packages and general locally installed binaries:

ls /$HOME/.volta/bin                  # List all JavaScript packages installed and managed with Volta by inspecting `.volta/bin`
npm list --location=global --depth 0  # When installing all global Node packages through Homebrew/Volta, listing globally installed npm packages contains only `corepack` and `npm`
ls /usr/local/*                       # View binaries installed locally through specific shell script files instead of Homebrew/VoltaList
tree /usr/local/ -L 2                 # List locally installed binaries a different way

Inspect your Volta configuration file:

cat $HOME/.volta/tools/user/platform.json

Since I installed a specific legacy version of yarn and opted not to use Volta's experimental pnpm support (see GitHub Issue #737), this outputs the following on my machine:

{"node":{"runtime":"20.12.0","npm":null},"pnpm":null,"yarn":"1.22.22"}

Authenticate CLIs

Authenticate CLIs for GitHub, Railway, Netlify, Vercel, and Wrangler.
# Run `gh status` or `gh help` for more info
gh auth login

# Run `ntl status` or `ntl help` for more info
ntl login

# Run `vercel whoami` or `vercel help` for more info
vercel login

# Run `railway whoami`, `railway status`, or `railway help` for more info
railway login   # or `railway login --browserless` for browserless login

# TODO: wrangler login

Configure Git

Set name, email, default branch, and automatic remote pushing.
git config --global init.defaultBranch main
git config --global user.name "FIRST_NAME LAST_NAME"
git config --global user.email "MY_NAME@example.com"
git config --global --add --bool push.autoSetupRemote true

These changes can be seen in your .gitconfig file.

[init]
	defaultBranch = main
[user]
	name = FIRST_NAME LAST_NAME
	email = MY_NAME@example.com
[push]
	autoSetupRemote = true

Common Workflows

Create and Push a Public GitHub Repo
mkdir github-cli-example
cd github-cli-example
echo '# GitHub CLI Example' >> README.md
git init
git add .
git commit -m "do the thing"
gh repo create github-cli-example \
  --public \
  --push \
  --source=. \
  --description="An example GitHub repo created and pushed to main with the GitHub CLI." \
  --remote=upstream
Deploy PostgreSQL Database with Railway
railway init -n example
railway add -p postgresql
railway open

Configure Aliases

Create aliases in .zshrc

Add the following lines of code to .zshrc:

alias ignore='echo ".DS_Store\nnode_modules\n.env\n.env.local" > .gitignore'
alias gs="git status"
alias gi="git init"
alias gc='git add . && git commit -m "commit"'
alias gp="git push"
alias t="tree -I node_modules -I whisper.cpp"
alias ls="ls -1"
alias ni='npm init -y && npm pkg set type="module"'
alias path='echo "$PATH" | tr ":" "\n" | nl'
  • ignore aliases to echo ".DS_Store\nnode_modules\n.env\n.env.local" > .gitignore for creating a custom .gitignore file that ignores .DS_Store for Mac users, node_modules for JavaScript projects, and .env/.env.local for sensitive API keys.
  • gi aliases to git init for initializing a Git repository
  • gs aliases to git status for checking the status of commits
  • gc aliases to git add . && git commit -m "commit" for automatically staging and committing changes (only use for solo projects where you do not wish to have meaningful commit messages to explain changes over time)
  • gp aliases to git push to push all new commits
  • t aliases to tree -I node_modules for printing a project's directory structure while ignoring any node_modules directories
  • ls aliases to ls -1 so files/directories displayed in the current working directory are listed one per line
  • ni aliases to a modification of npm init which runs npm pkg set type="module" to set type to module in package.json after initialization.
  • path aliases to echo "$PATH" | tr ":" "\n" | nl which displays an easily readable list of path variables instead of the single line of variables echo $0 outputs

Create Shell Functions

Current dotfiles (.zprofile, .zshrc, profile, and .gitconfig) are included at the bottom of the gist after the final DANGER section.

TODO: Better dotfile management.

DANGER - DO NOT RUN THESE UNLESS YOU KNOW WHAT YOU ARE DOING

Reset PATH to system default, uninstall/delete Homebrew/Volta and associated packages, and reset zsh dotfiles
# Reset PATH to default
export PATH=/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin

# Delete Volta and all installed packages
rm -rf $HOME/.volta

# Uninstall Homebrew
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/uninstall.sh)"

# If anything remains after uninstalling for some reason, you can delete the entire Homebrew directory
rm -rf /opt/homebrew

# Reset zsh dotfiles
rm -rf $HOME/.zprofile $HOME/.zshrc $HOME/.zsh_history $HOME/.zsh_sessions

Deprecated Setup Commands

Install Go and IPFS

No longer using Go or IPFS Kudo, migrating to Helia.

# Install Go
curl --remote-name https://dl.google.com/go/go1.20.4.darwin-arm64.pkg
sudo installer -pkg go1.20.4.darwin-arm64.pkg -target /
rm go1.20.4.darwin-arm64.pkg
go version # open new terminal and check go version
# Install IPFS Kudo
curl --remote-name https://dist.ipfs.tech/kubo/v0.16.0/kubo_v0.16.0_darwin-arm64.tar.gz
tar -xvzf kubo_v0.16.0_darwin-arm64.tar.gz
sudo bash kubo/install.sh
rm -rf kubo kubo_v0.16.0_darwin-arm64.tar.gz
ipfs --version # ipfs version 0.16.0
Install Rustup

Not installing right now cause Rust is cool but writing Rust is a lifestyle and I'm not ready for a long term commitment. And anyway, at this point shouldn't I just learn Zig instead?

curl https://sh.rustup.rs -sSf | sh  # Select 1) Proceed with installation (default)
source "$HOME/.cargo/env"
Install and Configure AWS CLI

No longer using AWS CLI cause YOLO.

curl --remote-name "https://awscli.amazonaws.com/AWSCLIV2.pkg" -s  # Download the AWS CLI installer
sudo installer -pkg AWSCLIV2.pkg -target /                         # Use the installer command to unzip the package
rm AWSCLIV2.pkg                                                    # Delete the installer package
aws configure                                                      # Configure AWS Access Key ID and Secret Access Key
aws --version                                                      # Check AWS CLI version
[init]
defaultBranch = main
[user]
name = Anthony Campolo
email = 12433465+ajcwebdev@users.noreply.github.com
[push]
autoSetupRemote = true
export VOLTA_HOME="$HOME/.volta"
export PATH="$VOLTA_HOME/bin:$PATH"
eval "$(/opt/homebrew/bin/brew shellenv)"
alias a="cd ajc && code ."
alias b="cd blog && code ."
alias ca="gh repo clone ajcwebdev/ajc && cd ajc && npm i && code ."
alias cb="gh repo clone ajcwebdev/blog && cd blog && code ."
alias ignore='echo ".DS_Store\nnode_modules\n.env\n.env.local" > .gitignore'
alias gs="git status"
alias gi="git init"
alias gc='git add . && git commit -m "commit"'
alias gp="git push"
alias t="tree -I node_modules -I whisper.cpp"
alias ls="ls -1"
alias ni='npm init -y && npm pkg set type="module"'
alias path='echo "$PATH" | tr ":" "\n" | nl'
# Define a Bash function named 'webp' to convert input image files to WebP format
#
# - Iterate through all input file arguments passed to the function
# - Extract base file name (without extension) from the input file
# - Convert input image file to WebP format with cwebp command
# - Set quality level to 80 and save output WebP file with same base name as input file
#
# Example command:
#
# curl "https://avatars.githubusercontent.com/u/12433465" > avatar.jpeg && webp avatar.jpeg
function webp() {
for file in "$@"; do
base=$(basename "$file" | cut -d. -f1)
cwebp -q 70 "$file" -o "$base.webp"
done
}
function resize() {
local directory=$1
local new_width=640
local new_height=336
# Check if the directory argument was provided
if [[ -z "$directory" ]]; then
echo "Please provide a directory."
return 1
fi
# Loop through each .webp file in the directory
for file in "$directory"/*.webp; do
# Construct the new filename by replacing the old dimensions with the new ones
local new_file=$(echo $file | sed "s/1600-840/$new_width-$new_height/" | sed "s/1600x840/$new_width-$new_height/")
# Use cwebp to resize the image and save it with the new filename
cwebp "$file" -o "$new_file" -resize $new_width 0
done
}
# Creates 'files.txt' file containing a list of filenames saved in a repo's Git history along with their file sizes
# Print a string "bfg " so the output will be fed into the next function which cleans large Git objects from its history
# Run a series of Git commands to generate the list of filenames and sizes
# Use 'sed' to process the output of the previous 'git' command
# Extract the hash values from the 'git' command output
# Use 'git cat-file --batch-check' to obtain information about Git objects
# Filter the objects to include only those of type 'blob' (file content)
# Sort the objects by size in ascending order
# Select the last 150 objects in the sorted list
# Use a 'while' loop to read each line (hash, type, size) and generate a 'sed' command
# Sort the 'sed' commands by size in ascending order
# Use 'awk' to extract the filenames from the sorted 'sed' commands
function rev() {
printf "bfg "
git rev-list --all --objects | \
sed -n $(git rev-list --objects --all | \
cut -f1 -d' ' | \
git cat-file --batch-check | \
grep blob | \
sort -n -k 3 | \
tail -n150 | \
while read hash type size; do echo -n "-e s/$hash/$size/p "; done) | \
sort -n -k2 | \
awk -F' ' '{sub(".*/", "", $NF); printf "%s ", $NF}'
} > files.txt
# Install and configure Java: brew install java
# sudo ln -sfn /opt/homebrew/opt/openjdk/libexec/openjdk.jdk /Library/Java/JavaVirtualMachines/openjdk.jdk
# Define a Bash function that runs the BFG Repo-Cleaner tool on one or more files
function bfg() {
if [ "$#" -eq 0 ]; then
echo "No files provided. Please provide a list of files to run the command on."
return 1
fi
for file in "$@"; do
java -jar /Library/Java/Extensions/bfg-1.14.0.jar \
--delete-files "$file"
done
}
# bun completions
[ -s "/Users/ajc/.bun/_bun" ] && source "/Users/ajc/.bun/_bun"
# bun
export BUN_INSTALL="$HOME/.bun"
export PATH="$BUN_INSTALL/bin:$PATH"
# >>> conda initialize >>>
# !! Contents within this block are managed by 'conda init' !!
__conda_setup="$('/Users/ajc/miniconda3/bin/conda' 'shell.zsh' 'hook' 2> /dev/null)"
if [ $? -eq 0 ]; then
eval "$__conda_setup"
else
if [ -f "/Users/ajc/miniconda3/etc/profile.d/conda.sh" ]; then
. "/Users/ajc/miniconda3/etc/profile.d/conda.sh"
else
export PATH="/Users/ajc/miniconda3/bin:$PATH"
fi
fi
unset __conda_setup
# <<< conda initialize <<<
@miwgel
Copy link

miwgel commented Apr 28, 2023

Very cool, thank you for sharing

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment