pact-foundation / pact-go

Golang version of Pact. Pact is a contract testing framework for HTTP APIs and non-HTTP asynchronous messaging systems.
http://pact.io
MIT License
857 stars 109 forks source link

can't run linter goanalysis_metalinter: inspect: failed to load package sugar: could not load export data: no export data for #212

Closed edouard-lopez closed 2 years ago

edouard-lopez commented 2 years ago

Software versions

Expected behaviour

Should lint file correctly

Actual behaviour

❯ make lint
go install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.45
golangci-lint run --skip-dirs cmd/pactgoconsumerexample_tester
ERRO Running error: 1 error occurred:
    * can't run linter goanalysis_metalinter: inspect: failed to load package sugar: could not load export data: no export data for "github.com/pact-foundation/pact-go/v2/sugar"

make: *** [Makefile:85: lint] Error 3

Steps to reproduce

Below is the file importing sugar

internal/b2b/b2b_contract_test.go
package b2b

import (
    "context"
    "fmt"
    "net/http"
    "os"
    "testing"

    "github.com/pact-foundation/pact-go/v2/sugar"

    "github.com/stretchr/testify/require"
)

func TestClientProduct(t *testing.T) {

    mockProvider, err := sugar.NewV2Pact(sugar.MockHTTPProviderConfig{
        Consumer: "ms.pact-consumer-example-for-go.b2b",
        Provider: "ms.pact-provider-example-for-go",
        PactDir:  "../../contracts",
    })
    require.NoError(t, err)

    t.Run("the product 1 exists", func(t *testing.T) {
        // Setup my expected interactions
        mockProvider.AddInteraction().
            Given("A product with id 1 exists").
            UponReceiving("a request Product 1").
            WithRequest(http.MethodGet, sugar.S("/api/v1/product/1")).
            WillRespondWith(http.StatusOK).
            WithJSONBody(sugar.Map{
                "id":             sugar.Integer(1),
                "name":           sugar.S("foo 2"),
                "brand":          sugar.S("bar 2"),
                "price_excl_tax": sugar.Decimal(20.125),
            }).
            WithHeader("Content-Type", sugar.Term("application/json; charset=utf-8", `application/json`))

        // Wrap my test in an callback function
        test := func(config sugar.MockServerConfig) error {
            var product Product
            var err error
            var myService B2b

            // set up the configuration for the driver
            baseURL := fmt.Sprintf("http://%s:%d", config.Host, config.Port)

            if err = os.Setenv("PACTGOCONSUMEREXAMPLE_PACTGOPROVIDEREXAMPLE_URL", baseURL); err != nil {
                return err
            }

            // instanciate the service
            if myService, err = New(); err != nil {
                return err
            }

            product, err = myService.Product(context.Background(), 1)
            require.NoError(t, err)

            require.Equal(t, 1, product.ID)
            require.Equal(t, "foo 2", product.Name)
            require.Equal(t, "bar 2", product.Brand)
            require.Equal(t, 20.125, product.Price)

            return nil
        }

        // Execute the test and check the expectation
        err := mockProvider.ExecuteTest(t, test)
        require.NoError(t, err)
    })
    t.Run("the product 2 doesn't exists", func(t *testing.T) {
        // Setup my expected interactions
        mockProvider.AddInteraction().
            Given("A product with id 2 does not exist").
            UponReceiving("a request Product 2").
            WithRequest(http.MethodGet, sugar.S("/api/v1/product/2")).
            WillRespondWith(http.StatusNotFound).
            WithHeader("Content-Type", sugar.Term("application/json; charset=utf-8", `application/json`))

        // Wrap my test in an callback function
        test := func(config sugar.MockServerConfig) error {
            var product Product
            var err error
            var myService B2b

            // set up the configuration for the driver
            baseURL := fmt.Sprintf("http://%s:%d", config.Host, config.Port)

            if err = os.Setenv("PACTGOCONSUMEREXAMPLE_PACTGOPROVIDEREXAMPLE_URL", baseURL); err != nil {
                return err
            }

            // instanciate the service
            if myService, err = New(); err != nil {
                return err
            }

            product, err = myService.Product(context.Background(), 2)
            require.Error(t, err)
            require.Equal(t, Product{}, product)

            return nil
        }

        // Execute the test and check the expectation
        err := mockProvider.ExecuteTest(t, test)
        require.NoError(t, err)
    })
}

Relevent log files

Please ensure you set logging to DEBUG and attach any relevant log files here (or link from a gist).

mefellows commented 2 years ago

https://github.com/golangci/golangci-lint/discussions/1920?sort=old seems to suggest an invalid go modules file can cause this - are you able to validate you have a correct go.sum and go.mod file?

edouard-lopez commented 2 years ago

I aligned the go version from the go.mod file with the docker image I'm using (golang:1.18-buster). But still happening

Here is a verbose output of the command.

golangci-lint run --verbose --skip-dirs cmd/pactgoconsumerexample_tester
level=info msg="[config_reader] Config search paths: [./ /go/src/app/cmd /go/src/app /go/src /go / /root]"
level=info msg="[config_reader] Used config file .golangci.yaml"
level=info msg="[lintersdb] Active 59 linters: [asciicheck bidichk bodyclose containedctx contextcheck deadcode decorder dogsled dupl durationcheck errcheck errchkjson errname errorlint exhaustive exportloopref forbidigo forcetypeassert funlen gochecknoglobals gocognit goconst gocritic gocyclo godox goerr113 gomnd gomoddirectives gomodguard goprintffuncname gosec gosimple govet grouper ineffassign lll maintidx makezero nakedret nilerr nilnil nlreturn noctx prealloc promlinter rowserrcheck sqlclosecheck staticcheck structcheck stylecheck tenv tparallel typecheck unconvert unparam unused varcheck varnamelen wastedassign]"
level=info msg="[loader] Go packages loading at mode 575 (imports|types_sizes|compiled_files|deps|exports_file|files|name) took 15.747516569s"
level=info msg="[runner/filename_unadjuster] Pre-built 0 adjustments in 430.585µs"
level=warning msg="[linters context] bodyclose is disabled because of go1.18. You can track the evolution of the go1.18 support by following the https://github.com/golangci/golangci-lint/issues/2649."
level=warning msg="[linters context] contextcheck is disabled because of go1.18. You can track the evolution of the go1.18 support by following the https://github.com/golangci/golangci-lint/issues/2649."
level=info msg="[linters context/goanalysis] analyzers took 5.168891374s with top 10 stages: exhaustive: 2.283305473s, inspect: 898.546146ms, bidichk: 570.0985ms, printf: 467.143074ms, ctrlflow: 466.030231ms, findcall: 381.718162ms, forbidigo: 25.121657ms, gocritic: 17.211745ms, the_only_name: 14.364332ms, unconvert: 9.836893ms"
level=warning msg="[runner] Can't run linter goanalysis_metalinter: inspect: failed to load package sugar: could not load export data: no export data for \"github.com/pact-foundation/pact-go/v2/sugar\""
level=warning msg="[linters context] gosimple is disabled because of go1.18. You can track the evolution of the go1.18 support by following the https://github.com/golangci/golangci-lint/issues/2649."
level=warning msg="[linters context] nilerr is disabled because of go1.18. You can track the evolution of the go1.18 support by following the https://github.com/golangci/golangci-lint/issues/2649."
level=warning msg="[linters context] noctx is disabled because of go1.18. You can track the evolution of the go1.18 support by following the https://github.com/golangci/golangci-lint/issues/2649."
level=warning msg="[linters context] rowserrcheck is disabled because of go1.18. You can track the evolution of the go1.18 support by following the https://github.com/golangci/golangci-lint/issues/2649."
level=warning msg="[linters context] sqlclosecheck is disabled because of go1.18. You can track the evolution of the go1.18 support by following the https://github.com/golangci/golangci-lint/issues/2649."
level=warning msg="[linters context] staticcheck is disabled because of go1.18. You can track the evolution of the go1.18 support by following the https://github.com/golangci/golangci-lint/issues/2649."
level=warning msg="[linters context] structcheck is disabled because of go1.18. You can track the evolution of the go1.18 support by following the https://github.com/golangci/golangci-lint/issues/2649."
level=warning msg="[linters context] stylecheck is disabled because of go1.18. You can track the evolution of the go1.18 support by following the https://github.com/golangci/golangci-lint/issues/2649."
level=warning msg="[linters context] tparallel is disabled because of go1.18. You can track the evolution of the go1.18 support by following the https://github.com/golangci/golangci-lint/issues/2649."
level=warning msg="[linters context] unparam is disabled because of go1.18. You can track the evolution of the go1.18 support by following the https://github.com/golangci/golangci-lint/issues/2649."
level=warning msg="[linters context] wastedassign is disabled because of go1.18. You can track the evolution of the go1.18 support by following the https://github.com/golangci/golangci-lint/issues/2649."
level=warning msg="[linters context] unused is disabled because of go1.18. You can track the evolution of the go1.18 support by following the https://github.com/golangci/golangci-lint/issues/2649."
level=info msg="[runner] processing took 3.019µs with stages: max_same_issues: 731ns, skip_dirs: 325ns, nolint: 261ns, max_from_linter: 226ns, autogenerated_exclude: 166ns, cgo: 147ns, skip_files: 136ns, exclude: 133ns, path_prettifier: 126ns, uniq_by_line: 121ns, identifier_marker: 119ns, filename_unadjuster: 113ns, exclude-rules: 59ns, source_code: 56ns, path_shortener: 54ns, severity-rules: 50ns, sort_results: 50ns, max_per_file_from_linter: 49ns, diff: 49ns, path_prefixer: 48ns"
level=info msg="[runner] linters took 3.309609006s with stages: goanalysis_metalinter: 3.309464202s, bodyclose: 11.266µs, nilerr: 10.043µs, tparallel: 7.261µs, unparam: 7.176µs, unused: 6.829µs, noctx: 6.68µs, structcheck: 6.473µs, wastedassign: 6.272µs, gosimple: 6.132µs, staticcheck: 5.57µs, rowserrcheck: 5.264µs, stylecheck: 5.153µs, sqlclosecheck: 4.988µs, contextcheck: 4.422µs"
level=error msg="Running error: 1 error occurred:\n\t* can't run linter goanalysis_metalinter: inspect: failed to load package sugar: could not load export data: no export data for \"github.com/pact-foundation/pact-go/v2/sugar\"\n\n"
level=info msg="Memory: 192 samples, avg is 102.2MB, max is 654.2MB"
level=info msg="Execution took 19.061678941s"
make: *** [Makefile:87: lint] Error 3
KEdore commented 2 years ago

Was this ever resolved?

mefellows commented 2 years ago

I'm going to kill the sugar package. It was always an experimental concept, but the longer it has been out the more I feel it's an anti-pattern.

I'm currently focussed on making the package layout more sensible, and during that process will remove the sugar package.

It will be gone in the next beta release, which will contain support for v4 pacts and plugins.

KEdore commented 2 years ago

Ahh ok @mefellows . I am getting a similar error but I am getting this:

Can't run linter goanalysis_metalinter: buildir: failed to load package native: could not load export data: no export data for \"http://github.com/pact-foundation/pact-go/v2/internal/native\
mefellows commented 2 years ago

Interesting. If you can figure out why it's failing and how to address it, happy to do so.

It could be because that package has CGo code in it, and maybe it doesn't like that.

ldez commented 2 years ago

Hello,

the problem inside golangci-lint is now fixed, and it will be shipped in the next bug fix release.

mefellows commented 2 years ago

Great, thanks for the update!

I'm going to close this issue unless there is something required by Pact to fix.