Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .goreleaser.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ builds:
- CGO_ENABLED=0
goos:
- darwin
- linux
goarch:
- amd64
- arm64
Expand All @@ -38,6 +39,7 @@ builds:
- CGO_ENABLED=0
goos:
- darwin
- linux
goarch:
- amd64
- arm64
Expand Down Expand Up @@ -68,7 +70,7 @@ builds:
archives:
# Combined tarball for Homebrew
- id: cache-cleaner
name_template: "cache-cleaner-{{ .Version }}-darwin-{{ .Arch }}"
name_template: "cache-cleaner-{{ .Version }}-{{ .Os }}-{{ .Arch }}"
files:
- none* # Only include binaries, no extra files

Copy link

Copilot AI Mar 1, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

install.sh now downloads per-app assets named ${APP_NAME}-${OS}-${ARCH} (e.g. dev-cache-linux-amd64), but in this GoReleaser config I only see a combined archive artifact (cache-cleaner-{{ .Version }}-{{ .Os }}-{{ .Arch }}) being defined. Unless there is another (missing) artifact configuration, the Linux installer URLs will 404. Consider either (a) adding GoReleaser artifacts that publish per-app binaries with the ${app}-${os}-${arch} naming for linux as well, or (b) updating install.sh to download the cache-cleaner-* archive and extract the requested binaries.

Suggested change
# Per-app Linux binaries for install.sh (${APP_NAME}-${OS}-${ARCH})
- id: per-app-linux-binaries
format: binary
builds:
- dev-cache
- git-cleaner
goos:
- linux
name_template: "{{ .Binary }}-{{ .Os }}-{{ .Arch }}"

Copilot uses AI. Check for mistakes.
Expand Down
15 changes: 10 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,9 @@ This installs all 3 apps: `dev-cache`, `git-cleaner`, and `mac-cache-cleaner`.
If you don't have Homebrew, you can use the install script:

```bash
# Install all 3 apps to ~/.local/bin
# Install all available apps for your OS to ~/.local/bin
# - macOS: dev-cache, git-cleaner, mac-cache-cleaner
# - Linux: dev-cache, git-cleaner
curl -sSfL https://raw.githubusercontent.com/markcallen/cache-cleaner/HEAD/install.sh | sh -s -- -b $HOME/.local/bin

# Install specific app only
Expand All @@ -53,10 +55,12 @@ Add this to your shell profile (`~/.zshrc` or `~/.bashrc`) to make it permanent.

#### install.sh behavior

- The script installs from the latest GitHub release archives.
- The script downloads the latest GitHub release binaries from `releases/download` assets.
- `-b <dir>` is mandatory and determines where binaries are written.
- Use `-a <app>` to install a single binary (`dev-cache`, `git-cleaner`, or `mac-cache-cleaner`); omit `-a` to install all three.
- The script exits early with an error (without partial installs) if required flags or tools are missing.
- Supported OS values are `darwin` and `linux`.
- Use `-a <app>` to install a single binary (`dev-cache`, `git-cleaner`, or `mac-cache-cleaner`).
- On Linux, default install includes `dev-cache` and `git-cleaner`; `mac-cache-cleaner` is macOS-only.
- The script exits early with an error if required flags or tools are missing; when installing multiple apps, a failure part-way through may leave earlier apps installed.

## Quick Start

Expand Down Expand Up @@ -179,7 +183,8 @@ git push origin v1.0.0

1. GitHub Actions will trigger the release workflow
2. GoReleaser will:
- Build all 3 binaries for darwin/amd64 and darwin/arm64
- Build `dev-cache` and `git-cleaner` for darwin+linux (amd64 and arm64)
- Build `mac-cache-cleaner` for darwin (amd64 and arm64)
- Create a GitHub release with binaries attached
- Generate a Homebrew cask
- Push the formula to `homebrew-cache-cleaner` repository
Expand Down
81 changes: 47 additions & 34 deletions install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ REPO_OWNER="markcallen"
REPO_NAME="cache-cleaner"

# Available apps
APPS="dev-cache git-cleaner mac-cache-cleaner"
ALL_APPS="dev-cache git-cleaner mac-cache-cleaner"
APPS="$ALL_APPS"

usage() {
cat <<EOF
Expand All @@ -22,13 +23,13 @@ Usage:
Options:
-b <bin_dir> Install destination directory (REQUIRED)
-a <app> Install specific app only: dev-cache, git-cleaner, or mac-cache-cleaner
(default: install all 3 apps)
(default: all available apps for this OS)

Arguments:
<version> Version tag to install (e.g., v1.2.3). Default: latest release

Examples:
# Install all 3 apps (latest) to ~/.local/bin
# Install all available apps (latest) to ~/.local/bin
curl -sSfL https://raw.githubusercontent.com/${REPO_OWNER}/${REPO_NAME}/HEAD/install.sh | sh -s -- -b \$HOME/.local/bin

# Install only mac-cache-cleaner
Expand Down Expand Up @@ -59,19 +60,32 @@ while [ $# -gt 0 ]; do
shift
done

# Determine OS/ARCH
OS="$(uname -s | tr '[:upper:]' '[:lower:]')"
case "$OS" in
darwin)
APPS="$ALL_APPS"
;;
linux)
APPS="dev-cache git-cleaner"
;;
*)
error "unsupported OS: $OS (supported: darwin, linux)"
;;
esac

# Validate app filter if provided
if [ -n "$APP_FILTER" ]; then
case "$APP_FILTER" in
dev-cache|git-cleaner|mac-cache-cleaner) : ;;
*) error "invalid app: $APP_FILTER (must be one of: dev-cache, git-cleaner, mac-cache-cleaner)" ;;
esac
if [ "$OS" = "linux" ] && [ "$APP_FILTER" = "mac-cache-cleaner" ]; then
error "mac-cache-cleaner is only available on macOS"
fi
APPS="$APP_FILTER"
fi

# Determine OS/ARCH
OS="$(uname -s | tr '[:upper:]' '[:lower:]')"
[ "$OS" = "darwin" ] || error "only macOS (darwin) is supported"

UNAME_M="$(uname -m)"
case "$UNAME_M" in
x86_64) ARCH=amd64 ;;
Expand Down Expand Up @@ -133,43 +147,42 @@ case "$VERSION" in
*) error "version must be a semver tag like v1.2.3" ;;
esac

# Require tools
command -v curl >/dev/null 2>&1 || error "curl is required"
command -v tar >/dev/null 2>&1 || error "tar is required"

# Cleanup function for temp files
cleanup() {
if [ -n "${TMPFILE:-}" ] && [ -f "$TMPFILE" ]; then
rm -f "$TMPFILE"
if [ -n "${TMPDIR:-}" ] && [ -d "$TMPDIR" ]; then
rm -rf "$TMPDIR"
fi
}
trap cleanup EXIT INT HUP TERM

# Install each app
for APP_NAME in $APPS; do
ASSET_NAME="${APP_NAME}-darwin-${ARCH}"
DOWNLOAD_URL="https://github.com/${REPO_OWNER}/${REPO_NAME}/releases/download/${VERSION}/${ASSET_NAME}"
VERSION_NO_V="$(printf "%s" "$VERSION" | sed 's/^v//')"
ARCHIVE_NAME="cache-cleaner-${VERSION_NO_V}-${OS}-${ARCH}.tar.gz"
DOWNLOAD_URL="https://github.com/${REPO_OWNER}/${REPO_NAME}/releases/download/${VERSION}/${ARCHIVE_NAME}"

TMPFILE="$(mktemp -t ${APP_NAME}.XXXXXX)"
TMPDIR="$(mktemp -d -t cache-cleaner.XXXXXX)"
ARCHIVE_PATH="${TMPDIR}/${ARCHIVE_NAME}"
STAGE_DIR="${TMPDIR}/stage"
mkdir -p "$STAGE_DIR"

printf "Installing %s %s for %s/%s to %s\n" "$APP_NAME" "$VERSION" "$OS" "$ARCH" "$BIN_DIR"
printf "Downloading %s for %s/%s\n" "$ARCHIVE_NAME" "$OS" "$ARCH"
curl -fL "${DOWNLOAD_URL}" -o "$ARCHIVE_PATH" || error "download failed: ${DOWNLOAD_URL}"

curl -fL "${DOWNLOAD_URL}" -o "$TMPFILE" || error "download failed: ${DOWNLOAD_URL}"

chmod 0755 "$TMPFILE"
mkdir -p "$BIN_DIR"
DEST="$BIN_DIR/${APP_NAME}"

if mv "$TMPFILE" "$DEST" 2>/dev/null; then
# Successfully moved, clear TMPFILE so cleanup doesn't try to remove it
TMPFILE=""
else
# Try install to handle cross-filesystem permissions
if install -m 0755 "$TMPFILE" "$DEST" 2>/dev/null; then
# Successfully installed, remove temp file since install copies it
rm -f "$TMPFILE"
TMPFILE=""
else
error "failed to install to $DEST (try with sudo or set -b)"
fi
fi
tar -xzf "$ARCHIVE_PATH" -C "$STAGE_DIR" || error "failed to extract ${ARCHIVE_NAME}"

mkdir -p "$BIN_DIR"
for APP_NAME in $APPS; do
SRC="${STAGE_DIR}/${APP_NAME}"
DEST="${BIN_DIR}/${APP_NAME}"
[ -f "$SRC" ] || error "release archive missing binary: ${APP_NAME}"
chmod 0755 "$SRC"
printf "Installing %s %s for %s/%s to %s\n" "$APP_NAME" "$VERSION" "$OS" "$ARCH" "$BIN_DIR"
if ! install -m 0755 "$SRC" "$DEST" 2>/dev/null; then
error "failed to install to $DEST (try with sudo or set -b)"
fi
printf "Installed: %s\n" "$DEST"
"$DEST" --version >/dev/null 2>&1 || true
done