gouick/cmd/init.go
Matthieu 'JP' DERASSE cda86019bb
All checks were successful
continuous-integration/drone/push Build is passing
feat(go-swagger): Allow generate launcher makefile and readme. Refactoring
2022-09-20 21:49:37 +00:00

220 lines
5.9 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 := 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
}
}