furt/scripts/update_script_labels.sh

492 lines
15 KiB
Bash
Raw Normal View History

#!/bin/bash
# scripts/update_script_labels.sh
# Auto-updates all scripts with current label definitions from registry
# FINAL FIXED VERSION with corrected all_templates logic
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
REGISTRY_FILE="$PROJECT_ROOT/configs/labels.registry"
# Colors for logging
GREEN='\033[0;32m'
BLUE='\033[0;34m'
RED='\033[0;31m'
YELLOW='\033[1;33m'
NC='\033[0m'
log_info() { echo -e "${BLUE}[INFO]${NC} $1"; }
log_success() { echo -e "${GREEN}[SUCCESS]${NC} $1"; }
log_error() { echo -e "${RED}[ERROR]${NC} $1"; }
log_warning() { echo -e "${YELLOW}[WARNING]${NC} $1"; }
# Parse label registry into associative arrays
declare -A LABEL_COLORS
declare -A LABEL_CONTEXTS
declare -A LABEL_USAGES
# Create registry file if it doesn't exist
create_registry_if_missing() {
if [[ ! -f "$REGISTRY_FILE" ]]; then
log_info "Creating label registry file..."
mkdir -p "$(dirname "$REGISTRY_FILE")"
cat > "$REGISTRY_FILE" << 'EOF'
# Central Label Registry for Furt API Gateway Project
# Format: name:color:context:usage_contexts
# This file is the single source of truth for all labels
# === CORE WORKFLOW LABELS ===
service-request:7057ff:new_service:service_templates,status_updates
enhancement:84b6eb:improvement:all_templates
bug:d73a4a:error:bug_template,status_updates
question:d876e3:discussion:question_template
# === COMPONENT CATEGORIES ===
gateway:0052cc:gateway_core:architecture_template,performance_template,service_templates
performance:fbca04:optimization:performance_template,architecture_template
architecture:d4c5f9:design:architecture_template,gateway
security:28a745:security_review:security_template,architecture_template
configuration:f9d71c:config_management:deployment_template,architecture_template
# === SERVICE-SPECIFIC LABELS ===
service-formular2mail:1d76db:formular2mail:formular2mail_integration
service-sagjan:1d76db:sagjan:sagjan_integration
service-newsletter:ff6b6b:newsletter:newsletter_integration
# === WORKFLOW STATE LABELS ===
work-in-progress:fbca04:active:status_updates
needs-review:0e8a16:review:status_updates
blocked:d73a4a:blocked:status_updates
ready-for-deployment:28a745:deploy_ready:status_updates
# === INTEGRATION LABELS ===
hugo-integration:ff7518:frontend:hugo_templates,integration
api-contract:5319e7:api_design:api_templates,service_templates
breaking-change:d73a4a:breaking:api_templates,architecture_template
# === PRIORITY LABELS ===
high-priority:d73a4a:urgent:all_templates
low-priority:0e8a16:nice_to_have:all_templates
# === META LABELS ===
low-tech:6f42c1:low_tech_principle:architecture_template,performance_template,security_template
digital-sovereignty:6f42c1:digital_sovereignty:architecture_template,performance_template,security_template
good-first-issue:7057ff:beginner_friendly:manual_assignment
help-wanted:159818:community_help:manual_assignment
# === DEPLOYMENT LABELS ===
deployment:ff7518:deployment:deployment_template
testing:f9d71c:testing:testing_template,integration
EOF
log_success "Created label registry: $REGISTRY_FILE"
fi
}
parse_registry() {
create_registry_if_missing
log_info "Parsing label registry..."
while IFS= read -r line; do
# Skip comments and empty lines
[[ "$line" =~ ^#.*$ ]] && continue
[[ -z "$line" ]] && continue
# Parse format: name:color:context:usage_contexts
if [[ "$line" =~ ^([^:]+):([^:]+):([^:]+):(.+)$ ]]; then
local name="${BASH_REMATCH[1]}"
local color="${BASH_REMATCH[2]}"
local context="${BASH_REMATCH[3]}"
local usage="${BASH_REMATCH[4]}"
LABEL_COLORS["$name"]="$color"
LABEL_CONTEXTS["$name"]="$context"
LABEL_USAGES["$name"]="$usage"
log_info "Loaded label: $name ($context)"
fi
done < "$REGISTRY_FILE"
log_success "Loaded ${#LABEL_COLORS[@]} labels from registry"
}
# Generate label definitions section for scripts
generate_label_definitions() {
cat << 'EOF'
# === LABEL DEFINITIONS START ===
# This section is auto-maintained by update_script_labels.sh
# DO NOT EDIT MANUALLY - Changes will be overwritten
declare -A LABEL_DEFINITIONS=(
EOF
for label in "${!LABEL_COLORS[@]}"; do
local color="${LABEL_COLORS[$label]}"
local context="${LABEL_CONTEXTS[$label]}"
local usage="${LABEL_USAGES[$label]}"
echo " [\"$label\"]=\"color:$color;context:$context;usage:$usage\""
done
cat << 'EOF'
)
# Extract label info
get_label_color() { echo "${LABEL_DEFINITIONS[$1]}" | cut -d';' -f1 | cut -d':' -f2; }
get_label_context() { echo "${LABEL_DEFINITIONS[$1]}" | cut -d';' -f2 | cut -d':' -f2; }
get_label_usage() { echo "${LABEL_DEFINITIONS[$1]}" | cut -d';' -f3 | cut -d':' -f2; }
# Check if label is valid for context
is_label_valid_for_context() {
local label="$1"
local context="$2"
local usage=$(get_label_usage "$label")
[[ "$usage" == *"$context"* ]] || [[ "$usage" == "all_templates" ]]
}
# === LABEL DEFINITIONS END ===
EOF
}
# Generate template-to-labels mapping - FIXED VERSION
generate_template_mappings() {
cat << 'EOF'
# === TEMPLATE LABEL MAPPINGS START ===
# Auto-generated template to label mappings
declare -A TEMPLATE_LABELS=(
EOF
# FIXED: Consistent template names with corrected all_templates logic
declare -A template_mappings=(
["service"]="service_templates"
["architecture"]="architecture_template"
["performance"]="performance_template"
["bug"]="bug_template"
["security"]="security_template"
["hugo"]="hugo_templates"
["api"]="api_templates"
["deployment"]="deployment_template"
)
for template_name in "${!template_mappings[@]}"; do
local template_usage="${template_mappings[$template_name]}"
local labels=()
# FIXED: First add all_templates labels to every template
for label in "${!LABEL_USAGES[@]}"; do
local usage="${LABEL_USAGES[$label]}"
# EXCLUDE service-specific labels from all templates
if [[ "$label" == service-* ]]; then
continue
fi
# Skip manual assignment labels
if [[ "$usage" == "manual_assignment" ]]; then
continue
fi
# FIXED: Add all_templates labels to every template first
if [[ "$usage" == "all_templates" ]]; then
labels+=("$label")
continue
fi
# Add template-specific labels
if [[ "$usage" == *"$template_usage"* ]]; then
labels+=("$label")
fi
done
if [[ ${#labels[@]} -gt 0 ]]; then
local label_list=$(IFS=','; echo "${labels[*]}")
echo " [\"$template_name\"]=\"$label_list\""
fi
done
cat << 'EOF'
)
# === TEMPLATE LABEL MAPPINGS END ===
EOF
}
# Generate filter options for get_issues.sh
generate_filter_options() {
cat << 'EOF'
# === FILTER OPTIONS START ===
# Auto-generated filter options for get_issues.sh
show_filter_help() {
echo "📋 Available filters:"
EOF
# Group labels by context for better help display
declare -A context_labels
for label in "${!LABEL_CONTEXTS[@]}"; do
local context="${LABEL_CONTEXTS[$label]}"
if [[ -z "${context_labels[$context]}" ]]; then
context_labels[$context]="$label"
else
context_labels[$context]="${context_labels[$context]},$label"
fi
done
for context in "${!context_labels[@]}"; do
echo " echo \" $context: ${context_labels[$context]}\""
done
cat << 'EOF'
}
# Filter case statement
handle_filter() {
local filter="$1"
case "$filter" in
EOF
for label in "${!LABEL_COLORS[@]}"; do
echo " $label) filter_by_label \"$label\" ;;"
done
cat << 'EOF'
pipeline) show_pipeline_overview ;;
stats) show_statistics ;;
all) show_all_issues ;;
*)
log_error "Unknown filter: $filter"
show_filter_help
exit 1
;;
esac
}
# === FILTER OPTIONS END ===
EOF
}
# Update a single script file
update_script_file() {
local script_file="$1"
if [[ ! -f "$script_file" ]]; then
log_warning "Script not found: $script_file"
return 1
fi
log_info "Updating $script_file..."
# Create backup
cp "$script_file" "${script_file}.backup"
# Check if script has label definition sections
if ! grep -q "# === LABEL DEFINITIONS START ===" "$script_file"; then
log_warning "$script_file has no label definitions section - skipping"
return 0
fi
# Find section boundaries
local start_line=$(grep -n "# === LABEL DEFINITIONS START ===" "$script_file" | cut -d: -f1)
local end_line=$(grep -n "# === LABEL DEFINITIONS END ===" "$script_file" | cut -d: -f1)
if [[ -z "$start_line" ]] || [[ -z "$end_line" ]]; then
log_error "Malformed label definition section in $script_file"
return 1
fi
# Generate new content
local new_definitions=$(generate_label_definitions)
# Handle template mappings if present
if grep -q "# === TEMPLATE LABEL MAPPINGS START ===" "$script_file"; then
new_definitions+="\n$(generate_template_mappings)"
fi
# Handle filter options if present (for get_issues.sh)
if grep -q "# === FILTER OPTIONS START ===" "$script_file"; then
new_definitions+="\n$(generate_filter_options)"
fi
# Create temporary file with updated content
local temp_file=$(mktemp)
# Copy everything before label definitions
sed -n "1,$((start_line-1))p" "$script_file" > "$temp_file"
# Add new definitions
echo -e "$new_definitions" >> "$temp_file"
# Copy everything after label definitions (find new end line)
if grep -q "# === TEMPLATE LABEL MAPPINGS END ===" "$script_file"; then
local actual_end_line=$(grep -n "# === TEMPLATE LABEL MAPPINGS END ===" "$script_file" | cut -d: -f1)
elif grep -q "# === FILTER OPTIONS END ===" "$script_file"; then
local actual_end_line=$(grep -n "# === FILTER OPTIONS END ===" "$script_file" | cut -d: -f1)
else
local actual_end_line="$end_line"
fi
sed -n "$((actual_end_line+1)),\$p" "$script_file" >> "$temp_file"
# Replace original file
mv "$temp_file" "$script_file"
chmod +x "$script_file"
log_success "Updated $script_file"
}
# Add new label to registry
add_label_to_registry() {
local name="$1"
local color="${2:-ff6b6b}"
local context="${3:-auto_generated}"
local usage="${4:-manual_assignment}"
# Skip if called during auto-update to prevent loops
if [[ "${FURT_AUTO_UPDATE:-}" == "true" ]]; then
log_info "Auto-update mode: Adding $name to registry (skipping rebuild)"
else
log_info "Adding new label to registry: $name"
fi
# Ensure registry exists
create_registry_if_missing
# Check if label already exists
if grep -q "^$name:" "$REGISTRY_FILE"; then
log_warning "Label $name already exists in registry"
return 0
fi
# Add to appropriate section (determine by context)
local section_marker="# === CORE WORKFLOW LABELS ==="
if [[ "$context" == *"service"* ]] || [[ "$name" == service-* ]]; then
section_marker="# === SERVICE-SPECIFIC LABELS ==="
elif [[ "$context" == *"workflow"* ]]; then
section_marker="# === WORKFLOW STATE LABELS ==="
elif [[ "$context" == *"component"* ]]; then
section_marker="# === COMPONENT CATEGORIES ==="
fi
# Create backup
cp "$REGISTRY_FILE" "${REGISTRY_FILE}.backup"
# Find section and add label
local temp_file=$(mktemp)
local added=false
while IFS= read -r line; do
echo "$line" >> "$temp_file"
if [[ "$line" == "$section_marker" ]] && [[ "$added" == false ]]; then
echo "$name:$color:$context:$usage" >> "$temp_file"
added=true
log_success "Added label $name to registry"
fi
done < "$REGISTRY_FILE"
mv "$temp_file" "$REGISTRY_FILE"
}
# Show current registry status
show_registry_status() {
echo "📊 Label Registry Status"
echo "========================"
echo "Registry file: $REGISTRY_FILE"
if [[ -f "$REGISTRY_FILE" ]]; then
echo "Total labels: $(grep -c "^[^#]" "$REGISTRY_FILE" 2>/dev/null || echo 0)"
echo ""
echo "Labels by category:"
local current_section=""
while IFS= read -r line; do
if [[ "$line" =~ ^#\ ===.*===\ $ ]]; then
current_section=$(echo "$line" | sed 's/# === \(.*\) ===/\1/')
echo " $current_section:"
elif [[ "$line" =~ ^[^#]+: ]] && [[ -n "$current_section" ]]; then
local label_name=$(echo "$line" | cut -d: -f1)
echo " - $label_name"
fi
done < "$REGISTRY_FILE"
else
echo "Registry file not found!"
fi
}
# Main function
main() {
local command="${1:-update}"
case "$command" in
update)
log_info "Starting label synchronization..."
parse_registry
# Update all script files
local scripts=(
"$PROJECT_ROOT/scripts/create_issue.sh"
"$PROJECT_ROOT/scripts/get_issues.sh"
"$PROJECT_ROOT/scripts/update_issue.sh"
)
for script in "${scripts[@]}"; do
update_script_file "$script"
done
log_success "All scripts synchronized with label registry!"
;;
add)
local name="$2"
local color="${3:-ff6b6b}"
local context="${4:-auto_generated}"
local usage="${5:-manual_assignment}"
if [[ -z "$name" ]]; then
log_error "Usage: $0 add <name> [color] [context] [usage]"
exit 1
fi
add_label_to_registry "$name" "$color" "$context" "$usage"
# Only update scripts if not in auto-update mode
if [[ "${FURT_AUTO_UPDATE:-}" != "true" ]]; then
parse_registry
main update
fi
;;
status)
show_registry_status
;;
help)
echo "Usage: $0 [command] [options]"
echo ""
echo "Commands:"
echo " update Update all scripts with current registry"
echo " add <name> Add new label to registry and update scripts"
echo " status Show registry status"
echo " help Show this help"
echo ""
echo "Examples:"
echo " $0 update"
echo " $0 add newsletter ff6b6b newsletter_service service_templates"
echo " $0 status"
;;
*)
log_error "Unknown command: $command"
main help
exit 1
;;
esac
}
# Run if executed directly
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
main "$@"
fi