package commands import ( "fmt" "os/exec" "os" "time" "path/filepath" "datasmith/utils" "datasmith/templates" ) func InitProject(name string, dbType string) { utils.PromptIfEmpty(&name, "Enter the name of the project: ") slug := utils.Slugify(name) // Check if datasmith.yaml already exists in the directory configFilePath := filepath.Join(slug, "datasmith.yaml") if _, err := os.Stat(configFilePath); err == nil { fmt.Printf("Error: A datasmith.yaml file already exists in the directory '%s'. Initialization aborted.\n", slug) return } else if !os.IsNotExist(err) { fmt.Printf("Error checking datasmith.yaml file: %v\n", err) return } if dbType == "" { dbType = promptForDbType() } fmt.Printf("Initializing new project structure in '%s' with database type '%s'\n", slug, dbType) // Create project directories createProjectDirs(slug) // Create README.md file from template createReadmeFile(slug, name, dbType) // Create CHANGELOG.md file from template createChangelogFile(slug) // Create datasmith.yaml file from template createConfigFile(slug, name, dbType) // Create an empty database.dbml file createDBMLFile(slug) // Create LICENSE.md file from template createLicenseFile(slug, name) // Create CONTRIBUTING.md file from template createContributingFile(slug) // Create .gitignore file from template createGitignoreFile(slug) // Create .dockerignore file from template createDockerignoreFile(slug) // Create Containerfile from template based on dbType createContainerfile(slug, dbType) // Create .gitlab-ci.yml file from template based on dbType createGitlabCiFile(slug, dbType) // Create generate_db_tests.sh script from template createGenerateDbTestsScript(slug) // Create sqlfluff file from template createSqlfluffFile(slug) // Create import-sql.sh script from template based on dbType createImportSqlScript(slug, dbType) // Create k8s/persistentvolumeclaim.template.yaml file from template createK8sPersistentVolumeFile(slug) // Create k8s/persistentvolumeclaim.template.yaml file from template createK8sPersistentVolumeClaimFile(slug) // Create k8s/service.template.yaml file from template createK8sServiceFile(slug) // Create k8s/deployment.template.yaml file from template based on dbType createK8sDeploymentFile(slug, dbType) fmt.Printf("Initialized new project structure in '%s'\n", slug) fmt.Println("Initializing Git repository...") cmd := exec.Command("git", "init", slug) cmd.Run() } // promptForDbType prompts the user to select a database type func promptForDbType() string { options := []utils.MenuOption{ {Display: "MySQL (default)", Value: "mysql"}, {Display: "PostgreSQL", Value: "postgres"}, } dbType, err := utils.SelectMenu(options, "Select database type:") if err != nil { fmt.Println("Error:", err) os.Exit(1) } return dbType } // createProjectDirs creates the necessary project directories func createProjectDirs(projectName string) { dirs := []string{"k8s", "sql"} for _, dir := range dirs { path := filepath.Join(projectName, dir) if err := os.MkdirAll(path, os.ModePerm); err != nil { fmt.Printf("Error creating directory '%s': %v\n", path, err) } else { fmt.Printf("Created directory: %s\n", path) } } } // createReadmeFile creates the README.md file from template func createReadmeFile(projectDir, projectName, dbType string) { data := map[string]interface{}{ "Name": projectName, "DbType": dbType, } err := templates.CreateFileFromTemplate(projectDir, "", "README.md", "README.md", data) if err != nil { fmt.Printf("Error creating README.md file: %v\n", err) } else { fmt.Printf("Created file: %s/README.md\n", projectDir) } } // createChangelogFile creates the CHANGELOG.md file from template func createChangelogFile(projectDir string) { data := map[string]interface{}{ "Date": time.Now().Format("2006-01-02"), } err := templates.CreateFileFromTemplate(projectDir, "", "CHANGELOG.md", "CHANGELOG.md", data) if err != nil { fmt.Printf("Error creating CHANGELOG.md file: %v\n", err) } else { fmt.Printf("Created file: %s/CHANGELOG.md\n", projectDir) } } // createConfigFile creates the datasmith.yaml file from template func createConfigFile(projectDir, projectName, dbType string) { data := map[string]interface{}{ "Name": projectName, "CreatedAt": time.Now().Format(time.RFC3339), "DbType": dbType, } err := templates.CreateFileFromTemplate(projectDir, "", "datasmith.yaml", "datasmith.yaml", data) if err != nil { fmt.Printf("Error creating datasmith.yaml file: %v\n", err) } else { fmt.Printf("Created file: %s/datasmith.yaml\n", projectDir) } } // createDBMLFile creates an empty database.dbml file in the project directory func createDBMLFile(projectDir string) { dbmlFilePath := filepath.Join(projectDir, "database.dbml") file, err := os.Create(dbmlFilePath) if err != nil { fmt.Printf("Error creating database.dbml file: %v\n", err) return } defer file.Close() fmt.Printf("Created file: %s/database.dbml\n", projectDir) } // createLicenseFile creates the LICENSE.md file from template func createLicenseFile(projectDir, projectName string) { data := map[string]interface{}{ "Name": projectName, "Year": time.Now().Year(), } err := templates.CreateFileFromTemplate(projectDir, "", "LICENSE.md", "LICENSE.md", data) if err != nil { fmt.Printf("Error creating LICENSE.md file: %v\n", err) } else { fmt.Printf("Created file: %s/LICENSE.md\n", projectDir) } } // createContributingFile creates the CONTRIBUTING.md file from template func createContributingFile(projectDir string) { err := templates.CreateFileFromTemplate(projectDir, "", "CONTRIBUTING.md", "CONTRIBUTING.md", nil) if err != nil { fmt.Printf("Error creating CONTRIBUTING.md file: %v\n", err) } else { fmt.Printf("Created file: %s/CONTRIBUTING.md\n", projectDir) } } // createGitignoreFile creates the .gitignore file from template func createGitignoreFile(projectDir string) { err := templates.CreateFileFromTemplate(projectDir, "", ".gitignore", "gitignore", nil) if err != nil { fmt.Printf("Error creating .gitignore file: %v\n", err) } else { fmt.Printf("Created file: %s/.gitignore\n", projectDir) } } // createDockerignoreFile creates the .dockerignore file from template func createDockerignoreFile(projectDir string) { err := templates.CreateFileFromTemplate(projectDir, "", ".dockerignore", "dockerignore", nil) if err != nil { fmt.Printf("Error creating .dockerignore file: %v\n", err) } else { fmt.Printf("Created file: %s/.dockerignore\n", projectDir) } } // createContainerfile creates the Containerfile from the appropriate template func createContainerfile(projectDir, dbType string) { templateFile := "Containerfile.mysql" if dbType == "postgres" { templateFile = "Containerfile.postgres" } err := templates.CreateFileFromTemplate(projectDir, "", "Containerfile", templateFile, nil) if err != nil { fmt.Printf("Error creating Containerfile: %v\n", err) } else { fmt.Printf("Created file: %s/Containerfile\n", projectDir) } } // createGitlabCiFile creates the .gitlab-ci.yml file from the appropriate template func createGitlabCiFile(projectDir, dbType string) { templateFile := "gitlab-ci.mysql.yaml" if dbType == "postgres" { templateFile = "gitlab-ci.postgres.yaml" } err := templates.CreateFileFromTemplate(projectDir, "", ".gitlab-ci.yml", templateFile, nil) if err != nil { fmt.Printf("Error creating .gitlab-ci.yml file: %v\n", err) } else { fmt.Printf("Created file: %s/.gitlab-ci.yml\n", projectDir) } } // createGenerateDbTestsScript creates the generate_db_tests.sh script from template func createGenerateDbTestsScript(projectDir string) { err := templates.CreateFileFromTemplate(projectDir, "", "generate_db_tests.sh", "generate_db_tests.sh", nil) if err != nil { fmt.Printf("Error creating generate_db_tests.sh script: %v\n", err) } else { fmt.Printf("Created file: %s/generate_db_tests.sh\n", projectDir) } } // createSqlfluffFile creates the sqlfluff configuration file from template func createSqlfluffFile(projectDir string) { err := templates.CreateFileFromTemplate(projectDir, "", "sqlfluff", "sqlfluff", nil) if err != nil { fmt.Printf("Error creating sqlfluff file: %v\n", err) } else { fmt.Printf("Created file: %s/sqlfluff\n", projectDir) } } // createImportSqlScript creates the import-sql.sh script from the appropriate template func createImportSqlScript(projectDir, dbType string) { templateFile := "import-sql.mysql" if dbType == "postgres" { templateFile = "import-sql.postgres" } err := templates.CreateFileFromTemplate(projectDir, "", "import-sql.sh", templateFile, nil) if err != nil { fmt.Printf("Error creating import-sql.sh script: %v\n", err) } else { fmt.Printf("Created file: %s/import-sql.sh\n", projectDir) } } // createK8sPersistentVolumeClaimFile creates the k8s/persistentVolume.template.yaml file from template func createK8sPersistentVolumeFile(projectDir string) { err := templates.CreateFileFromTemplate(projectDir, "k8s", "persistentVolume.template.yaml", "k8s/persistentVolume.template.yaml", nil) if err != nil { fmt.Printf("Error creating k8s/persistentVolume.template.yaml file: %v\n", err) } else { fmt.Printf("Created file: %s/k8s/persistentVolume.template.yaml\n", projectDir) } } // createK8sPersistentVolumeClaimFile creates the k8s/persistentVolumeClaim.template.yaml file from template func createK8sPersistentVolumeClaimFile(projectDir string) { err := templates.CreateFileFromTemplate(projectDir, "k8s", "persistentVolumeClaim.template.yaml", "k8s/persistentVolumeClaim.template.yaml", nil) if err != nil { fmt.Printf("Error creating k8s/persistentVolumeClaim.template.yaml file: %v\n", err) } else { fmt.Printf("Created file: %s/k8s/persistentVolumeClaim.template.yaml\n", projectDir) } } // createK8sPerviceFile creates the k8s/service.template.yaml file from template func createK8sServiceFile(projectDir string) { err := templates.CreateFileFromTemplate(projectDir, "k8s", "service.template.yaml", "k8s/service.template.yaml", nil) if err != nil { fmt.Printf("Error creating k8s/service.template.yaml file: %v\n", err) } else { fmt.Printf("Created file: %s/k8s/service.template.yaml\n", projectDir) } } // createK8sDeploymentFile creates the k8s/deployment.template.yaml file from the appropriate template func createK8sDeploymentFile(projectDir, dbType string) { templateFile := "k8s/deployment.mysql.template.yaml" if dbType == "postgres" { templateFile = "k8s/deployment.postgres.template.yaml" } err := templates.CreateFileFromTemplate(projectDir, "k8s", "deployment.template.yaml", templateFile, nil) if err != nil { fmt.Printf("Error creating k8s/deployment.template.yaml file: %v\n", err) } else { fmt.Printf("Created file: %s/k8s/deployment.template.yaml\n", projectDir) } } // Help returns the help information for the init command func InitHelp() string { return "init [name] [--type mysql|postgres] : Create a new project with the specified name and database type." }