fix(lint): Continue to apply linter recommandation
Some checks failed
continuous-integration/drone/push Build is failing

This commit is contained in:
Matthieu 'JP' DERASSE 2022-08-03 11:17:15 +00:00
parent 101ca9a79c
commit 660a4ef162
Signed by: mderasse
GPG Key ID: 55141C777B16A705
35 changed files with 187 additions and 159 deletions

View File

@ -74,7 +74,7 @@ linters:
- goconst # finds repeated strings that could be replaced by a constant - goconst # finds repeated strings that could be replaced by a constant
- godot - godot
- godox # tool for detection of FIXME, TODO and other comment keywords - godox # tool for detection of FIXME, TODO and other comment keywords
- gofumpt - gofmt
- goimports # Goimports does everything that gofmt does. Additionally it checks unused imports - goimports # Goimports does everything that gofmt does. Additionally it checks unused imports
- gomoddirectives # manage the use of 'replace', 'retract', and 'excludes' directives in go.mod. - gomoddirectives # manage the use of 'replace', 'retract', and 'excludes' directives in go.mod.
- gomodguard # check for blocked dependencies - gomodguard # check for blocked dependencies

View File

@ -1,6 +1,3 @@
# Gouick (name TBD) # Gouick
Only tested on Linux [![Build Status](https://drone.home.m-and-m.ovh/api/badges/mderasse/gouick/status.svg?ref=refs/heads/main)](https://drone.home.m-and-m.ovh/mderasse/gouick)
## Todo
- Implement for MacOS & Windows

View File

@ -10,14 +10,13 @@ import (
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
// generateCmd represents the generate command // generateCmd represents the generate command.
var generateCmd = &cobra.Command{ var generateCmd = &cobra.Command{
Use: "generate", Use: "generate",
Short: "Generate all the files (API, DB, ...)", Short: "Generate all the files (API, DB, ...)",
Long: `Generate will automatically create all the files of the Project. Long: `Generate will automatically create all the files of the Project.
You can also generate files for each 'modules' by using the command bellows`, You can also generate files for each 'modules' by using the command bellows`,
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
fmt.Println("generate called") fmt.Println("generate called")
}, },
} }

View File

@ -10,7 +10,7 @@ import (
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
// apiCmd represents the api command // apiCmd represents the api command.
var apiCmd = &cobra.Command{ var apiCmd = &cobra.Command{
Use: "api", Use: "api",
Short: "Generate Go-Swagger Files and Controllers", Short: "Generate Go-Swagger Files and Controllers",

View File

@ -10,7 +10,7 @@ import (
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
// dbCmd represents the db command // dbCmd represents the db command.
var dbCmd = &cobra.Command{ var dbCmd = &cobra.Command{
Use: "db", Use: "db",
Short: "Generate Database Struct from pkg/dbmodels/schema.yaml", Short: "Generate Database Struct from pkg/dbmodels/schema.yaml",

View File

@ -10,7 +10,7 @@ import (
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
// dockerCmd represents the docker command // dockerCmd represents the docker command.
var dockerCmd = &cobra.Command{ var dockerCmd = &cobra.Command{
Use: "docker", Use: "docker",
Short: "Generate Dockerfile for API & Workers", Short: "Generate Dockerfile for API & Workers",

View File

@ -10,7 +10,7 @@ import (
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
// helmCmd represents the helm command // helmCmd represents the helm command.
var helmCmd = &cobra.Command{ var helmCmd = &cobra.Command{
Use: "helm", Use: "helm",
Short: "Generate Kubernetes Helm chart for API & Workers", Short: "Generate Kubernetes Helm chart for API & Workers",

View File

@ -8,7 +8,7 @@ import (
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
// helpCmd represents the help command // helpCmd represents the help command.
var helpCmd = &cobra.Command{ var helpCmd = &cobra.Command{
Use: "help", Use: "help",
Short: "Show that help", Short: "Show that help",

View File

@ -10,7 +10,7 @@ import (
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
// launcherCmd represents the launcher command // launcherCmd represents the launcher command.
var launcherCmd = &cobra.Command{ var launcherCmd = &cobra.Command{
Use: "launcher", Use: "launcher",
Short: "Generate Launcher Bash script", Short: "Generate Launcher Bash script",

View File

@ -10,7 +10,7 @@ import (
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
// makefileCmd represents the makefile command // makefileCmd represents the makefile command.
var makefileCmd = &cobra.Command{ var makefileCmd = &cobra.Command{
Use: "makefile", Use: "makefile",
Short: "Generate Makefile", Short: "Generate Makefile",

View File

@ -19,7 +19,7 @@ import (
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
) )
// initCmd represents the init command // initCmd represents the init command.
var initCmd = &cobra.Command{ var initCmd = &cobra.Command{
Use: "init", Use: "init",
Short: "Initialize a new project", Short: "Initialize a new project",
@ -39,11 +39,10 @@ func init() {
// runInitAction // runInitAction
// Steps: // Steps:
// 1 - Check that we have the dependencies // 1 - Check that we have the dependencies.
// 2 - Check that we are not in project directory // 2 - Check that we are not in project directory.
// 3 - Ask info to the user // 3 - Ask info to the user.
func runInitAction(cmd *cobra.Command, args []string) { func runInitAction(cmd *cobra.Command, args []string) {
log.Debugf("Starting command Init") log.Debugf("Starting command Init")
log.Debugf("Checking dependencies") log.Debugf("Checking dependencies")
@ -90,7 +89,7 @@ func runInitAction(cmd *cobra.Command, args []string) {
} }
// ask which API type we want to use // ask which API type we want to use
var possibleAPITypes []string possibleAPITypes := make([]string, 0)
for _, apiType := range models.GetListOfAPITypeName() { for _, apiType := range models.GetListOfAPITypeName() {
possibleAPITypes = append(possibleAPITypes, string(apiType)) possibleAPITypes = append(possibleAPITypes, string(apiType))
} }

View File

@ -13,7 +13,8 @@ import (
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
) )
var version = "0.0.1" const version = "0.0.1"
var verbose = false var verbose = false
var acceptAll = false var acceptAll = false
var dependencyList = []dependencies.DependencyInterface{ var dependencyList = []dependencies.DependencyInterface{
@ -22,7 +23,7 @@ var dependencyList = []dependencies.DependencyInterface{
dependencies.Swagger{}, dependencies.Swagger{},
} }
// rootCmd represents the base command when called without any subcommands // rootCmd represents the base command when called without any subcommands.
var rootCmd = &cobra.Command{ var rootCmd = &cobra.Command{
Use: "boot", Use: "boot",
Short: "Boot is a toolbox app to bootstrap quickly a Go-Swagger API", Short: "Boot is a toolbox app to bootstrap quickly a Go-Swagger API",
@ -32,7 +33,7 @@ It will:
- Auto-Update - Auto-Update
- Download dependencies (go-swagger, ...) - Download dependencies (go-swagger, ...)
- Initialize an API with default middlewares - Initialize an API with default middlewares
- Generate Models / Controlers - Generate Models / Controllers
- Generate Database structs - Generate Database structs
- ....`, - ....`,
@ -46,8 +47,7 @@ It will:
// Execute adds all child commands to the root command and sets flags appropriately. // Execute adds all child commands to the root command and sets flags appropriately.
// This is called by main.main(). It only needs to happen once to the rootCmd. // This is called by main.main(). It only needs to happen once to the rootCmd.
func Execute() { func Execute() {
err := rootCmd.Execute() if err := rootCmd.Execute(); err != nil {
if err != nil {
os.Exit(1) os.Exit(1)
} }
} }
@ -57,11 +57,9 @@ func init() {
rootCmd.PersistentFlags().BoolVarP(&acceptAll, "yes", "y", false, "accept all change, disable interactive process") rootCmd.PersistentFlags().BoolVarP(&acceptAll, "yes", "y", false, "accept all change, disable interactive process")
} }
// checkDependencies // checkDependencies will go through all the dependencies a check if they are installed and respect minimum version.
func checkDependencies() bool { func checkDependencies() bool {
for _, dependency := range dependencyList { for _, dependency := range dependencyList {
isSupported, err := dependency.IsVersionSupported() isSupported, err := dependency.IsVersionSupported()
if err != nil { if err != nil {
log.Errorf("Fail to check %s version. The following error happen: %s", dependency.GetName(), err.Error()) log.Errorf("Fail to check %s version. The following error happen: %s", dependency.GetName(), err.Error())

View File

@ -10,7 +10,7 @@ import (
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
// testCmd represents the test command // testCmd represents the test command.
var testCmd = &cobra.Command{ var testCmd = &cobra.Command{
Use: "test", Use: "test",
Short: "Launch Test", Short: "Launch Test",

View File

@ -12,7 +12,7 @@ import (
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
) )
// upgradeCmd represents the upgrade command // upgradeCmd represents the upgrade command.
var upgradeCmd = &cobra.Command{ var upgradeCmd = &cobra.Command{
Use: "upgrade", Use: "upgrade",
Short: "Upgrade all development dependencies", Short: "Upgrade all development dependencies",
@ -29,11 +29,9 @@ func init() {
} }
func runUpgradeAction(cmd *cobra.Command, args []string) { func runUpgradeAction(cmd *cobra.Command, args []string) {
log.Debug("Starting Upgrade command") log.Debug("Starting Upgrade command")
for _, dependency := range dependencyList { for _, dependency := range dependencyList {
log.Debugf("Checking if dependency %s is supported", dependency.GetName()) log.Debugf("Checking if dependency %s is supported", dependency.GetName())
isSupported, err := dependency.IsVersionSupported() isSupported, err := dependency.IsVersionSupported()
@ -81,7 +79,6 @@ func runUpgradeAction(cmd *cobra.Command, args []string) {
log.Infof("Where do you want to install %s ?", dependency.GetName()) log.Infof("Where do you want to install %s ?", dependency.GetName())
installDirectory = helpers.PathInput() installDirectory = helpers.PathInput()
} }
} else { } else {
log.Infof("Installing %s in the following directory: %s", dependency.GetName(), installDirectory) log.Infof("Installing %s in the following directory: %s", dependency.GetName(), installDirectory)
} }
@ -91,7 +88,7 @@ func runUpgradeAction(cmd *cobra.Command, args []string) {
// check if the path is ok, else ask user for new path if we are in a interactive mode, else stop // check if the path is ok, else ask user for new path if we are in a interactive mode, else stop
_, err = helpers.CheckAndCreateDir(installDirectory) _, err = helpers.CheckAndCreateDir(installDirectory)
if err != nil { if err != nil {
log.Errorf("Impossible to create the instalation directory for %s", dependency.GetName()) log.Errorf("Impossible to create the installation directory for %s", dependency.GetName())
if acceptAll { if acceptAll {
return return
} }

View File

@ -10,7 +10,7 @@ import (
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
// versionCmd represents the version command // versionCmd represents the version command.
var versionCmd = &cobra.Command{ var versionCmd = &cobra.Command{
Use: "version", Use: "version",
Short: "Show gouick version", Short: "Show gouick version",

View File

@ -9,6 +9,7 @@ import (
"git.home.m-and-m.ovh/mderasse/gouick/helpers/models" "git.home.m-and-m.ovh/mderasse/gouick/helpers/models"
) )
// GetAPIType will return the APIType object based on an APITypeName.
func GetAPIType(in models.APITypeName) (APITypeInterface, error) { func GetAPIType(in models.APITypeName) (APITypeInterface, error) {
if in == "" { if in == "" {
return nil, errors.BadRequestf("missing parameter") return nil, errors.BadRequestf("missing parameter")
@ -25,6 +26,8 @@ func GetAPIType(in models.APITypeName) (APITypeInterface, error) {
return go_swagger.APIType{}, nil return go_swagger.APIType{}, nil
case models.APITypeName_MOJOLICIOUS: case models.APITypeName_MOJOLICIOUS:
return mojolicious.APIType{}, nil return mojolicious.APIType{}, nil
case models.APITypeName_NULL:
break
} }
return nil, errors.NotFoundf("Unknown Api Type") return nil, errors.NotFoundf("Unknown Api Type")

View File

@ -1,5 +1,5 @@
package base package base
// APIType // APIType struct.
type APIType struct { type APIType struct {
} }

View File

@ -4,8 +4,7 @@ import (
"github.com/juju/errors" "github.com/juju/errors"
) )
// CheckInitialize // CheckInitialize will do preliminary check before initializing a new project.
func (a APIType) CheckInitialize() error { func (a APIType) CheckInitialize() error {
return errors.NotImplementedf("CheckInitialize not implemented for %s", a.GetName()) return errors.NotImplementedf("CheckInitialize not implemented for %s", a.GetName())
} }

View File

@ -4,6 +4,7 @@ import (
"git.home.m-and-m.ovh/mderasse/gouick/helpers/models" "git.home.m-and-m.ovh/mderasse/gouick/helpers/models"
) )
// GetName return the APITypeName of the APIType.
func (a APIType) GetName() models.APITypeName { func (a APIType) GetName() models.APITypeName {
return models.APITypeName_NULL return models.APITypeName_NULL
} }

View File

@ -6,7 +6,7 @@ import (
"github.com/juju/errors" "github.com/juju/errors"
) )
// GetInitializeUserInput will ask user to provide information that allow initialization of a project.
func (a APIType) GetInitializeUserInput(params *models.UserInputParams) (*models.UserInputParams, error) { func (a APIType) GetInitializeUserInput(params *models.UserInputParams) (*models.UserInputParams, error) {
return nil, errors.NotImplementedf("GetInitializeUserInput not implemented for %s", a.GetName()) return nil, errors.NotImplementedf("GetInitializeUserInput not implemented for %s", a.GetName())
} }

View File

@ -4,6 +4,7 @@ import (
"git.home.m-and-m.ovh/mderasse/gouick/helpers/models" "git.home.m-and-m.ovh/mderasse/gouick/helpers/models"
) )
// GetName return the APITypeName of the APIType.
func (a APIType) GetName() models.APITypeName { func (a APIType) GetName() models.APITypeName {
return models.APITypeName_GIN_GONIC return models.APITypeName_GIN_GONIC
} }

View File

@ -10,7 +10,7 @@ import (
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
) )
// CheckInitialize // CheckInitialize will do preliminary check before initializing a new project.
func (a APIType) CheckInitialize() error { func (a APIType) CheckInitialize() error {
log.Debugf("Starting %s check initialize", string(a.GetName())) log.Debugf("Starting %s check initialize", string(a.GetName()))

View File

@ -4,6 +4,7 @@ import (
"git.home.m-and-m.ovh/mderasse/gouick/helpers/models" "git.home.m-and-m.ovh/mderasse/gouick/helpers/models"
) )
// GetName return the APITypeName of the APIType.
func (a APIType) GetName() models.APITypeName { func (a APIType) GetName() models.APITypeName {
return models.APITypeName_GO_SWAGGER return models.APITypeName_GO_SWAGGER
} }

View File

@ -11,7 +11,7 @@ import (
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
) )
// GetInitializeUserInput // GetInitializeUserInput will ask user to provide information that allow initialization of a project.
func (a APIType) GetInitializeUserInput(params *models.UserInputParams) (*models.UserInputParams, error) { func (a APIType) GetInitializeUserInput(params *models.UserInputParams) (*models.UserInputParams, error) {
log.Debugf("Starting %s user input", a.GetName()) log.Debugf("Starting %s user input", a.GetName())

View File

@ -4,6 +4,7 @@ import (
"git.home.m-and-m.ovh/mderasse/gouick/helpers/models" "git.home.m-and-m.ovh/mderasse/gouick/helpers/models"
) )
// GetName return the APITypeName of the APIType.
func (a APIType) GetName() models.APITypeName { func (a APIType) GetName() models.APITypeName {
return models.APITypeName_MOJOLICIOUS return models.APITypeName_MOJOLICIOUS
} }

View File

@ -3,28 +3,29 @@ package dependencies
import ( import (
"os/exec" "os/exec"
"git.home.m-and-m.ovh/mderasse/gouick/helpers/models"
"github.com/juju/errors" "github.com/juju/errors"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
) )
// Git represent an empty struct respecting the DependencyInterface.
type Git struct{} type Git struct{}
// regroup all git dependencies function // regroup all git dependencies function
// GetName // GetName return the name of the dependency using DependencyName enum.
func (g Git) GetName() string { func (g Git) GetName() models.DependencyName {
return "Git" return models.DependencyName_GIT
} }
// GetMinimumVersion // GetMinimumVersion return the minimum version required for that dependency.
func (g Git) GetMinimumVersion() string { func (g Git) GetMinimumVersion() string {
return "0.0.0" return "0.0.0"
} }
// IsInstalled // IsInstalled check if the dependency is installed on the system.
func (g Git) IsInstalled() (bool, error) { func (g Git) IsInstalled() (bool, error) {
_, err := g.GetBinaryPath() _, err := g.GetBinaryPath()
if err != nil && !errors.Is(err, exec.ErrNotFound) { if err != nil && !errors.Is(err, exec.ErrNotFound) {
return false, errors.Trace(err) return false, errors.Trace(err)
@ -35,7 +36,7 @@ func (g Git) IsInstalled() (bool, error) {
return true, nil return true, nil
} }
// GetBinaryPath // GetBinaryPath will search for the binary and return the path if found.
func (g Git) GetBinaryPath() (string, error) { func (g Git) GetBinaryPath() (string, error) {
log.Debug("looking for git binary") log.Debug("looking for git binary")
@ -49,9 +50,8 @@ func (g Git) GetBinaryPath() (string, error) {
return path, nil return path, nil
} }
// GetVersion // GetVersion will find the current version of the dependency.
func (g Git) GetVersion() (string, error) { func (g Git) GetVersion() (string, error) {
isInstalled, err := g.IsInstalled() isInstalled, err := g.IsInstalled()
if err != nil { if err != nil {
return "", errors.Trace(err) return "", errors.Trace(err)
@ -64,9 +64,8 @@ func (g Git) GetVersion() (string, error) {
return "0.0.0", nil return "0.0.0", nil
} }
// IsVersionSupported // IsVersionSupported will compare the current version with the minimum expected version.
func (g Git) IsVersionSupported() (bool, error) { func (g Git) IsVersionSupported() (bool, error) {
isInstalled, err := g.IsInstalled() isInstalled, err := g.IsInstalled()
if err != nil { if err != nil {
return false, errors.Trace(err) return false, errors.Trace(err)
@ -78,32 +77,32 @@ func (g Git) IsVersionSupported() (bool, error) {
return true, nil return true, nil
} }
// CanBeInstalled // CanBeInstalled define if the dependency installation is handled by the app.
func (g Git) CanBeInstalled() bool { func (g Git) CanBeInstalled() bool {
return false return false
} }
// DescribeInstall // DescribeInstall will do nothing for that dependency.
func (g Git) DescribeInstall(path string) string { func (g Git) DescribeInstall(path string) string {
return "" return ""
} }
// Install // Install will do nothing for that dependency.
func (g Git) Install(path string) error { func (g Git) Install(path string) error {
return nil return nil
} }
// DescribePostInstall // DescribePostInstall will do nothing for that dependency.
func (g Git) DescribePostInstall(path string) string { func (g Git) DescribePostInstall(path string) string {
return "" return ""
} }
// PostInstall // PostInstall will do nothing for that dependency.
func (g Git) PostInstall(path string) error { func (g Git) PostInstall(path string) error {
return nil return nil
} }
// GetInstallDirectory // GetInstallDirectory will do nothing for that dependency.
func (g Git) GetInstallDirectory() (string, error) { func (g Git) GetInstallDirectory() (string, error) {
return "", nil return "", nil
} }

View File

@ -13,36 +13,37 @@ import (
"github.com/juju/errors" "github.com/juju/errors"
"git.home.m-and-m.ovh/mderasse/gouick/helpers" "git.home.m-and-m.ovh/mderasse/gouick/helpers"
"git.home.m-and-m.ovh/mderasse/gouick/helpers/models"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
) )
// minimum minor required for the app to work // minimumGolangVersion is the minimum minor required for the app to work.
const minimumGolangVersion = "1.18.4" const minimumGolangVersion = "1.18.4"
// installation directory for fresh install. // installation directory for fresh install.
// will be prefixed by $HOME // will be prefixed by $HOME.
const defaultGolangInstallDir = "/local/go" const defaultGolangInstallDir = "/local/go"
var regexGolangVersion = regexp.MustCompile(`^go version go(\d+\.\d+\.\d+)`) var regexGolangVersion = regexp.MustCompile(`^go version go(\d+\.\d+\.\d+)`)
// Golang represent an empty struct respecting the DependencyInterface.
type Golang struct{} type Golang struct{}
// regroup all golang dependencies function // regroup all golang dependencies function.
// GetName // GetName return the name of the dependency using DependencyName enum.
func (g Golang) GetName() string { func (g Golang) GetName() models.DependencyName {
return "Golang" return models.DependencyName_GOLANG
} }
// GetMinimumVersion // GetMinimumVersion return the minimum version required for that dependency.
func (g Golang) GetMinimumVersion() string { func (g Golang) GetMinimumVersion() string {
return minimumGolangVersion return minimumGolangVersion
} }
// IsInstalled // IsInstalled check if the dependency is installed on the system.
func (g Golang) IsInstalled() (bool, error) { func (g Golang) IsInstalled() (bool, error) {
_, err := g.GetBinaryPath() _, err := g.GetBinaryPath()
if err != nil && !errors.Is(err, exec.ErrNotFound) { if err != nil && !errors.Is(err, exec.ErrNotFound) {
return false, errors.Trace(err) return false, errors.Trace(err)
@ -53,7 +54,7 @@ func (g Golang) IsInstalled() (bool, error) {
return true, nil return true, nil
} }
// GetBinaryPath // GetBinaryPath will search for the binary and return the path if found.
func (g Golang) GetBinaryPath() (string, error) { func (g Golang) GetBinaryPath() (string, error) {
log.Debug("looking for golang binary") log.Debug("looking for golang binary")
@ -67,7 +68,7 @@ func (g Golang) GetBinaryPath() (string, error) {
return path, nil return path, nil
} }
// GetVersion // GetVersion will find the current version of the dependency.
func (g Golang) GetVersion() (string, error) { func (g Golang) GetVersion() (string, error) {
isInstalled, err := g.IsInstalled() isInstalled, err := g.IsInstalled()
@ -86,6 +87,7 @@ func (g Golang) GetVersion() (string, error) {
log.Debug("executing go version command") log.Debug("executing go version command")
//nolint:gosec // we trust the binary we are launching
cmd := exec.Command(binaryPath, "version") cmd := exec.Command(binaryPath, "version")
stdout, err := cmd.Output() stdout, err := cmd.Output()
if err != nil { if err != nil {
@ -103,9 +105,8 @@ func (g Golang) GetVersion() (string, error) {
return parseOutput[1], nil return parseOutput[1], nil
} }
// IsVersionSupported // IsVersionSupported will compare the current version with the minimum expected version.
func (g Golang) IsVersionSupported() (bool, error) { func (g Golang) IsVersionSupported() (bool, error) {
isInstalled, err := g.IsInstalled() isInstalled, err := g.IsInstalled()
if err != nil { if err != nil {
return false, errors.Trace(err) return false, errors.Trace(err)
@ -136,14 +137,13 @@ func (g Golang) IsVersionSupported() (bool, error) {
return true, nil return true, nil
} }
// CanBeInstalled // CanBeInstalled define if the dependency installation is handled by the app.
func (g Golang) CanBeInstalled() bool { func (g Golang) CanBeInstalled() bool {
return true return true
} }
// DescribeInstall // DescribeInstall will list the aciton that will be executed for the dependency update or installation.
func (g Golang) DescribeInstall(path string) string { func (g Golang) DescribeInstall(path string) string {
commands := []string{ commands := []string{
"The following commands will be executed", "The following commands will be executed",
fmt.Sprintf("rm -rf %s/* ", path), fmt.Sprintf("rm -rf %s/* ", path),
@ -153,9 +153,8 @@ func (g Golang) DescribeInstall(path string) string {
return strings.Join(commands, "\n") return strings.Join(commands, "\n")
} }
// Install // Install will install or update the dependency.
func (g Golang) Install(path string) error { func (g Golang) Install(path string) error {
err := helpers.RemoveDirectoryContent(path) err := helpers.RemoveDirectoryContent(path)
if err != nil { if err != nil {
log.Warnf("fail to delete content of directory %s", path) log.Warnf("fail to delete content of directory %s", path)
@ -170,7 +169,6 @@ func (g Golang) Install(path string) error {
// zip on windows, tar gz on other platform // zip on windows, tar gz on other platform
if runtime.GOOS == "windows" { if runtime.GOOS == "windows" {
log.Debug("Working on zip, Unzip") log.Debug("Working on zip, Unzip")
err = unZip(content, "go/", path) err = unZip(content, "go/", path)
@ -178,9 +176,7 @@ func (g Golang) Install(path string) error {
log.Warnf("fail to un-zip downloaded file from %s", downloadURL) log.Warnf("fail to un-zip downloaded file from %s", downloadURL)
return errors.Trace(err) return errors.Trace(err)
} }
} else { } else {
log.Debug("Working on tar gz, UnGzip & unTar") log.Debug("Working on tar gz, UnGzip & unTar")
gzipReader, err := unGzip(content) gzipReader, err := unGzip(content)
@ -199,9 +195,8 @@ func (g Golang) Install(path string) error {
return nil return nil
} }
// DescribePostInstall // DescribePostInstall will list the post installation action that will be executed.
func (g Golang) DescribePostInstall(path string) string { func (g Golang) DescribePostInstall(path string) string {
descriptions := []string{ descriptions := []string{
`For your environment to work correctly, we will add if needed the following environment variable to your .bashrc: `For your environment to work correctly, we will add if needed the following environment variable to your .bashrc:
@ -219,9 +214,8 @@ You will have to reopen a new terminal to apply the changes or execute the follo
return strings.Join(descriptions, "\n") return strings.Join(descriptions, "\n")
} }
// PostInstall // PostInstall will execute the post installation or update of the dependency.
func (g Golang) PostInstall(path string) error { func (g Golang) PostInstall(path string) error {
if runtime.GOOS == "windows" { if runtime.GOOS == "windows" {
log.Warnf("Unable to environement variable on windows. Please add it by yourself") log.Warnf("Unable to environement variable on windows. Please add it by yourself")
return nil return nil
@ -231,15 +225,13 @@ func (g Golang) PostInstall(path string) error {
"# Golang - Added by gouick", "# Golang - Added by gouick",
} }
gopath := os.Getenv("GOPATH")
createGoPath := false createGoPath := false
if gopath == "" { if os.Getenv("GOPATH") == "" {
lineBashRc = append(lineBashRc, "export GOPATH=\"$HOME/go\"") lineBashRc = append(lineBashRc, "export GOPATH=\"$HOME/go\"")
createGoPath = true createGoPath = true
} }
goroot := os.Getenv("GOROOT") if os.Getenv("GOROOT") == "" {
if goroot == "" {
lineBashRc = append(lineBashRc, fmt.Sprintf("export GOROOT=\"%s\"", path)) lineBashRc = append(lineBashRc, fmt.Sprintf("export GOROOT=\"%s\"", path))
} }
@ -265,12 +257,17 @@ func (g Golang) PostInstall(path string) error {
fh, err := os.OpenFile( fh, err := os.OpenFile(
filepath.Join(homeDir, ".bashrc"), filepath.Join(homeDir, ".bashrc"),
os.O_APPEND|os.O_CREATE|os.O_WRONLY, os.O_APPEND|os.O_CREATE|os.O_WRONLY,
0644, 0600,
) )
if err != nil { if err != nil {
return errors.Trace(err) return errors.Trace(err)
} }
defer fh.Close()
defer func() {
if err := fh.Close(); err != nil {
log.Errorf("Error closing file: %s", err)
}
}()
_, err = fh.WriteString( _, err = fh.WriteString(
fmt.Sprintf("\n\n%s\n", strings.Join(lineBashRc, "\n")), fmt.Sprintf("\n\n%s\n", strings.Join(lineBashRc, "\n")),
@ -281,7 +278,6 @@ func (g Golang) PostInstall(path string) error {
} }
if createGoPath { if createGoPath {
log.Debug("creating gopath directory") log.Debug("creating gopath directory")
_, err = helpers.CheckAndCreateDir(filepath.Join(homeDir, "go")) _, err = helpers.CheckAndCreateDir(filepath.Join(homeDir, "go"))
@ -295,9 +291,8 @@ func (g Golang) PostInstall(path string) error {
// GetInstallDirectory will try to find the current golang directory. If it doesn't exist or if it's in a // GetInstallDirectory will try to find the current golang directory. If it doesn't exist or if it's in a
// not userspace directory, it will provide the "default" // not userspace directory, it will provide the "default"
// It doesn't mean that the directory is "writable" // It doesn't mean that the directory is "writable".
func (g Golang) GetInstallDirectory() (string, error) { func (g Golang) GetInstallDirectory() (string, error) {
homeDir, err := os.UserHomeDir() homeDir, err := os.UserHomeDir()
if err != nil { if err != nil {
return "", errors.Trace(err) return "", errors.Trace(err)
@ -321,6 +316,7 @@ func (g Golang) GetInstallDirectory() (string, error) {
log.Debug("executing go env GOROOT command") log.Debug("executing go env GOROOT command")
//nolint:gosec // we trust the binary we are launching
cmd := exec.Command(binaryPath, "env", "GOROOT") cmd := exec.Command(binaryPath, "env", "GOROOT")
stdout, err := cmd.Output() stdout, err := cmd.Output()
if err != nil { if err != nil {
@ -336,10 +332,9 @@ func (g Golang) GetInstallDirectory() (string, error) {
} }
func (g Golang) getDownloadURL() string { func (g Golang) getDownloadURL() string {
if runtime.GOOS == "windows" { if runtime.GOOS == "windows" {
return fmt.Sprintf("https://dl.google.com/go/go%s.%s-%s.zip", minimumGolangVersion, runtime.GOOS, runtime.GOARCH) return fmt.Sprintf("https://dl.google.com/go/go%s.%s-%s.zip", minimumGolangVersion, runtime.GOOS, runtime.GOARCH)
} else { }
return fmt.Sprintf("https://dl.google.com/go/go%s.%s-%s.tar.gz", minimumGolangVersion, runtime.GOOS, runtime.GOARCH) return fmt.Sprintf("https://dl.google.com/go/go%s.%s-%s.tar.gz", minimumGolangVersion, runtime.GOOS, runtime.GOARCH)
} }
}

View File

@ -1,13 +1,15 @@
package dependencies package dependencies
// DependencyInterface import "git.home.m-and-m.ovh/mderasse/gouick/helpers/models"
// DependencyInterface is the interface that need to be respected for a dependency.
type DependencyInterface interface { type DependencyInterface interface {
CanBeInstalled() bool CanBeInstalled() bool
DescribeInstall(path string) string DescribeInstall(path string) string
DescribePostInstall(path string) string DescribePostInstall(path string) string
GetBinaryPath() (string, error) GetBinaryPath() (string, error)
GetInstallDirectory() (string, error) GetInstallDirectory() (string, error)
GetName() string GetName() models.DependencyName
GetMinimumVersion() string GetMinimumVersion() string
GetVersion() (string, error) GetVersion() (string, error)
Install(path string) error Install(path string) error

View File

@ -2,7 +2,7 @@ package dependencies
import ( import (
"fmt" "fmt"
"io/ioutil" "io"
"os" "os"
"os/exec" "os/exec"
"path/filepath" "path/filepath"
@ -10,38 +10,39 @@ import (
"runtime" "runtime"
"strings" "strings"
"git.home.m-and-m.ovh/mderasse/gouick/helpers/models"
"github.com/blang/semver" "github.com/blang/semver"
"github.com/juju/errors" "github.com/juju/errors"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
) )
// minimum minor required for the app to work // minimumGolangVersion is the minimum minor required for the app to work.
const minimumSwaggerVersion = "0.29.0" const minimumSwaggerVersion = "0.29.0"
// installation directory for fresh install. // installation directory for fresh install.
// will be prefixed by $HOME // will be prefixed by $HOME.
const defaultSwaggerInstallDir = "/bin" const defaultSwaggerInstallDir = "/bin"
var regexSwaggerVersion = regexp.MustCompile(`^version: v(\d+\.\d+\.\d+)`) var regexSwaggerVersion = regexp.MustCompile(`^version: v(\d+\.\d+\.\d+)`)
// Swagger represent an empty struct respecting the DependencyInterface.
type Swagger struct{} type Swagger struct{}
// regroup all swagger dependencies function // regroup all swagger dependencies function.
// GetName // GetName return the name of the dependency using DependencyName enum.
func (s Swagger) GetName() string { func (s Swagger) GetName() models.DependencyName {
return "Go Swagger" return models.DependencyName_GO_SWAGGER
} }
// GetMinimumVersion // GetMinimumVersion return the minimum version required for that dependency.
func (s Swagger) GetMinimumVersion() string { func (s Swagger) GetMinimumVersion() string {
return minimumSwaggerVersion return minimumSwaggerVersion
} }
// IsInstalled // IsInstalled check if the dependency is installed on the system.
func (s Swagger) IsInstalled() (bool, error) { func (s Swagger) IsInstalled() (bool, error) {
_, err := s.GetBinaryPath() _, err := s.GetBinaryPath()
if err != nil && !errors.Is(err, exec.ErrNotFound) { if err != nil && !errors.Is(err, exec.ErrNotFound) {
return false, errors.Trace(err) return false, errors.Trace(err)
@ -52,7 +53,7 @@ func (s Swagger) IsInstalled() (bool, error) {
return true, nil return true, nil
} }
// GetBinaryPath // GetBinaryPath will search for the binary and return the path if found.
func (s Swagger) GetBinaryPath() (string, error) { func (s Swagger) GetBinaryPath() (string, error) {
log.Debug("looking for swagger binary") log.Debug("looking for swagger binary")
@ -66,7 +67,7 @@ func (s Swagger) GetBinaryPath() (string, error) {
return path, nil return path, nil
} }
// GetVersion // GetVersion will find the current version of the dependency.
func (s Swagger) GetVersion() (string, error) { func (s Swagger) GetVersion() (string, error) {
isInstalled, err := s.IsInstalled() isInstalled, err := s.IsInstalled()
@ -85,6 +86,7 @@ func (s Swagger) GetVersion() (string, error) {
log.Debug("executing swagger version command") log.Debug("executing swagger version command")
//nolint:gosec // we trust the binary we are launching
cmd := exec.Command(binaryPath, "version") cmd := exec.Command(binaryPath, "version")
stdout, err := cmd.Output() stdout, err := cmd.Output()
if err != nil { if err != nil {
@ -102,9 +104,8 @@ func (s Swagger) GetVersion() (string, error) {
return parseOutput[1], nil return parseOutput[1], nil
} }
// IsVersionSupported // IsVersionSupported will compare the current version with the minimum expected version.
func (s Swagger) IsVersionSupported() (bool, error) { func (s Swagger) IsVersionSupported() (bool, error) {
isInstalled, err := s.IsInstalled() isInstalled, err := s.IsInstalled()
if err != nil { if err != nil {
return false, errors.Trace(err) return false, errors.Trace(err)
@ -135,14 +136,13 @@ func (s Swagger) IsVersionSupported() (bool, error) {
return true, nil return true, nil
} }
// CanBeInstalled // CanBeInstalled define if the dependency installation is handled by the app.
func (s Swagger) CanBeInstalled() bool { func (s Swagger) CanBeInstalled() bool {
return true return true
} }
// DescribeInstall // DescribeInstall will list the aciton that will be executed for the dependency update or installation.
func (s Swagger) DescribeInstall(path string) string { func (s Swagger) DescribeInstall(path string) string {
commands := []string{ commands := []string{
"The following commands will be executed", "The following commands will be executed",
fmt.Sprintf("rm -rf %s/swagger ", path), fmt.Sprintf("rm -rf %s/swagger ", path),
@ -153,9 +153,8 @@ func (s Swagger) DescribeInstall(path string) string {
return strings.Join(commands, "\n") return strings.Join(commands, "\n")
} }
// Install // Install will install or update the dependency.
func (s Swagger) Install(path string) error { func (s Swagger) Install(path string) error {
downloadURL := s.getDownloadURL() downloadURL := s.getDownloadURL()
content, err := downloadFile(downloadURL) content, err := downloadFile(downloadURL)
if err != nil { if err != nil {
@ -166,14 +165,19 @@ func (s Swagger) Install(path string) error {
fh, err := os.OpenFile( fh, err := os.OpenFile(
filepath.Join(path, "swagger"), filepath.Join(path, "swagger"),
os.O_RDWR|os.O_CREATE|os.O_TRUNC, os.O_RDWR|os.O_CREATE|os.O_TRUNC,
0744, 0600,
) )
if err != nil { if err != nil {
return errors.Trace(err) return errors.Trace(err)
} }
defer fh.Close()
bContent, err := ioutil.ReadAll(content) defer func() {
if err := fh.Close(); err != nil {
log.Errorf("Error closing file: %s", err)
}
}()
bContent, err := io.ReadAll(content)
if err != nil { if err != nil {
return errors.Trace(err) return errors.Trace(err)
} }
@ -186,9 +190,8 @@ func (s Swagger) Install(path string) error {
return nil return nil
} }
// DescribePostInstall // DescribePostInstall will list the post installation action that will be executed.
func (s Swagger) DescribePostInstall(path string) string { func (s Swagger) DescribePostInstall(path string) string {
return `For your environment to work correctly, we will add if needed the following environment variable to your .bashrc: return `For your environment to work correctly, we will add if needed the following environment variable to your .bashrc:
PATH=\"$HOME/bin:$PATH\" PATH=\"$HOME/bin:$PATH\"
@ -200,9 +203,8 @@ You will have to reopen a new terminal to apply the changes or execute the follo
` `
} }
// PostInstall // PostInstall will execute the post installation or update of the dependency.
func (s Swagger) PostInstall(path string) error { func (s Swagger) PostInstall(path string) error {
lineBashRc := []string{ lineBashRc := []string{
"# Swagger - Added by gouick", "# Swagger - Added by gouick",
} }
@ -229,12 +231,17 @@ func (s Swagger) PostInstall(path string) error {
fh, err := os.OpenFile( fh, err := os.OpenFile(
filepath.Join(homeDir, ".bashrc"), filepath.Join(homeDir, ".bashrc"),
os.O_APPEND|os.O_CREATE|os.O_WRONLY, os.O_APPEND|os.O_CREATE|os.O_WRONLY,
0644, 0600,
) )
if err != nil { if err != nil {
return errors.Trace(err) return errors.Trace(err)
} }
defer fh.Close()
defer func() {
if err := fh.Close(); err != nil {
log.Errorf("Error closing file: %s", err)
}
}()
_, err = fh.WriteString( _, err = fh.WriteString(
fmt.Sprintf("\n\n%s\n", strings.Join(lineBashRc, "\n")), fmt.Sprintf("\n\n%s\n", strings.Join(lineBashRc, "\n")),
@ -249,9 +256,8 @@ func (s Swagger) PostInstall(path string) error {
// GetInstallDirectory will try to find the current swagger directory. If it doesn't exist or if it's in a // GetInstallDirectory will try to find the current swagger directory. If it doesn't exist or if it's in a
// not userspace directory, it will provide the "default" // not userspace directory, it will provide the "default"
// It doesn't mean that the directory is "writable" // It doesn't mean that the directory is "writable".
func (s Swagger) GetInstallDirectory() (string, error) { func (s Swagger) GetInstallDirectory() (string, error) {
homeDir, err := os.UserHomeDir() homeDir, err := os.UserHomeDir()
if err != nil { if err != nil {
return "", errors.Trace(err) return "", errors.Trace(err)
@ -277,6 +283,5 @@ func (s Swagger) GetInstallDirectory() (string, error) {
} }
func (s Swagger) getDownloadURL() string { func (s Swagger) getDownloadURL() string {
return fmt.Sprintf("https://github.com/go-swagger/go-swagger/releases/download/v%s/swagger_%s_%s", minimumSwaggerVersion, runtime.GOOS, runtime.GOARCH) return fmt.Sprintf("https://github.com/go-swagger/go-swagger/releases/download/v%s/swagger_%s_%s", minimumSwaggerVersion, runtime.GOOS, runtime.GOARCH)
} }

View File

@ -20,13 +20,17 @@ import (
// downloadFile will download file from a given url and store in memory the content // downloadFile will download file from a given url and store in memory the content
// content will probably be untar, ungzip, .... // content will probably be untar, ungzip, ....
func downloadFile(url string) (io.Reader, error) { func downloadFile(url string) (io.Reader, error) {
// Get the data // Get the data
resp, err := http.Get(url) resp, err := http.Get(url)
if err != nil { if err != nil {
return nil, errors.Trace(err) return nil, errors.Trace(err)
} }
defer resp.Body.Close()
defer func() {
if err := resp.Body.Close(); err != nil {
log.Errorf("Error closing body: %s", err)
}
}()
buf := new(bytes.Buffer) buf := new(bytes.Buffer)
_, err = buf.ReadFrom(resp.Body) _, err = buf.ReadFrom(resp.Body)
@ -38,12 +42,16 @@ func downloadFile(url string) (io.Reader, error) {
} }
func unGzip(reader io.Reader) (io.Reader, error) { func unGzip(reader io.Reader) (io.Reader, error) {
gzipReader, err := gzip.NewReader(reader) gzipReader, err := gzip.NewReader(reader)
if err != nil { if err != nil {
return nil, errors.Trace(err) return nil, errors.Trace(err)
} }
defer gzipReader.Close()
defer func() {
if err := gzipReader.Close(); err != nil {
log.Errorf("Error closing gzip reader: %s", err)
}
}()
return gzipReader, nil return gzipReader, nil
} }
@ -59,7 +67,7 @@ func unTar(reader io.Reader, subdir string, dest string) error {
header, err := tr.Next() header, err := tr.Next()
switch { switch {
// no more files // no more files
case err == io.EOF: case errors.Is(err, io.EOF):
return nil return nil
case err != nil: case err != nil:
return errors.Trace(err) return errors.Trace(err)
@ -70,7 +78,6 @@ func unTar(reader io.Reader, subdir string, dest string) error {
filename := header.Name filename := header.Name
if subdir != "" && strings.HasPrefix(filename, subdir) { if subdir != "" && strings.HasPrefix(filename, subdir) {
filename = strings.TrimPrefix(filename, subdir) filename = strings.TrimPrefix(filename, subdir)
if filename == "" { if filename == "" {
@ -78,7 +85,10 @@ func unTar(reader io.Reader, subdir string, dest string) error {
} }
} }
target := filepath.Join(dest, filename) target, err := sanitizeArchivePath(dest, filename)
if err != nil {
return errors.Trace(err)
}
log.Debugf("Extacting %s", target) log.Debugf("Extacting %s", target)
@ -86,7 +96,7 @@ func unTar(reader io.Reader, subdir string, dest string) error {
// create directory if doesn't exit // create directory if doesn't exit
case tar.TypeDir: case tar.TypeDir:
if _, err := os.Stat(target); err != nil { if _, err := os.Stat(target); err != nil {
if err := os.MkdirAll(target, 0755); err != nil { if err := os.MkdirAll(target, 0750); err != nil {
return errors.Trace(err) return errors.Trace(err)
} }
} }
@ -96,7 +106,12 @@ func unTar(reader io.Reader, subdir string, dest string) error {
if err != nil { if err != nil {
return errors.Trace(err) return errors.Trace(err)
} }
defer f.Close()
defer func() {
if err := f.Close(); err != nil {
log.Errorf("Error closing file: %s", err)
}
}()
// copy contents to file // copy contents to file
if _, err := io.Copy(f, tr); err != nil { if _, err := io.Copy(f, tr); err != nil {
@ -107,7 +122,6 @@ func unTar(reader io.Reader, subdir string, dest string) error {
} }
func unZip(reader io.Reader, subdir string, dest string) error { func unZip(reader io.Reader, subdir string, dest string) error {
if subdir != "" && !strings.HasSuffix(subdir, "/") { if subdir != "" && !strings.HasSuffix(subdir, "/") {
subdir = fmt.Sprintf("%s/", subdir) subdir = fmt.Sprintf("%s/", subdir)
} }
@ -128,11 +142,9 @@ func unZip(reader io.Reader, subdir string, dest string) error {
} }
for _, file := range zipReader.File { for _, file := range zipReader.File {
filename := file.Name filename := file.Name
if subdir != "" && strings.HasPrefix(filename, subdir) { if subdir != "" && strings.HasPrefix(filename, subdir) {
filename = strings.TrimPrefix(filename, subdir) filename = strings.TrimPrefix(filename, subdir)
if filename == "" { if filename == "" {
@ -140,29 +152,41 @@ func unZip(reader io.Reader, subdir string, dest string) error {
} }
} }
target := filepath.Join(dest, filename) target, err := sanitizeArchivePath(dest, filename)
if err != nil {
return errors.Trace(err)
}
log.Debugf("Extacting %s", target) log.Debugf("Extacting %s", target)
if file.FileInfo().IsDir() { if file.FileInfo().IsDir() {
if _, err := os.Stat(target); err != nil { if _, err := os.Stat(target); err != nil {
if err := os.MkdirAll(target, 0755); err != nil { if err := os.MkdirAll(target, 0750); err != nil {
return errors.Trace(err) return errors.Trace(err)
} }
} }
} else { } else {
f, err := os.OpenFile(target, os.O_CREATE|os.O_RDWR, file.Mode()) f, err := os.OpenFile(target, os.O_CREATE|os.O_RDWR, file.Mode())
if err != nil { if err != nil {
return errors.Trace(err) return errors.Trace(err)
} }
defer f.Close()
defer func() {
if err := f.Close(); err != nil {
log.Errorf("Error closing file: %s", err)
}
}()
fileInArchive, err := file.Open() fileInArchive, err := file.Open()
if err != nil { if err != nil {
return errors.Trace(err) return errors.Trace(err)
} }
defer fileInArchive.Close()
defer func() {
if err := fileInArchive.Close(); err != nil {
log.Errorf("Error closing file: %s", err)
}
}()
// copy contents to file // copy contents to file
if _, err := io.Copy(f, fileInArchive); err != nil { if _, err := io.Copy(f, fileInArchive); err != nil {
@ -173,3 +197,12 @@ func unZip(reader io.Reader, subdir string, dest string) error {
return nil return nil
} }
// sanitizeArchivePath will sanitize archive file pathing from "G305: Zip Slip vulnerability".
func sanitizeArchivePath(d string, t string) (string, error) {
if v := filepath.Join(d, t); strings.HasPrefix(v, filepath.Clean(d)) {
return v, nil
}
return "", fmt.Errorf("%s: %s", "content filepath is tainted", t)
}

View File

@ -2,7 +2,6 @@ package helpers
import ( import (
"io/fs" "io/fs"
"io/ioutil"
"os" "os"
"path/filepath" "path/filepath"
@ -117,7 +116,6 @@ func CheckAndCreateDir(path string) (bool, error) {
err = createDirectory(path) err = createDirectory(path)
if err != nil { if err != nil {
log.Warnf("impossible to create directory (%s), please try again", err.Error()) log.Warnf("impossible to create directory (%s), please try again", err.Error())
return false, err return false, err
} }
@ -127,20 +125,18 @@ func CheckAndCreateDir(path string) (bool, error) {
func RemoveDirectoryContent(path string) error { func RemoveDirectoryContent(path string) error {
dir, err := ioutil.ReadDir(path) dir, err := os.ReadDir(path)
if err != nil { if err != nil {
return errors.Trace(err) return errors.Trace(err)
} }
for _, d := range dir { for _, d := range dir {
err := os.RemoveAll( err := os.RemoveAll(
filepath.Join(path, d.Name()), filepath.Join(path, d.Name()),
) )
if err != nil { if err != nil {
return errors.Trace(err) return errors.Trace(err)
} }
} }
return nil return nil

View File

@ -106,7 +106,7 @@ func PathInput() string {
// APITypeNameInput // APITypeNameInput
func APITypeNameInput() models.APITypeName { func APITypeNameInput() models.APITypeName {
var possibleAPITypes []string possibleAPITypes := make([]string, 0)
for _, apiType := range models.GetListOfAPITypeName() { for _, apiType := range models.GetListOfAPITypeName() {
possibleAPITypes = append(possibleAPITypes, string(apiType)) possibleAPITypes = append(possibleAPITypes, string(apiType))
} }

View File

@ -1,6 +1,6 @@
package models package models
// UserInputParams // UserInputParams is a struct containing all fields that can be useful for project generation.
type UserInputParams struct { type UserInputParams struct {
DB bool DB bool
GoModuleName *string GoModuleName *string

View File

@ -6,9 +6,10 @@ import (
"github.com/juju/errors" "github.com/juju/errors"
) )
// APITypeName // APITypeName is a type used as an enum for possible API Type Name.
type APITypeName string type APITypeName string
//nolint:exported // keeping the enum simple and redeable.
const ( const (
APITypeName_GIN_GONIC APITypeName = "Gin Gonic" APITypeName_GIN_GONIC APITypeName = "Gin Gonic"
APITypeName_GO_SWAGGER APITypeName = "Go Swagger" APITypeName_GO_SWAGGER APITypeName = "Go Swagger"
@ -16,7 +17,7 @@ const (
APITypeName_NULL APITypeName = "" APITypeName_NULL APITypeName = ""
) )
// GetListOfAPITypeName returns a list of APITypeName // GetListOfAPITypeName returns a list of APITypeName.
func GetListOfAPITypeName() []APITypeName { func GetListOfAPITypeName() []APITypeName {
return []APITypeName{ return []APITypeName{
APITypeName_GIN_GONIC, APITypeName_GIN_GONIC,
@ -25,7 +26,7 @@ func GetListOfAPITypeName() []APITypeName {
} }
} }
// IsValid validates enum values // IsValid validates enum values.
func (e APITypeName) IsValid() bool { func (e APITypeName) IsValid() bool {
for _, v := range GetListOfAPITypeName() { for _, v := range GetListOfAPITypeName() {
if e == v { if e == v {
@ -36,6 +37,7 @@ func (e APITypeName) IsValid() bool {
return false return false
} }
// NewAPITypeName return a APITypeName based on a given string.
func NewAPITypeName(in string) (APITypeName, error) { func NewAPITypeName(in string) (APITypeName, error) {
out := APITypeName_NULL out := APITypeName_NULL
if in != "" { if in != "" {
@ -47,9 +49,8 @@ func NewAPITypeName(in string) (APITypeName, error) {
return out, nil return out, nil
} }
// NewAPITypeNameFromInput // NewAPITypeNameFromInput will try to sluggify a given string and make it match with a APITypeName.
func NewAPITypeNameFromInput(in string) (APITypeName, error) { func NewAPITypeNameFromInput(in string) (APITypeName, error) {
in = strings.ToLower(in) in = strings.ToLower(in)
in = strings.ReplaceAll(in, " ", "-") in = strings.ReplaceAll(in, " ", "-")
in = strings.ReplaceAll(in, "_", "-") in = strings.ReplaceAll(in, "_", "-")

View File

@ -1,8 +1,9 @@
package models package models
// DependencyName // DependencyName is a type used as an enum for possible Dependency Name.
type DependencyName string type DependencyName string
//nolint:exported // keeping the enum simple and redeable.
const ( const (
DependencyName_GIT DependencyName = "Git" DependencyName_GIT DependencyName = "Git"
DependencyName_GOLANG DependencyName = "Golang" DependencyName_GOLANG DependencyName = "Golang"