diff --git a/.golangci.yml b/.golangci.yml index 6f2a951..13d1fe2 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -93,6 +93,7 @@ linters: - nolintlint # reports ill-formed or insufficient nolint directives - nonamedreturns - prealloc # finds slice declarations that could potentially be preallocated + - revive - sqlclosecheck - staticcheck # Staticcheck is a go vet on steroids, applying a ton of static analysis checks - structcheck # finds unused struct fields @@ -103,8 +104,6 @@ linters: - unused # checks Go code for unused constants, variables, functions and types - varcheck # Finds unused global variables and constants - wastedassign # wastedassign finds wasted assignment statements. - - whitespace - - revive # all available settings of specific linters linters-settings: @@ -129,7 +128,7 @@ linters-settings: dupl: # tokens count to trigger issue, 150 by default - threshold: 100 + threshold: 150 gomoddirectives: # Allow local `replace` directives. Default is false. diff --git a/README.md b/README.md index 1ab6af1..2fd83ad 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,7 @@ # Gouick [![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) + + +## Improvement idea +* Refactoring of dependencies to use same architecture as APIType to use base function and avoid dups \ No newline at end of file diff --git a/helpers/api_types/gin_gonic/api_type.go b/helpers/api_types/gin_gonic/api_type.go index 664ba1c..deb5b35 100644 --- a/helpers/api_types/gin_gonic/api_type.go +++ b/helpers/api_types/gin_gonic/api_type.go @@ -2,7 +2,7 @@ package gin_gonic import "git.home.m-and-m.ovh/mderasse/gouick/helpers/api_types/base" -// APIType +// APIType represent an empty struct respecting the APITypeInterface. type APIType struct { base.APIType } diff --git a/helpers/api_types/go_swagger/api_type.go b/helpers/api_types/go_swagger/api_type.go index 955fed1..264f7a5 100644 --- a/helpers/api_types/go_swagger/api_type.go +++ b/helpers/api_types/go_swagger/api_type.go @@ -2,7 +2,7 @@ package go_swagger import "git.home.m-and-m.ovh/mderasse/gouick/helpers/api_types/base" -// APIType +// APIType represent an empty struct respecting the APITypeInterface. type APIType struct { base.APIType } diff --git a/helpers/api_types/go_swagger/check_initialize.go b/helpers/api_types/go_swagger/check_initialize.go index f034b66..78e9138 100644 --- a/helpers/api_types/go_swagger/check_initialize.go +++ b/helpers/api_types/go_swagger/check_initialize.go @@ -12,7 +12,6 @@ import ( // CheckInitialize will do preliminary check before initializing a new project. func (a APIType) CheckInitialize() error { - log.Debugf("Starting %s check initialize", string(a.GetName())) // Get current path diff --git a/helpers/api_types/go_swagger/get_user_input.go b/helpers/api_types/go_swagger/get_user_input.go index 46f57e2..4cc1333 100644 --- a/helpers/api_types/go_swagger/get_user_input.go +++ b/helpers/api_types/go_swagger/get_user_input.go @@ -13,7 +13,6 @@ import ( // GetInitializeUserInput will ask user to provide information that allow initialization of a project. func (a APIType) GetInitializeUserInput(params *models.UserInputParams) (*models.UserInputParams, error) { - log.Debugf("Starting %s user input", a.GetName()) // Get current path @@ -29,8 +28,8 @@ func (a APIType) GetInitializeUserInput(params *models.UserInputParams) (*models log.Debug("Checking if we are in GoPath") isInGoPath := helpers.IsInGoPath(currentPath) - if !isInGoPath { + if !isInGoPath { log.Debug("We are not in GoPath, ask extra info") goModulePath := helpers.StringInput() log.Info("Go Module name:") diff --git a/helpers/api_types/interface.go b/helpers/api_types/interface.go index d8ece1d..75b3cc1 100644 --- a/helpers/api_types/interface.go +++ b/helpers/api_types/interface.go @@ -2,7 +2,7 @@ package api_types import "git.home.m-and-m.ovh/mderasse/gouick/helpers/models" -// APITypeInterface +// APITypeInterface is the interface that need to be respected by an APIType. type APITypeInterface interface { CheckInitialize() error GetName() models.APITypeName diff --git a/helpers/api_types/mojolicious/api_type.go b/helpers/api_types/mojolicious/api_type.go index 39ed643..71e664c 100644 --- a/helpers/api_types/mojolicious/api_type.go +++ b/helpers/api_types/mojolicious/api_type.go @@ -2,7 +2,7 @@ package mojolicious import "git.home.m-and-m.ovh/mderasse/gouick/helpers/api_types/base" -// APIType +// APIType represent an empty struct respecting the APITypeInterface. type APIType struct { base.APIType } diff --git a/helpers/dependencies/golang.go b/helpers/dependencies/golang.go index 638fea0..e7c30ac 100644 --- a/helpers/dependencies/golang.go +++ b/helpers/dependencies/golang.go @@ -254,6 +254,7 @@ func (g Golang) PostInstall(path string) error { if len(lineBashRc) > 1 { log.Debug("Adding env variable to .bashrc") + //nolint:gosec // we did compute the file path fh, err := os.OpenFile( filepath.Join(homeDir, ".bashrc"), os.O_APPEND|os.O_CREATE|os.O_WRONLY, diff --git a/helpers/dependencies/swagger.go b/helpers/dependencies/swagger.go index 360d17a..a7944b1 100644 --- a/helpers/dependencies/swagger.go +++ b/helpers/dependencies/swagger.go @@ -162,6 +162,7 @@ func (s Swagger) Install(path string) error { return errors.Trace(err) } + //nolint:gosec // we did compute the file path fh, err := os.OpenFile( filepath.Join(path, "swagger"), os.O_RDWR|os.O_CREATE|os.O_TRUNC, @@ -228,6 +229,7 @@ func (s Swagger) PostInstall(path string) error { if len(lineBashRc) > 1 { log.Debug("Adding env variable to .bashrc") + //nolint:gosec // we did compute the file path fh, err := os.OpenFile( filepath.Join(homeDir, ".bashrc"), os.O_APPEND|os.O_CREATE|os.O_WRONLY, diff --git a/helpers/dependencies/utils.go b/helpers/dependencies/utils.go index d791408..ada8aeb 100644 --- a/helpers/dependencies/utils.go +++ b/helpers/dependencies/utils.go @@ -21,6 +21,7 @@ import ( // content will probably be untar, ungzip, .... func downloadFile(url string) (io.Reader, error) { // Get the data + //nolint:gosec,noctx // we trust the url resp, err := http.Get(url) if err != nil { return nil, errors.Trace(err) @@ -93,7 +94,7 @@ func unTar(reader io.Reader, subdir string, dest string) error { log.Debugf("Extacting %s", target) switch header.Typeflag { - // create directory if doesn't exit + // create directory if doesn't exit. case tar.TypeDir: if _, err := os.Stat(target); err != nil { if err := os.MkdirAll(target, 0750); err != nil { @@ -102,6 +103,7 @@ func unTar(reader io.Reader, subdir string, dest string) error { } // create file case tar.TypeReg: + //nolint:gosec // we did compute the file path. f, err := os.OpenFile(target, os.O_CREATE|os.O_RDWR, os.FileMode(header.Mode)) if err != nil { return errors.Trace(err) @@ -113,7 +115,8 @@ func unTar(reader io.Reader, subdir string, dest string) error { } }() - // copy contents to file + // copy contents to file. + //nolint:gosec // TODO: do a decompression that protect from decompression bomb. if _, err := io.Copy(f, tr); err != nil { return errors.Trace(err) } @@ -166,6 +169,7 @@ func unZip(reader io.Reader, subdir string, dest string) error { } } } else { + //nolint:gosec // we did compute the file path. f, err := os.OpenFile(target, os.O_CREATE|os.O_RDWR, file.Mode()) if err != nil { return errors.Trace(err) @@ -189,6 +193,7 @@ func unZip(reader io.Reader, subdir string, dest string) error { }() // copy contents to file + //nolint:gosec // TODO: do a decompression that protect from decompression bomb. if _, err := io.Copy(f, fileInArchive); err != nil { return errors.Trace(err) } diff --git a/helpers/file.go b/helpers/file.go index ab02e14..32c90b2 100644 --- a/helpers/file.go +++ b/helpers/file.go @@ -10,8 +10,8 @@ import ( log "github.com/sirupsen/logrus" ) +// IsGouickDirectory will check if we are in the same directory as the Gouick binary. func IsGouickDirectory(path string) (bool, error) { - binPath, err := os.Executable() if err != nil { return false, errors.Trace(err) @@ -26,8 +26,8 @@ func IsGouickDirectory(path string) (bool, error) { return true, nil } +// IsGouickProject will check if a gouick config file exist and readeable. func IsGouickProject(path string) (bool, error) { - exist, err := fileExists(filepath.Join(path, configFile)) if err != nil { return false, errors.Trace(err) @@ -40,11 +40,10 @@ func IsGouickProject(path string) (bool, error) { return true, nil } +// fileExists will check if a file exist and is readeable. func fileExists(path string) (bool, error) { - fileInfo, err := os.Stat(path) if err != nil { - if errors.Is(err, fs.ErrPermission) { return false, errors.NewForbidden(err, "file is not readeable") } else if errors.Is(err, fs.ErrNotExist) { @@ -60,12 +59,10 @@ func fileExists(path string) (bool, error) { return true, nil } -// isDirectoryWritable +// isDirectoryWritable will check if a directory path is writable. func isDirectoryWritable(path string) (bool, error) { - dirInfo, err := os.Stat(path) if err != nil { - if errors.Is(err, fs.ErrPermission) { return false, errors.NewForbidden(err, "directory is not readeable") } else if errors.Is(err, fs.ErrNotExist) { @@ -86,11 +83,10 @@ func isDirectoryWritable(path string) (bool, error) { return true, nil } -// createDirectory +// createDirectory will create a new directory along with necessessary parents. func createDirectory(path string) error { - - // no need to check if path exist - // MkdirAll will do it for us + // no need to check if path exist. + // MkdirAll will do it for us. err := os.MkdirAll(path, os.ModePerm) if err != nil { return errors.Trace(err) @@ -100,9 +96,8 @@ func createDirectory(path string) error { } // CheckAndCreateDir will check if path is writable and create directory if needed -// return a bool true if directory created, false if not +// return a bool true if directory created, false if not. func CheckAndCreateDir(path string) (bool, error) { - dirWritable, err := isDirectoryWritable(path) if dirWritable { return false, nil @@ -123,8 +118,8 @@ func CheckAndCreateDir(path string) (bool, error) { return true, nil } +// RemoveDirectoryContent will delete the content of a provided directory path. func RemoveDirectoryContent(path string) error { - dir, err := os.ReadDir(path) if err != nil { return errors.Trace(err) diff --git a/helpers/golang.go b/helpers/golang.go index b60d3e7..2982f26 100644 --- a/helpers/golang.go +++ b/helpers/golang.go @@ -8,9 +8,8 @@ import ( "github.com/juju/errors" ) -// IsGoProject +// IsGoProject check if we are in a golang project (have go.mod). func IsGoProject(path string) (bool, error) { - exist, err := fileExists(filepath.Join(path, "go.mod")) if err != nil { return false, errors.Trace(err) @@ -32,7 +31,7 @@ func IsGoProject(path string) (bool, error) { return false, nil } -// IsInGoPath +// IsInGoPath check if the given path is in the gopath directory. func IsInGoPath(path string) bool { gopath := os.Getenv("GOPATH") diff --git a/helpers/input.go b/helpers/input.go index afda2f8..b815785 100644 --- a/helpers/input.go +++ b/helpers/input.go @@ -11,12 +11,11 @@ import ( log "github.com/sirupsen/logrus" ) -// YesOrNoInput +// YesOrNoInput ask user for a yes or no reply and try until we get a possible answer. func YesOrNoInput() bool { scanner := bufio.NewScanner(os.Stdin) for { - scanner.Scan() userInput := scanner.Text() @@ -37,7 +36,7 @@ func YesOrNoInput() bool { } } -// AlphanumericalInput +// AlphanumericalInput ask user for a alphanumerical string and try until we get a possible answer. func AlphanumericalInput() string { scanner := bufio.NewScanner(os.Stdin) @@ -61,7 +60,7 @@ func AlphanumericalInput() string { } } -// StringInput +// StringInput ask user for a string and try until we get a possible answer. func StringInput() string { scanner := bufio.NewScanner(os.Stdin) @@ -79,7 +78,7 @@ func StringInput() string { } } -// PathInput +// PathInput ask user for a path string and try until we get a possible answer. func PathInput() string { scanner := bufio.NewScanner(os.Stdin) @@ -103,7 +102,7 @@ func PathInput() string { } } -// APITypeNameInput +// APITypeNameInput ask user for a string that is a valid API Type name and try until we get a possible answer. func APITypeNameInput() models.APITypeName { possibleAPITypes := make([]string, 0)