/* Copyright © 2022 Matthieu Derasse */ package cmd import ( "os" "os/exec" "path/filepath" "strings" "github.com/juju/errors" "github.com/spf13/cobra" "git.home.m-and-m.ovh/mderasse/gouick/helpers" "git.home.m-and-m.ovh/mderasse/gouick/helpers/api_types" "git.home.m-and-m.ovh/mderasse/gouick/helpers/input" "git.home.m-and-m.ovh/mderasse/gouick/models" log "github.com/sirupsen/logrus" ) // initCmd represents the init command. var initCmd = &cobra.Command{ Use: "init", Short: "Initialize a new project", Long: `Initialize a new project by creating a new directory and: - Initialize a Git Repository - Create a Go-Swagger Struct - Add default routes - Generate the API. That command is Interactive or can be control through args`, Run: runInitAction, } func init() { rootCmd.AddCommand(initCmd) } // runInitAction will init a project. func runInitAction(cmd *cobra.Command, args []string) { log.Debugf("Starting command Init") log.Debugf("Checking dependencies") if !checkDependencies() { return } // Get current path currentPath, err := os.Getwd() if err != nil { log.Errorf("Fail to get current path. The following error happen: %s", err.Error()) return } log.Debugf("Working in directory: %s", currentPath) // Check if we are in gouick directory log.Debug("Checking if we are in the same directory as Gouick") isGouickDir, err := helpers.IsGouickDirectory(currentPath) if err != nil { log.Errorf("Fail to check if we are in gouick directory. The following error happen: %s", err.Error()) return } if isGouickDir { log.Error("You cannot initialize a new project in the same dir than gouick\nGouick should be added to your path") return } // Check if we are in a gouick project log.Debug("Checking if we are in a gouick project") isGouickProject, err := helpers.IsGouickProject(currentPath) if err != nil { log.Errorf("Fail to check if we are in a gouick project. The following error happen: %s", err.Error()) return } if isGouickProject { log.Error("You cannot initialize a new project in an already gouick project") return } // let's start to work on project configuration config := &models.Config{} // ask which API type we want to use. possibleAPITypes := make([]string, 0) for _, apiType := range models.GetListOfAPITypeName() { possibleAPITypes = append(possibleAPITypes, string(apiType)) } log.Infof("Which kind of API do you want to init (possible values: %s)", strings.Join(possibleAPITypes, ", ")) apiTypeName := input.APITypeName(true) log.Debugf("Using api type : %s", string(apiTypeName)) apiType, err := api_types.GetAPIType(apiTypeName) if err != nil { log.Error("Impossible to load that API Type generator") return } config.ProjectType = apiTypeName log.Debug("Check before init for the selected API type") err = apiType.CheckInitialize() if err != nil && !errors.Is(err, errors.NotImplemented) { log.Errorf("Impossible to initialize the project. The following error happen: %s", err.Error()) return } // ask project directory log.Info("Name of the project directory:") projectDirectory := input.Alphanumerical(true) // ask project name log.Info("Name of the project:") config.ProjectName = input.AlphanumericalAndSpace(true) // ask project description log.Info("Description of the project:") config.ProjectDescription = input.String(true) // ask project contact config.ProjectContact = models.ProjectContactStruct{} log.Info("Mail address of the developer team:") config.ProjectContact.Email = input.Mail(true) log.Info("Name of the team:") config.ProjectContact.Name = input.String(true) log.Info("URL of the contact informatino of the team:") config.ProjectContact.URL = input.String(false) // launch GetInitializeUserInput from selected api type log.Debug("Get user input for the selected API type") config, err = apiType.GetInitializeUserInput(config) if err != nil && !errors.Is(err, errors.NotImplemented) { log.Errorf("Fail to get all the required input. The following error happen: %s", err.Error()) return } projectDirPath := filepath.Join(currentPath, projectDirectory) log.Debugf("Our project directory path is: %s", projectDirPath) // create project directory log.Infof("Creating project directory") dirCreated, err := helpers.CheckAndCreateDir(projectDirPath) if err != nil { log.Errorf("Fail to create project directory. The following error happen: %s", err.Error()) return } if !dirCreated { log.Error("A directory already exist with your project directory name") return } // Move to project directory. log.Infof("Moving to the project directory: %s", projectDirectory) err = os.Chdir(projectDirPath) if err != nil { log.Errorf("Fail to move to project directory. The following error happen: %s", err.Error()) return } // Execute git init. log.Info("Initializing Git") gitinit := exec.Command("git", "init") _, err = gitinit.Output() if err != nil { log.Errorf("Fail to git init. The following error happen: %s", err.Error()) return } log.Info("Creating gouick configuration file") err = helpers.WriteConfig(projectDirPath, config) if err != nil { log.Errorf("Fail to write configuration. The following error happen: %s", err.Error()) return } // Generate Makefile log.Info("Generating Makefile") err = apiType.GenerateMakefile(projectDirPath, config) if err != nil { log.Errorf("Fail to generate Makefile. The following error happen: %s", err.Error()) return } // Generate Readme log.Info("Generating Readme") err = apiType.GenerateReadme(projectDirPath, config) if err != nil { log.Errorf("Fail to generate Readme.md. The following error happen: %s", err.Error()) return } // Create API Skeleton log.Info("Creating API skeleton") err = apiType.CreateProjectSkeleton(projectDirPath, config) if err != nil { log.Errorf("Fail to create the project skeleton. The following error happen: %s", err.Error()) return } }