-
Notifications
You must be signed in to change notification settings - Fork 43
fix(speckit): change branch naming scheme #8399
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -5,6 +5,7 @@ set -e | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| JSON_MODE=false | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| SHORT_NAME="" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| BRANCH_NUMBER="" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| INITIALS="" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ARGS=() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| i=1 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| while [ $i -le $# ]; do | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -40,18 +41,32 @@ while [ $i -le $# ]; do | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| BRANCH_NUMBER="$next_arg" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ;; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| --help|-h) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "Usage: $0 [--json] [--short-name <name>] [--number N] <feature_description>" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| --initials) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if [ $((i + 1)) -gt $# ]; then | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo 'Error: --initials requires a value' >&2 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| exit 1 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| i=$((i + 1)) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| next_arg="${!i}" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if [[ "$next_arg" == --* ]]; then | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo 'Error: --initials requires a value' >&2 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| exit 1 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| INITIALS="$next_arg" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ;; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| --help|-h) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "Usage: $0 [--json] [--short-name <name>] [--number N] [--initials <init>] <feature_description>" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "Options:" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo " --json Output in JSON format" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo " --short-name <name> Provide a custom short name (2-4 words) for the branch" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo " --number N Specify branch number manually (overrides auto-detection)" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo " --initials <init> Specify initials manually (overrides OPSMILL_GIT_USER_SHORT and git user.name)" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo " --help, -h Show this help message" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "Examples:" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo " $0 'Add user authentication system' --short-name 'user-auth'" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo " $0 'Implement OAuth2 integration for API' --number 5" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo " $0 'Implement OAuth2 integration for API' --number 5 --initials fac" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| exit 0 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ;; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| *) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -63,7 +78,7 @@ done | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| FEATURE_DESCRIPTION="${ARGS[*]}" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if [ -z "$FEATURE_DESCRIPTION" ]; then | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "Usage: $0 [--json] [--short-name <name>] [--number N] <feature_description>" >&2 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "Usage: $0 [--json] [--short-name <name>] [--number N] [--initials <init>] <feature_description>" >&2 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| exit 1 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -80,6 +95,44 @@ find_repo_root() { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return 1 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Function to extract user short name / initials. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Checks OPSMILL_GIT_USER_SHORT env var first, then falls back to deriving | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # initials from git user.name (first letter of first name + first two letters of last name). | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Example: "Fatih Acar" -> "fac", "John Doe" -> "jdo" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| get_git_initials() { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Prefer explicit environment variable | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if [ -n "${OPSMILL_GIT_USER_SHORT:-}" ]; then | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "$OPSMILL_GIT_USER_SHORT" | tr '[:upper:]' '[:lower:]' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return 0 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| local full_name | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| full_name=$(git config user.name 2>/dev/null || echo "") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
fatih-acar marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if [ -z "$full_name" ]; then | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return 1 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Split into words, take first and last | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| local first_name last_name | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| first_name=$(echo "$full_name" | awk '{print $1}') | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| last_name=$(echo "$full_name" | awk '{print $NF}') | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # If only one name provided, use first 3 chars of that name | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if [ "$first_name" = "$last_name" ]; then | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "$full_name" | tr '[:upper:]' '[:lower:]' | cut -c1-3 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return 0 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # First letter of first name + first two letters of last name | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| local first_initial last_initials | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| first_initial=$(echo "$first_name" | tr '[:upper:]' '[:lower:]' | cut -c1) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| last_initials=$(echo "$last_name" | tr '[:upper:]' '[:lower:]' | cut -c1-2) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "${first_initial}${last_initials}" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Function to get highest number from specs directory | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| get_highest_from_specs() { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| local specs_dir="$1" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -89,7 +142,8 @@ get_highest_from_specs() { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| for dir in "$specs_dir"/*; do | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| [ -d "$dir" ] || continue | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| dirname=$(basename "$dir") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| number=$(echo "$dirname" | grep -o '^[0-9]\+' || echo "0") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Strip optional initials prefix (2-4 lowercase letters followed by hyphen) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| number=$(echo "$dirname" | sed 's/^[a-z]\{2,4\}-//' | grep -o '^[0-9]\+' || echo "0") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| number=$((10#$number)) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if [ "$number" -gt "$highest" ]; then | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| highest=$number | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -112,8 +166,14 @@ get_highest_from_branches() { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Clean branch name: remove leading markers and remote prefixes | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| clean_branch=$(echo "$branch" | sed 's/^[* ]*//; s|^remotes/[^/]*/||') | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Extract feature number if branch matches pattern ###-* | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if echo "$clean_branch" | grep -q '^[0-9]\{3\}-'; then | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Extract feature number if branch matches new format: initials-###-* or old format: ###-* | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if echo "$clean_branch" | grep -q '^[a-z]\{2,4\}-[0-9]\{3\}-'; then | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| number=$(echo "$clean_branch" | sed 's/^[a-z]*-//' | grep -o '^[0-9]\{3\}' || echo "0") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| number=$((10#$number)) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if [ "$number" -gt "$highest" ]; then | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| highest=$number | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| elif echo "$clean_branch" | grep -q '^[0-9]\{3\}-'; then | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| number=$(echo "$clean_branch" | grep -o '^[0-9]\{3\}' || echo "0") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| number=$((10#$number)) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if [ "$number" -gt "$highest" ]; then | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -246,26 +306,43 @@ if [ -z "$BRANCH_NUMBER" ]; then | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Determine initials | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if [ -z "$INITIALS" ]; then | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if [ "$HAS_GIT" = true ]; then | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| INITIALS=$(get_git_initials) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if [ -z "$INITIALS" ]; then | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "Error: Could not determine initials." >&2 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "Set OPSMILL_GIT_USER_SHORT, git config user.name, or use --initials <initials>" >&2 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| exit 1 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| else | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "Error: No git available and --initials not provided." >&2 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "Use --initials <initials> to specify manually." >&2 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| exit 1 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+309
to
+323
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Missing validation of
Add a validation gate after INITIALS is determined: 📝 Proposed fix fi
fi
+# Validate initials format
+if [[ ! "$INITIALS" =~ ^[a-z]{2,4}$ ]]; then
+ echo "Error: Initials '$INITIALS' must be 2-4 lowercase letters." >&2
+ echo "Use --initials <initials> to specify manually." >&2
+ exit 1
+fi
+
# Force base-10 interpretation ...📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Force base-10 interpretation to prevent octal conversion (e.g., 010 → 8 in octal, but should be 10 in decimal) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| FEATURE_NUM=$(printf "%03d" "$((10#$BRANCH_NUMBER))") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| BRANCH_NAME="${FEATURE_NUM}-${BRANCH_SUFFIX}" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| BRANCH_NAME="${INITIALS}-${FEATURE_NUM}-${BRANCH_SUFFIX}" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We could perhaps get to this later, but if we're looking at changing the existing files it could also be good to mention that we can add a suffix key to link any PR to a Jira issue. I.e. if the branch name ends with something like "-IFC-906" we can then see that the issue is linked to a PR from with Jira.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah I also thought including Jira IDs could be good, that would require asking the user for the ID during /speckit.specify I guess
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # GitHub enforces a 244-byte limit on branch names | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Validate and truncate if necessary | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| MAX_BRANCH_LENGTH=244 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if [ ${#BRANCH_NAME} -gt $MAX_BRANCH_LENGTH ]; then | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Calculate how much we need to trim from suffix | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Account for: feature number (3) + hyphen (1) = 4 chars | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| MAX_SUFFIX_LENGTH=$((MAX_BRANCH_LENGTH - 4)) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Account for: initials (variable) + hyphen (1) + feature number (3) + hyphen (1) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| PREFIX_LENGTH=$(( ${#INITIALS} + 1 + 3 + 1 )) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| MAX_SUFFIX_LENGTH=$((MAX_BRANCH_LENGTH - PREFIX_LENGTH)) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Truncate suffix at word boundary if possible | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| TRUNCATED_SUFFIX=$(echo "$BRANCH_SUFFIX" | cut -c1-$MAX_SUFFIX_LENGTH) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Remove trailing hyphen if truncation created one | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| TRUNCATED_SUFFIX=$(echo "$TRUNCATED_SUFFIX" | sed 's/-$//') | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ORIGINAL_BRANCH_NAME="$BRANCH_NAME" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| BRANCH_NAME="${FEATURE_NUM}-${TRUNCATED_SUFFIX}" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| BRANCH_NAME="${INITIALS}-${FEATURE_NUM}-${TRUNCATED_SUFFIX}" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| >&2 echo "[specify] Warning: Branch name exceeded GitHub's 244-byte limit" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| >&2 echo "[specify] Original: $ORIGINAL_BRANCH_NAME (${#ORIGINAL_BRANCH_NAME} bytes)" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| >&2 echo "[specify] Truncated to: $BRANCH_NAME (${#BRANCH_NAME} bytes)" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -288,10 +365,11 @@ if [ -f "$TEMPLATE" ]; then cp "$TEMPLATE" "$SPEC_FILE"; else touch "$SPEC_FILE" | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| export SPECIFY_FEATURE="$BRANCH_NAME" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if $JSON_MODE; then | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| printf '{"BRANCH_NAME":"%s","SPEC_FILE":"%s","FEATURE_NUM":"%s"}\n' "$BRANCH_NAME" "$SPEC_FILE" "$FEATURE_NUM" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| printf '{"BRANCH_NAME":"%s","SPEC_FILE":"%s","FEATURE_NUM":"%s","INITIALS":"%s"}\n' "$BRANCH_NAME" "$SPEC_FILE" "$FEATURE_NUM" "$INITIALS" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| else | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "BRANCH_NAME: $BRANCH_NAME" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "SPEC_FILE: $SPEC_FILE" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "FEATURE_NUM: $FEATURE_NUM" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "INITIALS: $INITIALS" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "SPECIFY_FEATURE environment variable set to: $BRANCH_NAME" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -45,9 +45,9 @@ Given that feature description, do this: | |||||||||
| ``` | ||||||||||
|
|
||||||||||
| b. Find the highest feature number across all sources for the short-name: | ||||||||||
| - Remote branches: `git ls-remote --heads origin | grep -E 'refs/heads/[0-9]+-<short-name>$'` | ||||||||||
| - Local branches: `git branch | grep -E '^[* ]*[0-9]+-<short-name>$'` | ||||||||||
| - Specs directories: Check for directories matching `specs/[0-9]+-<short-name>` | ||||||||||
| - Remote branches: `git ls-remote --heads origin | grep -E 'refs/heads/([a-z]{2,4}-)?[0-9]+-<short-name>$'` | ||||||||||
| - Local branches: `git branch | grep -E '^[* ]*([a-z]{2,4}-)?[0-9]+-<short-name>$'` | ||||||||||
| - Specs directories: Check for directories matching `specs/([a-z]{2,4}-)?[0-9]+-<short-name>` | ||||||||||
|
|
||||||||||
| c. Determine the next available number: | ||||||||||
| - Extract all numbers from all three sources | ||||||||||
|
|
@@ -56,11 +56,13 @@ Given that feature description, do this: | |||||||||
|
|
||||||||||
| d. Run the script `.specify/scripts/bash/create-new-feature.sh --json "$ARGUMENTS"` with the calculated number and short-name: | ||||||||||
| - Pass `--number N+1` and `--short-name "your-short-name"` along with the feature description | ||||||||||
| - Bash example: `.specify/scripts/bash/create-new-feature.sh --json "$ARGUMENTS" --json --number 5 --short-name "user-auth" "Add user authentication"` | ||||||||||
| - PowerShell example: `.specify/scripts/bash/create-new-feature.sh --json "$ARGUMENTS" -Json -Number 5 -ShortName "user-auth" "Add user authentication"` | ||||||||||
| - The `--initials` flag is optional; initials are auto-detected from `git config user.name` (first letter of first name + first two letters of last name, lowercased) | ||||||||||
| - Bash example: `.specify/scripts/bash/create-new-feature.sh --json --number 5 --short-name "user-auth" "Add user authentication"` | ||||||||||
| - PowerShell example: `.specify/scripts/bash/create-new-feature.sh --json -Number 5 -ShortName "user-auth" "Add user authentication"` | ||||||||||
|
Comment on lines
+60
to
+61
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. PowerShell example uses parameter names the bash script doesn't recognize. Line 61 passes Proposed fix- - PowerShell example: `.specify/scripts/bash/create-new-feature.sh --json -Number 5 -ShortName "user-auth" "Add user authentication"`
+ - PowerShell example: `.specify/scripts/bash/create-new-feature.sh --json --number 5 --short-name "user-auth" "Add user authentication"`📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||
|
|
||||||||||
| **IMPORTANT**: | ||||||||||
| - Check all three sources (remote branches, local branches, specs directories) to find the highest number | ||||||||||
| - Numbers are global across all developers -- scan ALL branches regardless of initials prefix | ||||||||||
| - Only match branches/directories with the exact short-name pattern | ||||||||||
| - If no existing branches/directories found with this short-name, start with number 1 | ||||||||||
| - You must only ever run this script once per feature | ||||||||||
|
|
||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix grammar: hyphenate "AI-generated".
When "AI generated" is used as a compound adjective modifying "content", it should be hyphenated.
📝 Proposed fix
📝 Committable suggestion
🧰 Tools
🪛 LanguageTool
[grammar] ~73-~73: Use a hyphen to join words.
Context: ...ools knowledge) - [ ] I have reviewed AI generated content
(QB_NEW_EN_HYPHEN)
🤖 Prompt for AI Agents