fiumba
This commit is contained in:
156
tools/branch.sh
Executable file
156
tools/branch.sh
Executable file
@ -0,0 +1,156 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Configuration
|
||||
USER_FILE="${HOME:?HOME not set}/.qtx_branch_last_user"
|
||||
VALID_TYPES=("feature" "hotfix" "refactor" "improvement" "doc" "fix")
|
||||
|
||||
# Trap for clean Ctrl+C handling
|
||||
trap 'echo ""; echo "Cancelled."; exit 130' INT TERM
|
||||
|
||||
# Check dependencies
|
||||
if ! command -v git &> /dev/null; then
|
||||
echo "Error: 'git' command not found" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check we're in project root
|
||||
if [[ ! -f "Makefile" ]]; then
|
||||
echo "Error: Makefile not found. Run this script from project root." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "=== Make Branch Helper ==="
|
||||
echo ""
|
||||
|
||||
# Load last user safely using shell built-in
|
||||
LAST_USER=""
|
||||
if [[ -f "$USER_FILE" && -r "$USER_FILE" && ! -L "$USER_FILE" ]]; then
|
||||
# Use shell built-in instead of cat, only read first line
|
||||
LAST_USER=$(head -n 1 "$USER_FILE" 2>/dev/null || true)
|
||||
fi
|
||||
|
||||
if [[ -n "$LAST_USER" ]]; then
|
||||
echo "Last user found: $LAST_USER"
|
||||
fi
|
||||
|
||||
# Select branch type
|
||||
echo ""
|
||||
echo "Select branch type:"
|
||||
select TYPE in "${VALID_TYPES[@]}"; do
|
||||
if [[ -n "$TYPE" ]]; then
|
||||
echo "Selected type: $TYPE"
|
||||
break
|
||||
else
|
||||
echo "Invalid selection. Please try again."
|
||||
fi
|
||||
done
|
||||
|
||||
# Get user with validation
|
||||
echo ""
|
||||
while true; do
|
||||
read -r -p "Enter user (alphanumeric, _, or -) [${LAST_USER:-none}]: " USER
|
||||
USER="${USER:-$LAST_USER}"
|
||||
|
||||
if [[ -z "$USER" ]]; then
|
||||
echo "Error: user is required (e.g., jdoe, fsmith)" >&2
|
||||
continue
|
||||
fi
|
||||
|
||||
if [[ ! "$USER" =~ ^[a-zA-Z0-9_-]+$ ]]; then
|
||||
echo "Error: user must be alphanumeric with optional _ or - (e.g., jdoe, f_smith)" >&2
|
||||
continue
|
||||
fi
|
||||
|
||||
break
|
||||
done
|
||||
|
||||
# Save user preference securely with umask
|
||||
if [[ -n "$HOME" ]]; then
|
||||
# Remove if it's a symlink (prevent symlink attacks)
|
||||
[[ -L "$USER_FILE" ]] && rm -f "$USER_FILE"
|
||||
|
||||
# Create with restricted permissions (600)
|
||||
(umask 077 && echo "$USER" > "$USER_FILE")
|
||||
fi
|
||||
|
||||
# Get issue number with numeric validation
|
||||
echo ""
|
||||
while true; do
|
||||
read -r -p "Enter issue number (numeric only): " ISSUE
|
||||
|
||||
if [[ -z "$ISSUE" ]]; then
|
||||
echo "Error: issue number is required (e.g., 123, 456)" >&2
|
||||
continue
|
||||
fi
|
||||
|
||||
if [[ ! "$ISSUE" =~ ^[0-9]+$ ]]; then
|
||||
echo "Error: issue number must be numeric only (e.g., 39, 123)" >&2
|
||||
continue
|
||||
fi
|
||||
|
||||
break
|
||||
done
|
||||
|
||||
# Get summary with validation
|
||||
echo ""
|
||||
while true; do
|
||||
read -r -p "Enter summary (max 100 chars): " SUMMARY
|
||||
|
||||
# Trim leading/trailing whitespace
|
||||
SUMMARY=$(echo "$SUMMARY" | xargs)
|
||||
|
||||
if [[ -z "$SUMMARY" ]]; then
|
||||
echo "Error: summary is required (e.g., 'add new endpoint', 'fix login bug')" >&2
|
||||
continue
|
||||
fi
|
||||
|
||||
if [[ ${#SUMMARY} -gt 100 ]]; then
|
||||
echo "Error: summary too long (${#SUMMARY} chars, max 100)" >&2
|
||||
continue
|
||||
fi
|
||||
|
||||
# Basic validation - allow common characters
|
||||
if [[ ! "$SUMMARY" =~ ^[a-zA-Z0-9\ _\-]+$ ]]; then
|
||||
echo "Warning: summary contains special characters. Use only letters, numbers, spaces, hyphens, and underscores." >&2
|
||||
read -r -p "Continue anyway? (y/N): " CONFIRM
|
||||
if [[ ! "$CONFIRM" =~ ^[Yy]$ ]]; then
|
||||
continue
|
||||
fi
|
||||
fi
|
||||
|
||||
break
|
||||
done
|
||||
|
||||
# Get ISSUE_PREFIX from Makefile.common (default to SKL if not found)
|
||||
ISSUE_PREFIX="SKL"
|
||||
if [[ -f "Makefile.common" ]]; then
|
||||
# Extract ISSUE_PREFIX from Makefile.common
|
||||
PREFIX_LINE=$(grep "^ISSUE_PREFIX" Makefile.common 2>/dev/null || true)
|
||||
if [[ -n "$PREFIX_LINE" ]]; then
|
||||
ISSUE_PREFIX=$(echo "$PREFIX_LINE" | cut -d'=' -f2 | tr -d ' ')
|
||||
fi
|
||||
fi
|
||||
|
||||
# Build branch name: type/user/PREFIX-number/summary_with_underscores
|
||||
BRANCH_NAME="$TYPE/$USER/$ISSUE_PREFIX-$ISSUE/${SUMMARY// /_}"
|
||||
|
||||
# Show summary and execute
|
||||
echo ""
|
||||
echo "Creating branch:"
|
||||
echo " Type: $TYPE"
|
||||
echo " User: $USER"
|
||||
echo " Issue: $ISSUE_PREFIX-$ISSUE"
|
||||
echo " Summary: $SUMMARY"
|
||||
echo " Branch: $BRANCH_NAME"
|
||||
echo ""
|
||||
|
||||
# Create the git branch
|
||||
if git checkout -b "$BRANCH_NAME"; then
|
||||
echo ""
|
||||
echo "✓ Branch '$BRANCH_NAME' created and checked out successfully"
|
||||
exit 0
|
||||
else
|
||||
echo "" >&2
|
||||
echo "✗ Failed to create branch '$BRANCH_NAME'" >&2
|
||||
exit 1
|
||||
fi
|
||||
Reference in New Issue
Block a user