192 lines
7.3 KiB
Bash
Executable File
192 lines
7.3 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# rename.sh — rename this template to your actual project.
|
|
#
|
|
# Usage:
|
|
# ./rename.sh # interactive prompts
|
|
# ./rename.sh acme-corp my-svc # non-interactive (org, project)
|
|
#
|
|
# What it changes:
|
|
# go.mod module path
|
|
# **/*.go import paths
|
|
# .mockery.yaml package path
|
|
# config/dev.yaml app.name
|
|
# .devcontainer/devcontainer.json name field
|
|
# README.md heading + module path references
|
|
# CLAUDE.md Module line
|
|
|
|
set -euo pipefail
|
|
|
|
# ── Colour helpers ────────────────────────────────────────────────────────────
|
|
RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'
|
|
BOLD='\033[1m'; RESET='\033[0m'
|
|
|
|
info() { echo -e "${GREEN}✓${RESET} $*"; }
|
|
warn() { echo -e "${YELLOW}!${RESET} $*"; }
|
|
error() { echo -e "${RED}✗${RESET} $*" >&2; }
|
|
heading() { echo -e "\n${BOLD}$*${RESET}"; }
|
|
|
|
# ── Default Git host ──────────────────────────────────────────────────────────
|
|
# Change this if you ever migrate to a different server.
|
|
DEFAULT_HOST="gitea.djmil.dev"
|
|
|
|
# ── Validation ────────────────────────────────────────────────────────────────
|
|
validate_slug() {
|
|
local val="$1" label="$2"
|
|
if [[ -z "$val" ]]; then
|
|
error "$label cannot be empty."
|
|
return 1
|
|
fi
|
|
if [[ ! "$val" =~ ^[a-z0-9]([a-z0-9._-]*[a-z0-9])?$ ]]; then
|
|
error "$label must be lowercase alphanumeric (hyphens/dots/underscores allowed, no leading/trailing)."
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
# ── Convert kebab-case / snake_case to Title Case ─────────────────────────────
|
|
to_title() {
|
|
echo "$1" | sed -E 's/[-_]/ /g' | awk '{for(i=1;i<=NF;i++) $i=toupper(substr($i,1,1)) substr($i,2)} 1'
|
|
}
|
|
|
|
# ── Determine script's own directory (works with symlinks) ───────────────────
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
cd "$SCRIPT_DIR"
|
|
|
|
# ── Check we're in the right repo ────────────────────────────────────────────
|
|
if [[ ! -f go.mod ]]; then
|
|
error "go.mod not found. Run this script from the project root."
|
|
exit 1
|
|
fi
|
|
|
|
CURRENT_MODULE=$(grep '^module ' go.mod | awk '{print $2}')
|
|
TEMPLATE_MODULE="${DEFAULT_HOST}/djmil/go-template"
|
|
|
|
if [[ "$CURRENT_MODULE" != "$TEMPLATE_MODULE" ]]; then
|
|
warn "Module is already '$CURRENT_MODULE' (not the default template value)."
|
|
warn "Continuing will replace '$CURRENT_MODULE' with your new path."
|
|
echo
|
|
fi
|
|
|
|
# ── Gather inputs ─────────────────────────────────────────────────────────────
|
|
heading "Go Template — Project Renamer"
|
|
echo "This script rewrites the module path and project name throughout the codebase."
|
|
echo
|
|
|
|
if [[ $# -ge 2 ]]; then
|
|
NEW_ORG="$1"
|
|
NEW_PROJECT="$2"
|
|
else
|
|
while true; do
|
|
read -rp "Org / username (e.g. djmil): " NEW_ORG
|
|
validate_slug "$NEW_ORG" "Org/username" && break
|
|
done
|
|
while true; do
|
|
read -rp "Project name (e.g. my-service): " NEW_PROJECT
|
|
validate_slug "$NEW_PROJECT" "Project name" && break
|
|
done
|
|
fi
|
|
|
|
validate_slug "$NEW_ORG" "Org/username"
|
|
validate_slug "$NEW_PROJECT" "Project name"
|
|
|
|
NEW_MODULE="${DEFAULT_HOST}/${NEW_ORG}/${NEW_PROJECT}"
|
|
OLD_MODULE="$CURRENT_MODULE"
|
|
OLD_PROJECT=$(basename "$OLD_MODULE") # e.g. go-template
|
|
NEW_DISPLAY=$(to_title "$NEW_PROJECT") # e.g. My Service
|
|
OLD_DISPLAY=$(to_title "$OLD_PROJECT") # e.g. Go Template
|
|
|
|
# ── Preview ───────────────────────────────────────────────────────────────────
|
|
heading "Changes to be applied"
|
|
printf " %-22s %s → %s\n" "Module path:" "$OLD_MODULE" "$NEW_MODULE"
|
|
printf " %-22s %s → %s\n" "Project name:" "$OLD_PROJECT" "$NEW_PROJECT"
|
|
printf " %-22s %s → %s\n" "Display name:" "$OLD_DISPLAY" "$NEW_DISPLAY"
|
|
echo
|
|
|
|
if [[ $# -lt 2 ]]; then
|
|
read -rp "Apply these changes? [y/N] " CONFIRM
|
|
case "$CONFIRM" in
|
|
[yY][eE][sS]|[yY]) ;;
|
|
*) echo "Aborted."; exit 0 ;;
|
|
esac
|
|
fi
|
|
|
|
# ── Helper: portable in-place sed ────────────────────────────────────────────
|
|
# macOS sed requires an extension argument for -i; GNU sed does not.
|
|
sedi() {
|
|
if sed --version &>/dev/null 2>&1; then
|
|
# GNU sed
|
|
sed -i "$@"
|
|
else
|
|
# BSD / macOS sed
|
|
sed -i '' "$@"
|
|
fi
|
|
}
|
|
|
|
# ── Apply substitutions ───────────────────────────────────────────────────────
|
|
heading "Applying changes"
|
|
|
|
# 1. go.mod — module declaration
|
|
sedi "s|${OLD_MODULE}|${NEW_MODULE}|g" go.mod
|
|
info "go.mod"
|
|
|
|
# 2. All Go source files — import paths
|
|
GO_FILES=$(find . \
|
|
-not -path './.git/*' \
|
|
-not -path './bin/*' \
|
|
-name '*.go' \
|
|
-type f)
|
|
|
|
CHANGED_GO=0
|
|
for f in $GO_FILES; do
|
|
if grep -q "$OLD_MODULE" "$f" 2>/dev/null; then
|
|
sedi "s|${OLD_MODULE}|${NEW_MODULE}|g" "$f"
|
|
CHANGED_GO=$((CHANGED_GO + 1))
|
|
fi
|
|
done
|
|
info "${CHANGED_GO} Go source file(s)"
|
|
|
|
# 3. .mockery.yaml — package path
|
|
if [[ -f .mockery.yaml ]]; then
|
|
sedi "s|${OLD_MODULE}|${NEW_MODULE}|g" .mockery.yaml
|
|
info ".mockery.yaml"
|
|
fi
|
|
|
|
# 4. config/dev.yaml — app.name
|
|
if [[ -f config/dev.yaml ]]; then
|
|
sedi "s|name: \"${OLD_PROJECT}\"|name: \"${NEW_PROJECT}\"|g" config/dev.yaml
|
|
info "config/dev.yaml"
|
|
fi
|
|
|
|
# 5. .devcontainer/devcontainer.json — "name" field
|
|
if [[ -f .devcontainer/devcontainer.json ]]; then
|
|
sedi "s|\"name\": \"${OLD_DISPLAY}\"|\"name\": \"${NEW_DISPLAY}\"|g" \
|
|
.devcontainer/devcontainer.json
|
|
info ".devcontainer/devcontainer.json"
|
|
fi
|
|
|
|
# 6. README.md — heading + all module path occurrences
|
|
if [[ -f README.md ]]; then
|
|
sedi "s|^# ${OLD_PROJECT}$|# ${NEW_PROJECT}|g" README.md
|
|
sedi "s|${OLD_MODULE}|${NEW_MODULE}|g" README.md
|
|
sedi "s|name: \"${OLD_PROJECT}\"|name: \"${NEW_PROJECT}\"|g" README.md
|
|
info "README.md"
|
|
fi
|
|
|
|
# 7. CLAUDE.md — Module line
|
|
if [[ -f CLAUDE.md ]]; then
|
|
sedi "s|${OLD_MODULE}|${NEW_MODULE}|g" CLAUDE.md
|
|
info "CLAUDE.md"
|
|
fi
|
|
|
|
# ── Post-rename suggestions ───────────────────────────────────────────────────
|
|
heading "Done"
|
|
echo "Module is now: ${BOLD}${NEW_MODULE}${RESET}"
|
|
echo
|
|
echo "Recommended next steps:"
|
|
echo " go mod tidy # sync go.sum after path change"
|
|
echo " make mocks # regenerate mocks with new import paths"
|
|
echo " make build # verify it compiles"
|
|
echo " make test # verify tests pass"
|
|
echo
|
|
warn "If you renamed the directory on disk, update git remote too:"
|
|
echo " git remote set-url origin git@${DEFAULT_HOST}:${NEW_ORG}/${NEW_PROJECT}.git"
|