350 lines
9 KiB
Bash
350 lines
9 KiB
Bash
|
|
#!/bin/bash
|
||
|
|
|
||
|
|
# Veza Development CLI
|
||
|
|
# Script principal pour gérer le développement du projet Veza
|
||
|
|
|
||
|
|
set -e
|
||
|
|
|
||
|
|
# Couleurs pour l'affichage
|
||
|
|
BLUE='\033[0;34m'
|
||
|
|
GREEN='\033[0;32m'
|
||
|
|
RED='\033[0;31m'
|
||
|
|
YELLOW='\033[1;33m'
|
||
|
|
NC='\033[0m' # No Color
|
||
|
|
|
||
|
|
# Configuration
|
||
|
|
PROJECT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||
|
|
MANIFEST_FILE="$PROJECT_ROOT/.veza/feature-manifest.yaml"
|
||
|
|
|
||
|
|
# Fonctions utilitaires
|
||
|
|
log_info() {
|
||
|
|
echo -e "${BLUE}[INFO]${NC} $1"
|
||
|
|
}
|
||
|
|
|
||
|
|
log_success() {
|
||
|
|
echo -e "${GREEN}[SUCCESS]${NC} $1"
|
||
|
|
}
|
||
|
|
|
||
|
|
log_warning() {
|
||
|
|
echo -e "${YELLOW}[WARNING]${NC} $1"
|
||
|
|
}
|
||
|
|
|
||
|
|
log_error() {
|
||
|
|
echo -e "${RED}[ERROR]${NC} $1"
|
||
|
|
}
|
||
|
|
|
||
|
|
# Vérifier que le manifeste existe
|
||
|
|
check_manifest() {
|
||
|
|
if [[ ! -f "$MANIFEST_FILE" ]]; then
|
||
|
|
log_error "Manifest file not found: $MANIFEST_FILE"
|
||
|
|
exit 1
|
||
|
|
fi
|
||
|
|
}
|
||
|
|
|
||
|
|
# Fonction pour valider la compatibilité
|
||
|
|
validate_compatibility() {
|
||
|
|
log_info "Validating feature compatibility..."
|
||
|
|
|
||
|
|
# Vérifier les dépendances
|
||
|
|
if command -v yq &> /dev/null; then
|
||
|
|
local features=$(yq eval '.features | keys | .[]' "$MANIFEST_FILE")
|
||
|
|
for feature in $features; do
|
||
|
|
log_info "Checking compatibility for feature: $feature"
|
||
|
|
# Ici on pourrait ajouter des vérifications spécifiques
|
||
|
|
done
|
||
|
|
log_success "Compatibility validation completed"
|
||
|
|
else
|
||
|
|
log_warning "yq not installed, skipping compatibility validation"
|
||
|
|
fi
|
||
|
|
}
|
||
|
|
|
||
|
|
# Fonction pour lancer les tests
|
||
|
|
run_tests() {
|
||
|
|
local scope=${1:-"all"}
|
||
|
|
|
||
|
|
log_info "Running tests for scope: $scope"
|
||
|
|
|
||
|
|
case $scope in
|
||
|
|
"core"|"all")
|
||
|
|
log_info "Testing core backend..."
|
||
|
|
cd "$PROJECT_ROOT/veza-backend-api"
|
||
|
|
make test
|
||
|
|
;;
|
||
|
|
"chat"|"all")
|
||
|
|
log_info "Testing chat server..."
|
||
|
|
cd "$PROJECT_ROOT/veza-chat-server"
|
||
|
|
cargo test
|
||
|
|
;;
|
||
|
|
"stream"|"all")
|
||
|
|
log_info "Testing stream server..."
|
||
|
|
cd "$PROJECT_ROOT/veza-stream-server"
|
||
|
|
cargo test
|
||
|
|
;;
|
||
|
|
*)
|
||
|
|
log_error "Unknown scope: $scope"
|
||
|
|
exit 1
|
||
|
|
;;
|
||
|
|
esac
|
||
|
|
|
||
|
|
log_success "Tests completed for scope: $scope"
|
||
|
|
}
|
||
|
|
|
||
|
|
# Fonction pour vérifier le format des commits
|
||
|
|
validate_commit_format() {
|
||
|
|
local commit_msg="$1"
|
||
|
|
local commit_regex='^\[(core|auth|chat|stream|market|docs|test)\]\[(feat|fix|refactor|test|docs|ci)\]'
|
||
|
|
|
||
|
|
if ! echo "$commit_msg" | grep -qE "$commit_regex"; then
|
||
|
|
log_error "Invalid commit format!"
|
||
|
|
echo "Expected format: [SCOPE][TYPE] Description"
|
||
|
|
echo "Examples:"
|
||
|
|
echo " [core][feat] Add user authentication"
|
||
|
|
echo " [chat][fix] Fix WebSocket connection"
|
||
|
|
echo " [docs][ci] Update API documentation"
|
||
|
|
exit 1
|
||
|
|
fi
|
||
|
|
|
||
|
|
log_success "Commit format is valid"
|
||
|
|
}
|
||
|
|
|
||
|
|
# Fonction pour créer une nouvelle feature
|
||
|
|
create_feature() {
|
||
|
|
local feature_name="$1"
|
||
|
|
|
||
|
|
if [[ -z "$feature_name" ]]; then
|
||
|
|
log_error "Feature name is required"
|
||
|
|
echo "Usage: $0 new feature <feature-name>"
|
||
|
|
exit 1
|
||
|
|
fi
|
||
|
|
|
||
|
|
log_info "Creating new feature: $feature_name"
|
||
|
|
|
||
|
|
# Créer la structure de la feature
|
||
|
|
local feature_dir="$PROJECT_ROOT/features/$feature_name"
|
||
|
|
mkdir -p "$feature_dir"/{cmd,internal/{handlers,services,repositories,models},tests/{unit,integration,e2e},docs,migrations}
|
||
|
|
|
||
|
|
# Générer le fichier de base de la feature
|
||
|
|
cat > "$feature_dir/feature.go" << EOF
|
||
|
|
package $feature_name
|
||
|
|
|
||
|
|
import (
|
||
|
|
"time"
|
||
|
|
"github.com/okinrev/veza-web-app/internal/core/contracts"
|
||
|
|
)
|
||
|
|
|
||
|
|
type Feature struct {
|
||
|
|
metadata contracts.FeatureMetadata
|
||
|
|
}
|
||
|
|
|
||
|
|
func New() contracts.FeatureContract {
|
||
|
|
return &Feature{
|
||
|
|
metadata: contracts.FeatureMetadata{
|
||
|
|
Name: "$feature_name",
|
||
|
|
Version: "0.1.0",
|
||
|
|
Description: "TODO: Add description",
|
||
|
|
Author: "$(git config user.name)",
|
||
|
|
CreatedAt: time.Now(),
|
||
|
|
},
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func (f *Feature) Validate(registry contracts.Registry) error {
|
||
|
|
// TODO: Implement validation
|
||
|
|
return nil
|
||
|
|
}
|
||
|
|
|
||
|
|
func (f *Feature) Initialize(registry contracts.Registry) error {
|
||
|
|
// TODO: Implement initialization
|
||
|
|
return nil
|
||
|
|
}
|
||
|
|
EOF
|
||
|
|
|
||
|
|
# Créer le manifeste de la feature
|
||
|
|
cat > "$feature_dir/manifest.yaml" << EOF
|
||
|
|
name: $feature_name
|
||
|
|
version: 0.1.0
|
||
|
|
description: "TODO: Add description"
|
||
|
|
dependencies:
|
||
|
|
core: ">=1.0.0"
|
||
|
|
compatibility:
|
||
|
|
min_version: "1.0.0"
|
||
|
|
max_version: "2.0.0"
|
||
|
|
EOF
|
||
|
|
|
||
|
|
log_success "Feature $feature_name created successfully!"
|
||
|
|
log_info "Location: $feature_dir"
|
||
|
|
}
|
||
|
|
|
||
|
|
# Fonction pour déployer
|
||
|
|
deploy() {
|
||
|
|
local environment="$1"
|
||
|
|
|
||
|
|
if [[ -z "$environment" ]]; then
|
||
|
|
log_error "Environment is required"
|
||
|
|
echo "Usage: $0 deploy <environment>"
|
||
|
|
echo "Environments: staging, production"
|
||
|
|
exit 1
|
||
|
|
fi
|
||
|
|
|
||
|
|
log_info "Deploying to environment: $environment"
|
||
|
|
|
||
|
|
case $environment in
|
||
|
|
"staging")
|
||
|
|
# Déploiement en staging
|
||
|
|
log_info "Deploying to staging..."
|
||
|
|
# Ici on ajouterait les commandes de déploiement
|
||
|
|
;;
|
||
|
|
"production")
|
||
|
|
# Déploiement en production
|
||
|
|
log_info "Deploying to production..."
|
||
|
|
# Ici on ajouterait les commandes de déploiement
|
||
|
|
;;
|
||
|
|
*)
|
||
|
|
log_error "Unknown environment: $environment"
|
||
|
|
exit 1
|
||
|
|
;;
|
||
|
|
esac
|
||
|
|
|
||
|
|
log_success "Deployment to $environment completed"
|
||
|
|
}
|
||
|
|
|
||
|
|
# Fonction pour générer la documentation
|
||
|
|
generate_docs() {
|
||
|
|
local doc_type="$1"
|
||
|
|
|
||
|
|
log_info "Generating documentation: $doc_type"
|
||
|
|
|
||
|
|
case $doc_type in
|
||
|
|
"api")
|
||
|
|
log_info "Generating API documentation..."
|
||
|
|
# Générer la documentation API
|
||
|
|
;;
|
||
|
|
"architecture")
|
||
|
|
log_info "Generating architecture documentation..."
|
||
|
|
# Générer la documentation d'architecture
|
||
|
|
;;
|
||
|
|
"all")
|
||
|
|
log_info "Generating all documentation..."
|
||
|
|
# Générer toute la documentation
|
||
|
|
;;
|
||
|
|
*)
|
||
|
|
log_error "Unknown documentation type: $doc_type"
|
||
|
|
exit 1
|
||
|
|
;;
|
||
|
|
esac
|
||
|
|
|
||
|
|
log_success "Documentation generation completed"
|
||
|
|
}
|
||
|
|
|
||
|
|
# Fonction pour synchroniser avec Cursor AI
|
||
|
|
sync_cursor() {
|
||
|
|
log_info "Synchronizing with Cursor AI..."
|
||
|
|
|
||
|
|
# Créer le dossier .cursor s'il n'existe pas
|
||
|
|
mkdir -p "$PROJECT_ROOT/.cursor"
|
||
|
|
|
||
|
|
# Générer le fichier de contexte
|
||
|
|
cat > "$PROJECT_ROOT/.cursor/context.json" << EOF
|
||
|
|
{
|
||
|
|
"project": "Veza",
|
||
|
|
"architecture": "hexagonal",
|
||
|
|
"features": {
|
||
|
|
"core": {
|
||
|
|
"status": "stable",
|
||
|
|
"version": "1.0.0"
|
||
|
|
},
|
||
|
|
"chat-server": {
|
||
|
|
"status": "stable",
|
||
|
|
"version": "1.0.0"
|
||
|
|
},
|
||
|
|
"stream-server": {
|
||
|
|
"status": "stable",
|
||
|
|
"version": "1.0.0"
|
||
|
|
}
|
||
|
|
},
|
||
|
|
"current_tasks": [],
|
||
|
|
"validation_rules": [
|
||
|
|
"version_compatibility",
|
||
|
|
"interface_contracts",
|
||
|
|
"event_consistency"
|
||
|
|
]
|
||
|
|
}
|
||
|
|
EOF
|
||
|
|
|
||
|
|
log_success "Cursor AI context synchronized"
|
||
|
|
}
|
||
|
|
|
||
|
|
# Fonction d'aide
|
||
|
|
show_help() {
|
||
|
|
echo "Veza Development CLI"
|
||
|
|
echo ""
|
||
|
|
echo "Usage: $0 <command> [options]"
|
||
|
|
echo ""
|
||
|
|
echo "Commands:"
|
||
|
|
echo " validate - Validate feature compatibility"
|
||
|
|
echo " test [scope] - Run tests (core|chat|stream|all)"
|
||
|
|
echo " new feature <name> - Create a new feature"
|
||
|
|
echo " deploy <environment> - Deploy to environment (staging|production)"
|
||
|
|
echo " generate docs [type] - Generate documentation (api|architecture|all)"
|
||
|
|
echo " sync-cursor - Synchronize with Cursor AI"
|
||
|
|
echo " commit-validate <message> - Validate commit message format"
|
||
|
|
echo " help - Show this help message"
|
||
|
|
echo ""
|
||
|
|
echo "Examples:"
|
||
|
|
echo " $0 validate"
|
||
|
|
echo " $0 test core"
|
||
|
|
echo " $0 new feature auth"
|
||
|
|
echo " $0 deploy staging"
|
||
|
|
echo " $0 generate docs api"
|
||
|
|
echo " $0 commit-validate '[core][feat] Add user authentication'"
|
||
|
|
}
|
||
|
|
|
||
|
|
# Fonction principale
|
||
|
|
main() {
|
||
|
|
check_manifest
|
||
|
|
|
||
|
|
case "${1:-help}" in
|
||
|
|
"validate")
|
||
|
|
validate_compatibility
|
||
|
|
;;
|
||
|
|
"test")
|
||
|
|
run_tests "$2"
|
||
|
|
;;
|
||
|
|
"new")
|
||
|
|
if [[ "$2" == "feature" ]]; then
|
||
|
|
create_feature "$3"
|
||
|
|
else
|
||
|
|
log_error "Unknown new command: $2"
|
||
|
|
exit 1
|
||
|
|
fi
|
||
|
|
;;
|
||
|
|
"deploy")
|
||
|
|
deploy "$2"
|
||
|
|
;;
|
||
|
|
"generate")
|
||
|
|
if [[ "$2" == "docs" ]]; then
|
||
|
|
generate_docs "$3"
|
||
|
|
else
|
||
|
|
log_error "Unknown generate command: $2"
|
||
|
|
exit 1
|
||
|
|
fi
|
||
|
|
;;
|
||
|
|
"sync-cursor")
|
||
|
|
sync_cursor
|
||
|
|
;;
|
||
|
|
"commit-validate")
|
||
|
|
validate_commit_format "$2"
|
||
|
|
;;
|
||
|
|
"help"|"--help"|"-h")
|
||
|
|
show_help
|
||
|
|
;;
|
||
|
|
*)
|
||
|
|
log_error "Unknown command: $1"
|
||
|
|
show_help
|
||
|
|
exit 1
|
||
|
|
;;
|
||
|
|
esac
|
||
|
|
}
|
||
|
|
|
||
|
|
# Exécuter la fonction principale
|
||
|
|
main "$@"
|