From 04a49123fa8ca8d87e0677b72723af63516089c2 Mon Sep 17 00:00:00 2001 From: Aisuko Date: Mon, 16 Oct 2023 03:28:56 +0000 Subject: [PATCH] Add golangci -lint, fix error of code Signed-off-by: GitHub --- .github/workflows/ci.yml | 12 +- .golangci.yml | 177 +++++++---------------- cmd/errorutil/internal/coder/commands.go | 10 +- cmd/syncmodutil/internal/modsync/sync.go | 4 +- go.mod | 2 +- go.sum | 4 +- models/controllers/meshsync.go | 8 +- utils/cue.go | 2 +- utils/kubernetes/apply-manifest.go | 7 +- utils/kubernetes/client.go | 3 +- utils/kubernetes/expose/expose.go | 2 +- utils/kubernetes/helm.go | 2 +- utils/kubernetes/kompose/composefile.go | 2 +- utils/kubernetes/kompose/convert.go | 10 +- utils/manifests/generateComponent.go | 2 +- utils/manifests/utils.go | 116 ++------------- utils/walker/git.go | 14 +- 17 files changed, 99 insertions(+), 278 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 01a2f37c..6af10732 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -20,16 +20,8 @@ jobs: - name: golangci-lint uses: golangci/golangci-lint-action@v3 with: - # Required: the version of golangci-lint is required and must be specified without patch version: we always use the latest patch version. - version: v1.54 - - # Optional: working directory, useful for monorepos - # working-directory: somedir - - # Optional: golangci-lint command line arguments. - - # Optional: show only new issues if it's a pull request. The default value is `false`. - # only-new-issues: true + version: latest + args: --timeout=5m tests: name: Tests runs-on: ubuntu-latest diff --git a/.golangci.yml b/.golangci.yml index d4aa8981..5353cc2c 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -1,135 +1,64 @@ linters-settings: - depguard: - list-type: blacklist - packages: - # logging is allowed only by logutils.Log, logrus - # is allowed to use only in logutils package - - github.com/sirupsen/logrus - packages-with-error-message: - - github.com/sirupsen/logrus: "logging is allowed only by logutils.Log" - dupl: - threshold: 100 - exhaustive: - default-signifies-exhaustive: false - funlen: - lines: 100 - statements: 50 gci: - local-prefixes: github.com/golangci/golangci-lint + enabled: true + max-len: 120 + line-length: 120 goconst: - min-len: 2 - min-occurrences: 2 + enabled: true gocritic: - enabled-tags: - - diagnostic - - experimental - - opinionated - - performance - - style - disabled-checks: - - dupImport # https://github.com/go-critic/go-critic/issues/845 - - ifElseChain - - octalLiteral - - whyNoLint - - wrapperFunc - gocyclo: - min-complexity: 15 - goimports: - local-prefixes: github.com/golangci/golangci-lint - golint: - min-confidence: 0 - gomnd: - settings: - mnd: - # don't include the "operation" and "assign" - checks: - - argument - - case - - condition - - return - gosec: - settings: - exclude: -G204 + enabled: true + disable: + - parallelize + - nesting + - hugeParam + - hugeStruct + - nestParam + - prealloc govet: - check-shadowing: false - settings: - printf: - funcs: - - (github.com/golangci/golangci-lint/pkg/logutils.Log).Infof - - (github.com/golangci/golangci-lint/pkg/logutils.Log).Warnf - - (github.com/golangci/golangci-lint/pkg/logutils.Log).Errorf - - (github.com/golangci/golangci-lint/pkg/logutils.Log).Fatalf - lll: - line-length: 950 - maligned: - suggest-new: true - misspell: - # Correct spellings using locale preferences for US or UK. - # Setting locale to US will correct the British spelling of 'colour' to 'color'. - # Default is to use a neutral variety of English. - locale: US - ignore-words: - - eles - nolintlint: - allow-leading-space: true # don't require machine-readable nolint directives (i.e. with no leading space) - allow-unused: false # report any unused nolint directives - require-explanation: false # don't require an explanation for nolint directives - require-specific: false # don't require nolint directives to be specific about which linter is being skipped + enabled: true + check-shadowing: true + tests: true + golint: + enabled: true + min-confidence: 0.8 + unused: + enabled: true + check-exported: true + check-packages: true + check-generated: true + tests: true + allow-unused-type-export: true + cyclop: + enabled: true + average-strictness: 7 + scopelint: + enabled: true + tests: true + +# Configuration for golangci-lint that is suitable for a Kubernetes operator project built with Golang linters: - # please, do not use `enable-all`: it's deprecated and will be removed soon. - # inverted configuration with `enable-all` and `disable` is not scalable during updates of golangci-lint - disable-all: true - enable: - # todo[kushthedude]: commenting most of the checks as our code can't persist all of the changes, however we can plan further on code-quality after v1.0 release. - # - bodyclose - # - deadcode - - dogsled - - errcheck - # - exhaustive - # - funlen - # - goconst - # - gocritic - # - gocyclo - - gofmt - - goimports - # - revive - # todo[kusthedude]: restore gosec check, once this issue is resolved https://github.com/golangci/golangci-lint/issues/177 - # - gosec - # - gomnd - # - goprintffuncname - # - gosimple + enable-all: false + disable-all: false + linters: + - gci + - goconst + - gocritic - govet - # - ineffassign - # - interfacer - - lll - - misspell - # - nakedret - # - nolintlint - # - rowserrcheck - # - scopelint - - staticcheck - # - structcheck - # - stylecheck - - typecheck - # - unconvert - # - unparam - # - unused - # - varcheck - - whitespace - - # don't enable: - # - asciicheck - # - gochecknoglobals - # - gocognit - # - godot - # - godox - # - goerr113 - # - maligned - # - nestif - # - prealloc - # - testpackage - # - wsl + - golint + - unused + - cyclop + - scopelint + exclude-rules: + - testpackage run: timeout: 5m + enable-cache: true + skip-dirs: + - vendor + - bundle + - config + - hack + - helpers + - img \ No newline at end of file diff --git a/cmd/errorutil/internal/coder/commands.go b/cmd/errorutil/internal/coder/commands.go index 96047216..6fb59098 100644 --- a/cmd/errorutil/internal/coder/commands.go +++ b/cmd/errorutil/internal/coder/commands.go @@ -106,11 +106,11 @@ func commandAnalyze() *cobra.Command { Long: `analyze analyzes a directory tree for error codes`, Args: cobra.MinimumNArgs(0), RunE: func(cmd *cobra.Command, args []string) error { - globalFlags, err := getGlobalFlags(cmd) + gFlags, err := getGlobalFlags(cmd) if err != nil { return err } - return walkSummarizeExport(globalFlags, false, false) + return walkSummarizeExport(gFlags, false, false) }, } } @@ -123,15 +123,15 @@ func commandUpdate() *cobra.Command { Long: "update replaces error codes where specified, and updates error details", Args: cobra.MinimumNArgs(0), RunE: func(cmd *cobra.Command, args []string) error { - globalFlags, err := getGlobalFlags(cmd) + gFlags, err := getGlobalFlags(cmd) if err != nil { return err } - updateAll, err := cmd.Flags().GetBool(forceUpdateAllCodesCmdFlag) + updateAll, err = cmd.Flags().GetBool(forceUpdateAllCodesCmdFlag) if err != nil { return err } - return walkSummarizeExport(globalFlags, true, updateAll) + return walkSummarizeExport(gFlags, true, updateAll) }, } cmd.PersistentFlags().BoolVar(&updateAll, forceUpdateAllCodesCmdFlag, false, "Update and re-sequence all error codes.") diff --git a/cmd/syncmodutil/internal/modsync/sync.go b/cmd/syncmodutil/internal/modsync/sync.go index 9e1a09d9..ca6cab35 100644 --- a/cmd/syncmodutil/internal/modsync/sync.go +++ b/cmd/syncmodutil/internal/modsync/sync.go @@ -51,8 +51,7 @@ func (g *GoMod) PrintReplacedVersions() { } } func (g *GoMod) SyncRequire(f io.Reader, throwerr bool) (gomod string, err error) { - var b = make([]byte, 1000) - b, err = io.ReadAll(f) + b, err := io.ReadAll(f) if err != nil { return string(b), err } @@ -90,7 +89,6 @@ func (g *GoMod) SyncRequire(f io.Reader, throwerr bool) (gomod string, err error // NewGoMod takes an io.Reader to a go.mod and returns GoMod struct func New(f io.Reader) (*GoMod, error) { - var b = make([]byte, 1000) b, err := io.ReadAll(f) if err != nil { return nil, err diff --git a/go.mod b/go.mod index 32c96ec3..57853792 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.21 replace ( github.com/Sirupsen/logrus => github.com/sirupsen/logrus v1.9.3 - github.com/docker/docker => github.com/moby/moby v20.10.7+incompatible + github.com/docker/docker => github.com/moby/moby v20.10.24+incompatible github.com/docker/libcompose => github.com/docker/libcompose v0.4.1-0.20190808084053-143e0f3f1ab9 github.com/googleapis/gnostic => github.com/googleapis/gnostic v0.5.5 github.com/jaguilar/vt100 => github.com/tonistiigi/vt100 v0.0.0-20190402012908-ad4c4a574305 diff --git a/go.sum b/go.sum index df03610d..c7a6d1c5 100644 --- a/go.sum +++ b/go.sum @@ -953,8 +953,8 @@ github.com/moby/buildkit v0.8.2-0.20210401015549-df49b648c8bf h1:dHwWBX8OhYb69qV github.com/moby/buildkit v0.8.2-0.20210401015549-df49b648c8bf/go.mod h1:GJcrUlTGFAPlEmPQtbrTsJYn+cy+Jwl7vTZS7jYAoow= github.com/moby/locker v1.0.1 h1:fOXqR41zeveg4fFODix+1Ch4mj/gT0NE1XJbp/epuBg= github.com/moby/locker v1.0.1/go.mod h1:S7SDdo5zpBK84bzzVlKr2V0hz+7x9hWbYC/kq7oQppc= -github.com/moby/moby v20.10.7+incompatible h1:mMDsIjUeon2FpxCJz0Xj32wzRcTbGLVzG1uEbPalok4= -github.com/moby/moby v20.10.7+incompatible/go.mod h1:fDXVQ6+S340veQPv35CzDahGBmHsiclFwfEygB/TWMc= +github.com/moby/moby v20.10.24+incompatible h1:hjfxUufgeyrgolyaOWASyR9SvehpNcq/QHp/tx4VgsM= +github.com/moby/moby v20.10.24+incompatible/go.mod h1:fDXVQ6+S340veQPv35CzDahGBmHsiclFwfEygB/TWMc= github.com/moby/spdystream v0.2.0 h1:cjW1zVyyoiM0T7b6UoySUFqzXMoqRckQtXwGPiBhOM8= github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c= github.com/moby/sys/mount v0.1.0/go.mod h1:FVQFLDRWwyBjDTBNQXDlWnSFREqOo3OKX9aqhmeoo74= diff --git a/models/controllers/meshsync.go b/models/controllers/meshsync.go index f8bc3387..595c38a2 100644 --- a/models/controllers/meshsync.go +++ b/models/controllers/meshsync.go @@ -39,11 +39,11 @@ func (ms *meshsync) GetStatus() MesheryControllerStatus { if err == nil { ms.status = Enabled - meshSyncPod, err := ms.kclient.KubeClient.CoreV1().Pods("meshery").List(context.TODO(), metav1.ListOptions{ + meshSyncPod, errMeshery := ms.kclient.KubeClient.CoreV1().Pods("meshery").List(context.TODO(), metav1.ListOptions{ LabelSelector: "component=meshsync", }) - if len(meshSyncPod.Items) == 0 || kubeerror.IsNotFound(err) { + if len(meshSyncPod.Items) == 0 || kubeerror.IsNotFound(errMeshery) { return ms.status } for _, pod := range meshSyncPod.Items { @@ -51,8 +51,8 @@ func (ms *meshsync) GetStatus() MesheryControllerStatus { case v1.PodRunning: ms.status = Running broker := NewMesheryBrokerHandler(ms.kclient) - brokerEndpoint, err := broker.GetPublicEndpoint() - if err != nil { + brokerEndpoint, errOfEndpoint := broker.GetPublicEndpoint() + if errOfEndpoint != nil { return ms.status } hostIP := strings.Split(brokerEndpoint, ":")[0] diff --git a/utils/cue.go b/utils/cue.go index 60a649dc..64f0db4d 100644 --- a/utils/cue.go +++ b/utils/cue.go @@ -82,7 +82,7 @@ func JsonSchemaToCue(value string) (cue.Value, error) { } cueCtx := cuecontext.New() cueJsonSchemaExpr := cueCtx.BuildExpr(jsonSchema) - if err := cueJsonSchemaExpr.Err(); err != nil { + if err = cueJsonSchemaExpr.Err(); err != nil { return out, ErrJsonSchemaToCue(err) } extractedSchema, err := jsonschema.Extract(cueJsonSchemaExpr, &jsonschema.Config{ diff --git a/utils/kubernetes/apply-manifest.go b/utils/kubernetes/apply-manifest.go index 01632174..f1d1beac 100644 --- a/utils/kubernetes/apply-manifest.go +++ b/utils/kubernetes/apply-manifest.go @@ -162,10 +162,13 @@ func createObject(restHelper *resource.Helper, namespace string, obj runtime.Obj return nil, err } - object, err := restHelper.Create(namespace, update, obj) + var object runtime.Object + var er error + + object, err = restHelper.Create(namespace, update, obj) if err != nil { if kubeerror.IsAlreadyExists(err) && update { - object, er := restHelper.Replace(namespace, name, update, obj) + object, er = restHelper.Replace(namespace, name, update, obj) if er != nil { if (kubeerror.IsInvalid(er) && strings.Contains(er.Error(), "field is immutable")) || (kubeerror.IsInvalid(er) && strings.Contains(er.Error(), "primary clusterIP can not be unset")) { return object, nil diff --git a/utils/kubernetes/client.go b/utils/kubernetes/client.go index 3b24a521..146da142 100644 --- a/utils/kubernetes/client.go +++ b/utils/kubernetes/client.go @@ -13,7 +13,8 @@ import ( // DetectKubeConfig detects the kubeconfig for the kubernetes cluster and returns it func DetectKubeConfig(configfile []byte) (config *rest.Config, err error) { if len(configfile) > 0 { - cfgFile, err := processConfig(configfile) + var cfgFile []byte + cfgFile, err = processConfig(configfile) if err != nil { return nil, err } diff --git a/utils/kubernetes/expose/expose.go b/utils/kubernetes/expose/expose.go index 1eca1a25..561c7256 100644 --- a/utils/kubernetes/expose/expose.go +++ b/utils/kubernetes/expose/expose.go @@ -125,7 +125,7 @@ func Expose( // Check if the resource can be exposed or not gk := info.GetObjectKind().GroupVersionKind().GroupKind() - if err := canBeExposed(gk); err != nil { + if err = canBeExposed(gk); err != nil { return nil, ErrResourceCannotBeExposed(err, gk.Kind) } diff --git a/utils/kubernetes/helm.go b/utils/kubernetes/helm.go index 16dca9ec..f65bba81 100644 --- a/utils/kubernetes/helm.go +++ b/utils/kubernetes/helm.go @@ -13,7 +13,7 @@ import ( // We will only make use of URL/ChartLocation/LocalPath to get and load the helm chart func ConvertHelmChartToK8sManifest(cfg ApplyHelmChartConfig) (manifest []byte, err error) { setupDefaults(&cfg) - if err := setupChartVersion(&cfg); err != nil { + if err = setupChartVersion(&cfg); err != nil { return nil, ErrApplyHelmChart(err) } diff --git a/utils/kubernetes/kompose/composefile.go b/utils/kubernetes/kompose/composefile.go index f74ccf7a..68e68ca1 100644 --- a/utils/kubernetes/kompose/composefile.go +++ b/utils/kubernetes/kompose/composefile.go @@ -17,7 +17,7 @@ func (dc *DockerComposeFile) Validate(schema []byte) error { } cueCtx := cuecontext.New() cueJsonSchemaExpr := cueCtx.BuildExpr(jsonSchema) - if err := cueJsonSchemaExpr.Err(); err != nil { + if err = cueJsonSchemaExpr.Err(); err != nil { return ErrValidateDockerComposeFile(err) } extractedSchema, err := jsonschema.Extract(cueJsonSchemaExpr, &jsonschema.Config{ diff --git a/utils/kubernetes/kompose/convert.go b/utils/kubernetes/kompose/convert.go index 52ed5f2f..5c2c0fb5 100644 --- a/utils/kubernetes/kompose/convert.go +++ b/utils/kubernetes/kompose/convert.go @@ -33,8 +33,7 @@ func IsManifestADockerCompose(manifest []byte, schemaURL string) error { if err != nil { return err } - var dockerComposeFile DockerComposeFile - dockerComposeFile = manifest + var dockerComposeFile DockerComposeFile = manifest err = dockerComposeFile.Validate([]byte(schema)) return err } @@ -169,13 +168,11 @@ func formatComposeFile(yamlManifest *DockerComposeFile) { return } // so that "3.3" and 3.3 are treated differently by `Kompose` - data.Version = fmt.Sprintf("%s", data.Version) out, err := yaml.Marshal(data) if err != nil { return } *yamlManifest = out - return } var inputFormat = "compose" @@ -192,10 +189,7 @@ func convert(opt kobject.ConvertOptions) error { return err } - komposeObject := kobject.KomposeObject{ - ServiceConfigs: make(map[string]kobject.ServiceConfig), - } - komposeObject, err = l.LoadFile(opt.InputFiles) + komposeObject, err := l.LoadFile(opt.InputFiles) if err != nil { return err } diff --git a/utils/manifests/generateComponent.go b/utils/manifests/generateComponent.go index 560eb1c0..9ae4c2cd 100644 --- a/utils/manifests/generateComponent.go +++ b/utils/manifests/generateComponent.go @@ -19,7 +19,7 @@ func GenerateComponents(ctx context.Context, manifest string, resource int, cfg crds = cfg.ExtractCrds(manifest) for _, crd := range crds { var parsedCrd cue.Value - if cfg.CrdFilter.IsJson != true { + if !cfg.CrdFilter.IsJson { file, err := yaml.Extract("crds", crd) // first argument is dummy if err != nil { // inability to generate component for a single crd should not affect the rest diff --git a/utils/manifests/utils.go b/utils/manifests/utils.go index b3cd1227..fb3990f7 100644 --- a/utils/manifests/utils.go +++ b/utils/manifests/utils.go @@ -1,13 +1,9 @@ package manifests import ( - "bytes" "context" "encoding/json" "fmt" - "os" - "os/exec" - "path/filepath" "reflect" "regexp" "strings" @@ -111,36 +107,6 @@ func getSchema(parsedCrd cue.Value, cfg Config, ctx context.Context) (string, er return string(output), nil } -func populateTempyaml(yaml string, path string) error { - var _, err = os.Stat(path) - if os.IsNotExist(err) { - var file, err = os.Create(path) - if err != nil { - return err - } - defer file.Close() - } - //delete any previous contents from the file - if err := os.Truncate(path, 0); err != nil { - return err - } - file, err := os.OpenFile(path, os.O_RDWR, 0644) - if err != nil { - return err - } - defer file.Close() - _, err = file.WriteString(yaml) - if err != nil { - return err - } - err = file.Sync() - if err != nil { - return err - } - - return nil -} - // removeMetadataFromCRD is used because in few cases (like linkerd), helm templating might be used there which makes the yaml invalid. // As those templates are useless for component creatin, we can replace them with "meshery" to make the YAML valid func RemoveHelmTemplatingFromCRD(crdyaml *string) { @@ -156,70 +122,6 @@ func RemoveHelmTemplatingFromCRD(crdyaml *string) { *crdyaml = strings.Join(yamlArr, "\n---\n") } -func getCrdnames(s string) []string { - s = strings.ReplaceAll(s, "\"", "") - s = strings.ReplaceAll(s, " ", "") - s = strings.ReplaceAll(s, ",", "") - crds := strings.Split(s, "\n") - if len(crds) <= 2 { - return []string{} - } - return crds[1 : len(crds)-2] // first and last characters are "[" and "]" respectively -} - -func filterYaml(ctx context.Context, yamlPath string, filter []string, binPath string, inputFormat string) error { - var ( - out bytes.Buffer - er bytes.Buffer - ) - filter = append(filter, "-o", "yaml") - getCrdsCmdArgs := append([]string{"--location", yamlPath, "-t", inputFormat, "--filter"}, filter...) - cmd := exec.CommandContext(ctx, binPath, getCrdsCmdArgs...) - //emptying buffers - out.Reset() - er.Reset() - cmd.Stdout = &out - cmd.Stderr = &er - err := cmd.Run() - if err != nil { - return err - } - path := filepath.Join(os.TempDir(), "/test.yaml") - err = populateTempyaml(out.String(), path) - if err != nil { - return ErrPopulatingYaml(err) - } - return nil -} - -// cleanup -func deleteFile(path string) error { - err := os.Remove(path) - if err != nil { - return err - } - return nil -} - -//TODO: After finalizing on where to keep dictionary.json, use that file to initialize dict map in init() -// var dict = map[string]string{} - -// func init() { -// dictf, err := os.Open("./dictionary.json") -// if err != nil { -// return -// } -// byt, err := io.ReadAll(dictf) -// if err != nil { -// return -// } - -// err = json.Unmarshal(byt, &dict) -// if err != nil { -// return -// } -// } - // This helps in formating the leftover fields using a pre-defined dictionary // If dictionary returns true then any other formatting should be skipped // The key in the dictionary contains completely unedited fields that are expected in certain input files @@ -364,8 +266,8 @@ func (ro *ResolveOpenApiRefs) ResolveReferences(manifest []byte, definitions cue if ro.isInsideJsonSchemaProps && (ref == JsonSchemaPropsRef) { // hack so that the UI doesn't crash val["$ref"] = "string" - marVal, err := json.Marshal(val) - if err != nil { + marVal, errJson := json.Marshal(val) + if errJson != nil { return manifest, nil } return marVal, nil @@ -407,8 +309,8 @@ func (ro *ResolveOpenApiRefs) ResolveReferences(manifest []byte, definitions cue if refVal.Err() != nil { return nil, refVal.Err() } - marshalledVal, err := refVal.MarshalJSON() - if err != nil { + marshalledVal, errJson := refVal.MarshalJSON() + if errJson != nil { return nil, err } def, err = ro.ResolveReferences(marshalledVal, definitions, cache) @@ -420,7 +322,7 @@ func (ro *ResolveOpenApiRefs) ResolveReferences(manifest []byte, definitions cue def = cache[path] } if def != nil { - err := replaceRefWithVal(def, val, k) + err = replaceRefWithVal(def, val, k) if err != nil { return def, nil } @@ -429,16 +331,18 @@ func (ro *ResolveOpenApiRefs) ResolveReferences(manifest []byte, definitions cue } } if reflect.ValueOf(v).Kind() == reflect.Map { - marVal, err := json.Marshal(v) + var marVal []byte + var def []byte + marVal, err = json.Marshal(v) if err != nil { return nil, err } - def, err := ro.ResolveReferences(marVal, definitions, cache) + def, err = ro.ResolveReferences(marVal, definitions, cache) if err != nil { return nil, err } if def != nil { - err := replaceRefWithVal(def, val, k) + err = replaceRefWithVal(def, val, k) if err != nil { return def, nil } diff --git a/utils/walker/git.go b/utils/walker/git.go index 502bfc75..17a2985d 100644 --- a/utils/walker/git.go +++ b/utils/walker/git.go @@ -152,7 +152,7 @@ func clonewalk(g *Git) error { // If recurse mode is on, we will walk the tree if g.recurse { - err := filepath.WalkDir(filepath.Join(path, g.root), func(path string, d fs.DirEntry, er error) error { + err = filepath.WalkDir(filepath.Join(path, g.root), func(path string, d fs.DirEntry, er error) error { if d.IsDir() && g.dirInterceptor != nil { return g.dirInterceptor(Directory{ Name: d.Name(), @@ -162,9 +162,9 @@ func clonewalk(g *Git) error { if d.IsDir() { return nil } - f, err := d.Info() + f, errInfo := d.Info() if err != nil { - return err + return errInfo } return g.readFile(f, path) }) @@ -186,24 +186,24 @@ func clonewalk(g *Git) error { } for _, f := range files { - path := filepath.Join(path, g.root, f.Name()) + fPath := filepath.Join(path, g.root, f.Name()) if f.IsDir() && g.dirInterceptor != nil { name := f.Name() go func(name string, path string, filename string) { err := g.dirInterceptor(Directory{ Name: filename, - Path: path, + Path: fPath, }) if err != nil { fmt.Println(err.Error()) } - }(name, path, f.Name()) + }(name, fPath, f.Name()) continue } if f.IsDir() { continue } - err := g.readFile(f, path) + err := g.readFile(f, fPath) if err != nil { fmt.Println(err.Error()) }