fix(lint): Continue to apply linter recommandation
Some checks failed
continuous-integration/drone/push Build is failing
Some checks failed
continuous-integration/drone/push Build is failing
This commit is contained in:
parent
101ca9a79c
commit
660a4ef162
@ -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
|
||||||
|
@ -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
|
|
||||||
|
@ -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")
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -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",
|
||||||
|
@ -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",
|
||||||
|
@ -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",
|
||||||
|
@ -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",
|
||||||
|
@ -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",
|
||||||
|
@ -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",
|
||||||
|
@ -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",
|
||||||
|
11
cmd/init.go
11
cmd/init.go
@ -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))
|
||||||
}
|
}
|
||||||
|
14
cmd/root.go
14
cmd/root.go
@ -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())
|
||||||
|
@ -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",
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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",
|
||||||
|
@ -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")
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
package base
|
package base
|
||||||
|
|
||||||
// APIType
|
// APIType struct.
|
||||||
type APIType struct {
|
type APIType struct {
|
||||||
}
|
}
|
||||||
|
@ -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())
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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())
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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()))
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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())
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@ -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
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
|
@ -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)
|
||||||
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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))
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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, "_", "-")
|
||||||
|
@ -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"
|
||||||
|
Loading…
Reference in New Issue
Block a user