First working version
This commit is contained in:
240
cmd/entity-maker/main.go
Normal file
240
cmd/entity-maker/main.go
Normal file
@ -0,0 +1,240 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/entity-maker/entity-maker/internal/config"
|
||||
"github.com/entity-maker/entity-maker/internal/database"
|
||||
"github.com/entity-maker/entity-maker/internal/generator"
|
||||
"github.com/entity-maker/entity-maker/internal/naming"
|
||||
"github.com/entity-maker/entity-maker/internal/prompt"
|
||||
"github.com/fatih/color"
|
||||
)
|
||||
|
||||
func main() {
|
||||
if err := run(); err != nil {
|
||||
prompt.PrintError(err.Error())
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
func run() error {
|
||||
// Parse command line flags
|
||||
var (
|
||||
dbHost = flag.String("host", "", "Database host")
|
||||
dbPort = flag.Int("port", 0, "Database port")
|
||||
dbName = flag.String("db", "", "Database name")
|
||||
dbSchema = flag.String("schema", "", "Database schema")
|
||||
dbUser = flag.String("user", "", "Database user")
|
||||
dbPassword = flag.String("password", "", "Database password")
|
||||
dbTable = flag.String("table", "", "Database table name")
|
||||
outputDir = flag.String("output", "", "Output directory")
|
||||
entityName = flag.String("entity", "", "Entity name override")
|
||||
)
|
||||
flag.Parse()
|
||||
|
||||
// Print header
|
||||
header := color.New(color.FgCyan, color.Bold)
|
||||
header.Println("\n╔════════════════════════════════════════╗")
|
||||
header.Println("║ Entity Maker for TelevendCore ║")
|
||||
header.Println("╚════════════════════════════════════════╝")
|
||||
|
||||
// Load configuration
|
||||
cfg, err := config.Load()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to load config: %w", err)
|
||||
}
|
||||
|
||||
// Prompt for parameters
|
||||
prompt.PrintHeader("Database Connection")
|
||||
|
||||
// Override config with command line flags if provided
|
||||
if *dbHost != "" {
|
||||
cfg.DBHost = *dbHost
|
||||
}
|
||||
if *dbPort != 0 {
|
||||
cfg.DBPort = *dbPort
|
||||
}
|
||||
if *dbName != "" {
|
||||
cfg.DBName = *dbName
|
||||
}
|
||||
if *dbSchema != "" {
|
||||
cfg.DBSchema = *dbSchema
|
||||
}
|
||||
if *dbUser != "" {
|
||||
cfg.DBUser = *dbUser
|
||||
}
|
||||
if *dbPassword != "" {
|
||||
cfg.DBPassword = *dbPassword
|
||||
}
|
||||
if *dbTable != "" {
|
||||
cfg.DBTable = *dbTable
|
||||
}
|
||||
if *outputDir != "" {
|
||||
cfg.OutputDir = *outputDir
|
||||
}
|
||||
if *entityName != "" {
|
||||
cfg.EntityName = *entityName
|
||||
}
|
||||
|
||||
// Prompt for missing parameters
|
||||
cfg.DBHost, err = prompt.PromptString("Database host", cfg.DBHost, false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cfg.DBPort, err = prompt.PromptInt("Database port", cfg.DBPort, false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cfg.DBName, err = prompt.PromptString("Database name", cfg.DBName, true)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cfg.DBSchema, err = prompt.PromptString("Database schema", cfg.DBSchema, false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cfg.DBUser, err = prompt.PromptString("Database user", cfg.DBUser, false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cfg.DBPassword, err = prompt.PromptString("Database password", cfg.DBPassword, false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cfg.DBTable, err = prompt.PromptString("Table name", cfg.DBTable, true)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cfg.OutputDir, err = prompt.PromptDirectory("Output directory", cfg.OutputDir, true)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cfg.EntityName, err = prompt.PromptString("Entity name (optional)", cfg.EntityName, false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Save configuration
|
||||
if err := cfg.Save(); err != nil {
|
||||
prompt.PrintError(fmt.Sprintf("Failed to save config: %v", err))
|
||||
// Don't fail, just warn
|
||||
} else {
|
||||
prompt.PrintSuccess("Configuration saved")
|
||||
}
|
||||
|
||||
// Connect to database
|
||||
prompt.PrintHeader("Connecting to Database")
|
||||
|
||||
dbClient, err := database.NewClient(database.Config{
|
||||
Host: cfg.DBHost,
|
||||
Port: cfg.DBPort,
|
||||
Database: cfg.DBName,
|
||||
Schema: cfg.DBSchema,
|
||||
User: cfg.DBUser,
|
||||
Password: cfg.DBPassword,
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("database connection failed: %w", err)
|
||||
}
|
||||
defer dbClient.Close()
|
||||
|
||||
prompt.PrintSuccess(fmt.Sprintf("Connected to %s@%s:%d/%s", cfg.DBUser, cfg.DBHost, cfg.DBPort, cfg.DBName))
|
||||
|
||||
// Check if table exists
|
||||
exists, err := dbClient.TableExists(cfg.DBTable)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to check table existence: %w", err)
|
||||
}
|
||||
if !exists {
|
||||
return fmt.Errorf("table '%s' does not exist in schema '%s'", cfg.DBTable, cfg.DBSchema)
|
||||
}
|
||||
|
||||
prompt.PrintSuccess(fmt.Sprintf("Found table '%s'", cfg.DBTable))
|
||||
|
||||
// Introspect table
|
||||
prompt.PrintHeader("Introspecting Table")
|
||||
|
||||
tableInfo, err := dbClient.IntrospectTable(cfg.DBTable)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to introspect table: %w", err)
|
||||
}
|
||||
|
||||
prompt.PrintSuccess(fmt.Sprintf("Found %d columns", len(tableInfo.Columns)))
|
||||
prompt.PrintSuccess(fmt.Sprintf("Found %d foreign keys", len(tableInfo.ForeignKeys)))
|
||||
prompt.PrintSuccess(fmt.Sprintf("Found %d enum types", len(tableInfo.EnumTypes)))
|
||||
|
||||
// Create generation context
|
||||
ctx := generator.NewContext(tableInfo, cfg.EntityName)
|
||||
|
||||
// Create output directory
|
||||
moduleName := naming.SingularizeTableName(cfg.DBTable)
|
||||
moduleDir := filepath.Join(cfg.OutputDir, moduleName)
|
||||
|
||||
if err := os.MkdirAll(moduleDir, 0755); err != nil {
|
||||
return fmt.Errorf("failed to create output directory: %w", err)
|
||||
}
|
||||
|
||||
prompt.PrintSuccess(fmt.Sprintf("Created directory: %s", moduleDir))
|
||||
|
||||
// Generate files
|
||||
prompt.PrintHeader("Generating Files")
|
||||
|
||||
files := map[string]func(*generator.Context) (string, error){
|
||||
"table.py": generator.GenerateTable,
|
||||
"model.py": generator.GenerateModel,
|
||||
"filter.py": generator.GenerateFilter,
|
||||
"load_options.py": generator.GenerateLoadOptions,
|
||||
"repository.py": generator.GenerateRepository,
|
||||
"manager.py": generator.GenerateManager,
|
||||
"factory.py": generator.GenerateFactory,
|
||||
"mapper.py": generator.GenerateMapper,
|
||||
"__init__.py": generator.GenerateInit,
|
||||
}
|
||||
|
||||
// Add enum.py if there are enum types
|
||||
if len(tableInfo.EnumTypes) > 0 {
|
||||
files["enum.py"] = generator.GenerateEnum
|
||||
}
|
||||
|
||||
// Generate and write each file
|
||||
for filename, genFunc := range files {
|
||||
content, err := genFunc(ctx)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to generate %s: %w", filename, err)
|
||||
}
|
||||
|
||||
filePath := filepath.Join(moduleDir, filename)
|
||||
if err := os.WriteFile(filePath, []byte(content), 0644); err != nil {
|
||||
return fmt.Errorf("failed to write %s: %w", filename, err)
|
||||
}
|
||||
|
||||
prompt.PrintSuccess(fmt.Sprintf("Generated %s", filename))
|
||||
}
|
||||
|
||||
// Print summary
|
||||
prompt.PrintHeader("Summary")
|
||||
fmt.Printf("\n")
|
||||
fmt.Printf(" Entity name: %s\n", color.GreenString(ctx.EntityName))
|
||||
fmt.Printf(" Module name: %s\n", color.GreenString(ctx.ModuleName))
|
||||
fmt.Printf(" Output dir: %s\n", color.GreenString(moduleDir))
|
||||
fmt.Printf(" Files: %s\n", color.GreenString("%d files generated", len(files)))
|
||||
fmt.Printf("\n")
|
||||
|
||||
success := color.New(color.FgGreen, color.Bold)
|
||||
success.Println("✓ Code generation completed successfully!")
|
||||
fmt.Println()
|
||||
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user