Skip to content

Commit

Permalink
feat: Fix bootstrap script and general improvements (#45)
Browse files Browse the repository at this point in the history
- proper bootstrap script
- rename setup.sh to run.sh and clean up
- remove need for sudo in local.sh
- move computer rename to macos.sh
- create dotsync.sh
- disable auto-run for macos.sh (needs fixing)
- update readme and license
- general cleanup

## Summary by Sourcery

Revamp the bootstrap process by introducing a new 'dotsync.sh' script
for dotfile management, renaming 'setup.sh' to 'run.sh', and removing
'sudo' requirements from 'local.sh'. Update the README and LICENSE to
reflect these changes and improve script idempotency and security by
integrating 1Password for secret management.

New Features:
- Introduce a new script 'dotsync.sh' for managing dotfiles linking and
unlinking.

Enhancements:
- Rename 'setup.sh' to 'run.sh' and streamline its functionality.
- Remove the need for 'sudo' in 'local.sh' to enhance security and
usability.
- Move computer renaming functionality from 'local.sh' to 'macos.sh'.
- Make scripts idempotent, allowing them to be run multiple times
without issues.
- Add support for 1Password to manage secrets used by scripts.

Documentation:
- Update README.md to reflect changes in script names and usage
instructions.
- Revise LICENSE.md to update copyright years.

---------

Co-authored-by: sourcery-ai[bot] <58596630+sourcery-ai[bot]@users.noreply.github.com>
  • Loading branch information
martimlobao and sourcery-ai[bot] authored Nov 5, 2024
1 parent ed3368c commit cc8340c
Show file tree
Hide file tree
Showing 10 changed files with 239 additions and 216 deletions.
5 changes: 2 additions & 3 deletions LICENSE.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
MIT License
# MIT License

Copyright (c) 2018-2021 Martim Lobao <https://martimlobao.com>
Copyright (c) 2013-2018 Mathias Bynens <https://mathiasbynens.be>
Copyright (c) 2018-2024 Martim Lobao <https://martimlobao.com>

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
88 changes: 27 additions & 61 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,83 +2,49 @@

![Screenshot of my shell prompt](static/screenshot.png)

This repository contains my personal dotfiles, as well as several scripts to install applications and configure settings. Although the bash configuration settings should (mostly) work on any Unix-based system, most of these scripts were only designed to run on macOS and likely won't run at all on any other OS.
This repository contains my personal dotfiles, as well as several scripts to install applications and configure settings. Although the shell configuration settings should (mostly) work on any Unix-based system, most of these scripts were only designed to run on macOS and likely won't run at all on any other OS.

Here's a short description of each script in this repository:

- `local.sh` _interactively_ configure local settings unique to each machine, like the computer name and your git user details
- `macos.sh` configure several macOS settings
- `brew.sh` install command-line tools using Homebrew
- `apps.sh` install fonts and macOS apps using Homebrew and Mac App Store
- `install.sh` install fonts, tools, and apps using Homebrew, [`uv`](https://docs.astral.sh/uv/), and the Mac App Store
- `dock.sh` configure macOS dock
- `bootstrap.sh` install dotfiles for bash settings and command line layout
- `setup.sh` install Homebrew, run all scripts, and install private dotfiles from private repository
- `bootstrap.sh` bootstrap install everything, including cloning this repository
- `run.sh` install Homebrew and run all scripts

**Attention:** Running these dotfiles blindly will overwrite settings and install apps and fonts that you probably don't need. Some care was taken to not overwrite non-transferable settings (e.g. [git user settings](https://github.com/martimlobao/dotfiles/blob/master/local.sh)), but unless your preferences are identical to mine, you should [fork this repository](https://github.com/martimlobao/dotfiles/fork), review the code, and remove things you don't want or need. Use at your own risk!
All these scripts are idempotent, meaning they can be run multiple times without issue.

## Installation

**Note:** If you fork this repository to create your own dotfiles, replace `https://git.io/dotinstall` with `https://github.com/<USER>/<REPO>/tarball/master` in the commands below.

### Fresh install

To download these dotfiles on a new Mac (without git):

```bash
curl -L https://git.io/dotinstall | tar -xz
```
**Attention:** Running these dotfiles blindly will overwrite settings and install apps and fonts that you probably don't need. Use at your own risk!

Then, open the downloaded folder and run `setup.sh`, `bootstrap.sh`, or any other script:

```bash
cd martim*
./local.sh
```

### One-line everything install

To run everything in a single command:

```bash
curl -L https://git.io/dotinstall | tar -xz; cd martim*; ./setup.sh
```

**Warning:** This will overwrite settings, any existing dotfiles in your home directory, and install apps and fonts. Don't run this unless you're me or you have my exact preferences!

### One-line dotfiles install

To _only_ install dotfiles without needing to install git or run any scripts:

```bash
cd; curl -L https://git.io/dotinstall | tar -xzv --strip-components 1 --exclude={*.sh,*.md}
```

**Warning:** This will overwrite any existing dotfiles in your home directory.

### Terminal-free install!

Go to [git.io/dotinstall](https://git.io/dotinstall) and open the downloaded file, then double-click on a script to run it.

## Usage
## Installation

Most of these scripts rely on [Homebrew](https://brew.sh/), which is installed when running `setup.sh`. However, if you don't want to install everything in this repository, you can choose to install Homebrew by itself and pick and choose what you like:
On a fresh (or not so fresh) macOS install, run the following command to install Homebrew and run all scripts:

```bash
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
curl -L http://dot.lobao.io | bash
```

## Contributing
### 1Password requirements

[Pull requests](https://github.com/martimlobao/dotfiles/pulls) are welcome. For non-minor changes, consider [opening an issue](https://github.com/martimlobao/dotfiles/issues) first to discuss what you would like to change.
1Password is required to store secrets used by these scripts. These include:

Note that these are my personal dotfiles, so if you'd like to customize them to your own taste, it might make more sense to [fork this repository](https://github.com/martimlobao/dotfiles/fork) instead.
- `op user get --me` to set your git `user.name`
- `op://Private/GitHub/email` and `op://Private/GitHub/username` to configure git and push to Github
- `op://Private/GitHub SSH Commit Signing Key/public key` to configure SSH commit signing
- `op://Private/iStat Menus 6/registered email` and `op://Private/iStat Menus 6/license key` to register iStat Menus 6
- `op://Private/Charles/registered name` and `op://Private/Charles/license key` to register Charles
- SSH keys for AWS

## Thanks

- [@mathiasbyens](https://mathiasbynens.be/) for his [dotfiles repository](https://github.com/mathiasbynens/dotfiles), off of which this repository was initially based
- [@ikuwow](https://github.com/ikuwow) for his [dotfiles](https://github.com/ikuwow/dotfiles)
- [@kennethreitz](https://www.kennethreitz.org/) for a few [functions and inspiration](https://github.com/kennethreitz/dotfiles)
- [@kevinsuttle](https://kevinsuttle.com/) for a great compilation of [macOS defaults](https://github.com/kevinSuttle/macOS-Defaults)
- [@ryanpavlick](https://github.com/rpavlick) for his [macOS dock customization functions](https://github.com/rpavlick/add_to_dock)
- [@br3ndonland](https://github.com/br3ndonland) for his [dotfiles](https://github.com/br3ndonland/dotfiles)
- [@pablopunk](https://github.com/pablopunk) for his [dotfiles](https://github.com/pablopunk/dotfiles)
Several people and repositories have contributed to or been a source of inspiration for this repository:

- [@mathiasbyens](https://mathiasbynens.be/)/[dotfiles](https://github.com/mathiasbynens/dotfiles), off of which this repository was initially based
- [@kevinsuttle](https://kevinsuttle.com/)/[macOS-Defaults](https://github.com/kevinSuttle/macOS-Defaults)
- [@ryanpavlick](https://github.com/rpavlick)/[add_to_dock](https://github.com/rpavlick/add_to_dock)
- [@ikuwow](https://github.com/ikuwow)/[dotfiles](https://github.com/ikuwow/dotfiles)
- [@kennethreitz](https://www.kennethreitz.org/)/[dotfiles](https://github.com/kennethreitz/dotfiles)
- [@br3ndonland](https://github.com/br3ndonland)/[dotfiles](https://github.com/br3ndonland/dotfiles)
- [@pablopunk](https://github.com/pablopunk)/[dotfiles](https://github.com/pablopunk/dotfiles)
- [@demophoon](https://github.com/demophoon)/[dotfiles](https://github.com/demophoon/dotfiles)
55 changes: 23 additions & 32 deletions bootstrap.sh
Original file line number Diff line number Diff line change
@@ -1,35 +1,26 @@
#!/usr/bin/env bash

# Source the bash_traceback.sh file
source "$(dirname "$0")/bash_traceback.sh"

###############################################################################
# UPDATE DOTFILES #
###############################################################################

cd "$(dirname "${BASH_SOURCE:-$0}")" || exit 1;

function dotlink() {
find "linkme" -type d -mindepth 1 | sed "s|^linkme/||" | while read -r dir; do mkdir -p "$HOME/$dir"; done
find "linkme" -type f -not -name '.DS_Store' | sed "s|^linkme/||" | while read -r file; do ln -fvns "$(pwd)/linkme/$file" "$HOME/$file"; done
}

function dotunlink() {
rsync -av --exclude='.DS_Store' linkme/ "$HOME" | \
grep -v "building file list ... done" | \
awk '/^$/ { exit } !/\/$/ { print "Restored " $0 }'
}

if [ "$1" == "unlink" ]; then
dotunlink;
elif [ "$1" == "--force" ] || [ "$1" == "-f" ]; then
dotlink;
{ # Prevent script from running if partially downloaded

set -euo pipefail

DOTPATH=$HOME/.dotfiles

echo -e "\033[1;34mπŸ₯Ύ Bootstrapping dotfiles\033[0m"

if [ ! -d "$DOTPATH" ]; then
git clone https://github.com/martimlobao/dotfiles.git "$DOTPATH"
echo -e "\033[1;32mβœ… Cloned $DOTPATH\033[0m"
else
read -rp $'❓ \e[1;31mThis may overwrite existing files in your home directory. Are you sure? (y/n)\e[0m ' REPLY
if [[ $REPLY =~ ^[Yy]$ ]]; then
dotlink;
fi;
fi;

# shellcheck source=/dev/null
source "$HOME"/.zprofile
echo -e "\033[1;34mβœ… Dotfiles already downloaded to $DOTPATH\033[0m"
fi

cd "$DOTPATH"

if [[ "${1:-}" == "--yes" ]] || [[ "${1:-}" == "-y" ]]; then
./run.sh -y
else
./run.sh
fi

} # Prevent script from running if partially downloaded
11 changes: 7 additions & 4 deletions dock.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ source "$(dirname "$0")/bash_traceback.sh"
###############################################################################
# FUNCTIONS FOR MANIPULATING MACOS DOCK #
###############################################################################

echo -e "πŸ”§ \033[1;34mConfiguring macOS Dock...\033[0m"

function add_app_to_dock {
# adds an application to macOS Dock
# usage: add_app_to_dock "Application Name"
Expand All @@ -15,9 +18,9 @@ function add_app_to_dock {
app_path=$(${launchservices_path} -dump | grep -o "/.*${app_name}.app" | grep -v -E "Backups|Caches|TimeMachine|Temporary|/Volumes/${app_name}" | uniq | sort | head -n1)
if open -Ra "${app_path}"; then
defaults write com.apple.dock persistent-apps -array-add "<dict><key>tile-data</key><dict><key>file-data</key><dict><key>_CFURLString</key><string>${app_path}</string><key>_CFURLStringType</key><integer>0</integer></dict></dict></dict>"
echo "$app_path added to the Dock."
echo -e "βœ… \033[1;32m$app_path added to the Dock.\033[0m"
else
echo "ERROR: $1 not found." 1>&2
echo -e "❌ \033[1;31mError: $1 not found.\033[0m" 1>&2
fi
}

Expand Down Expand Up @@ -80,9 +83,9 @@ function add_folder_to_dock {
</dict>
<key>tile-type</key> <string>directory-tile</string>
</dict>"
echo "$folder_path added to the Dock."
echo -e "βœ… \033[1;32m$folder_path added to the Dock.\033[0m"
else
echo "ERROR: $folder_path not found." 1>&2
echo -e "❌ \033[1;31mError: $folder_path not found.\033[0m" 1>&2
fi
}

Expand Down
47 changes: 47 additions & 0 deletions dotsync.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#!/usr/bin/env bash

# Source the bash_traceback.sh file
source "$(dirname "$0")/bash_traceback.sh"

###############################################################################
# UPDATE DOTFILES #
###############################################################################

# echo -e "\033[1;34mπŸ”— Installing dotfiles...\033[0m"
# sleep 1

function dotlink() {
find "linkme" -type d -mindepth 1 | sed "s|^linkme/||" | \
while read -r dir; do mkdir -p "$HOME/$dir"; done
find "linkme" -type f -not -name '.DS_Store' | sed "s|^linkme/||" | \
while read -r file; do
echo -e "\033[1;32mπŸ”— Linked $(pwd)/linkme/$file -> $HOME/$file\033[0m"
ln -fvns "$(pwd)/linkme/$file" "$HOME/$file" &> /dev/null;
done
}

function dotunlink() {
rsync -av --exclude='.DS_Store' linkme/ "$HOME" | \
grep -v "building file list ... done" | \
awk '/^$/ { exit } !/\/$/ { printf "\033[1;32mπŸ”™ Restored %s\033[0m\n", $0; }'
}

# Copy all files from copyme/ to $HOME
if [ "${1:-}" == "unlink" ]; then
echo -e "\033[1;34mπŸ“‹ Restoring dotfiles...\033[0m"
dotunlink;
else
echo -e "\033[1;34mπŸ”— Linking dotfiles...\033[0m"
if [[ "${1:-}" != "-y" ]] && [[ "${1:-}" != "--yes" ]]; then
read -rp $'❓ \e[1;31mOverwrite existing dotfiles with symlinks to stored dotfiles? (y/n)\e[0m ' LINK
else
LINK="y"
fi

if [[ $LINK =~ ^[Yy]$ ]]; then
dotlink;
fi
fi

# shellcheck source=/dev/null
source "$HOME"/.zprofile
36 changes: 23 additions & 13 deletions install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,13 @@ source "$(dirname "$0")/bash_traceback.sh"
# INSTALL APPS AND PACKAGES #
###############################################################################

echo -e "πŸ“² \033[1;36mInstalling apps and packages...\033[0m"
echo -e "πŸ“² \033[1;34mInstalling apps and packages...\033[0m"

# Check if the first argument is -y or --yes
auto_yes=false
if [[ "${1:-}" == "-y" ]] || [[ "${1:-}" == "--yes" ]]; then
auto_yes=true
fi

# Ensure yq is installed to parse the apps.toml file
if ! command -v yq &> /dev/null; then
Expand Down Expand Up @@ -115,7 +121,11 @@ brew_sync() {
echo "$missing_formulae" | sed 's/^/ /'
# shellcheck disable=SC2001
echo "$missing_casks" | sed 's/^/ /'
read -rp $'❓ \e[1;31mDo you want to uninstall these apps? (y/n)\e[0m ' choice
if [[ "$auto_yes" == false ]]; then
read -rp $'❓ \e[1;31mDo you want to uninstall these apps? (y/n)\e[0m ' choice
else
choice="y"
fi
if [[ "$choice" == "y" ]]; then
for app in $missing_apps; do
brew uninstall "$app"
Expand All @@ -140,7 +150,11 @@ uv_sync() {
echo -e "❗️ \033[1;31mThe following uv-installed apps are missing from apps.toml:\033[0m"
# shellcheck disable=SC2001
echo "$missing_uv_apps" | sed 's/^/ /'
read -rp $'❓ \e[1;31mDo you want to uninstall these apps? (y/n)\e[0m ' choice
if [[ "$auto_yes" == false ]]; then
read -rp $'❓ \e[1;31mDo you want to uninstall these apps? (y/n)\e[0m ' choice
else
choice="y"
fi
if [[ "$choice" == "y" ]]; then
for app in $missing_uv_apps; do
uv tool uninstall "$app"
Expand Down Expand Up @@ -175,11 +189,14 @@ mas_sync() {
for id in "${!missing_mas_apps[@]}"; do
echo -e " ${missing_mas_apps[$id]} ($id)"
done
read -rp $'❓ \e[1;31mDo you want to uninstall these apps? (y/n)\e[0m ' choice
if [[ "$auto_yes" == false ]]; then
read -rp $'❓ \e[1;31mDo you want to uninstall these apps? (y/n)\e[0m ' choice
else
choice="y"
fi
if [[ "$choice" == "y" ]]; then
for id in "${!missing_mas_apps[@]}"; do
name="${missing_mas_apps[$id]}"
# mas uninstall doesn't actually work so fall back to telling user to uninstall manually
if ! mas uninstall "$id"; then
echo -e "❌ \033[1;31mFailed to uninstall $name ($id). Please uninstall it manually.\033[0m"
else
Expand Down Expand Up @@ -222,14 +239,7 @@ echo -e "\nπŸ”Ό \033[1;35mUpdating existing apps and packages...\033[0m"
brew update
brew upgrade
uv tool upgrade --all
if mas outdated | grep -q .; then
echo -e "❗️ \033[1;31mThe following Mac App Store apps are outdated:\033[0m"
mas outdated
read -rp $'❓ \e[1;31mUpdate Mac App Store apps (may be slightly buggy)? (y/n)\e[0m ' choice
if [[ "$choice" == "y" ]]; then
mas upgrade
fi
fi
mas upgrade

# Remove outdated versions from the cellar
brew cleanup
Loading

0 comments on commit cc8340c

Please sign in to comment.