234 lines
		
	
	
		
			6.3 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			234 lines
		
	
	
		
			6.3 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| /*
 | |
| Copyright © 2022 Matthieu Derasse <git@derasse.fr>
 | |
| */
 | |
| 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 := strings.ToLower(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("Name of the team:")
 | |
| 	config.ProjectContact.Name = input.String(true)
 | |
| 
 | |
| 	log.Info("Mail address of the developer team:")
 | |
| 	config.ProjectContact.Email = input.Mail(true)
 | |
| 
 | |
| 	log.Info("URL of the contact information 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 with main branch")
 | |
| 
 | |
| 	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
 | |
| 	}
 | |
| 
 | |
| 	gitcheckout := exec.Command("git", "checkout", "-b", "main")
 | |
| 	_, err = gitcheckout.Output()
 | |
| 	if err != nil {
 | |
| 		log.Errorf("Fail to git checkout -b main. 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
 | |
| 	}
 | |
| 
 | |
| 	// 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
 | |
| 	}
 | |
| 
 | |
| 	// 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
 | |
| 	}
 | |
| 
 | |
| 	// Generate Launcher
 | |
| 	log.Info("Generating Launcher")
 | |
| 	err = apiType.GenerateLauncher(projectDirPath, config)
 | |
| 	if err != nil {
 | |
| 		log.Errorf("Fail to generate launcher.sh. The following error happen: %s", err.Error())
 | |
| 		return
 | |
| 	}
 | |
| }
 |