How to use internal packages with go modules?
Asked Answered
T

4

10

I am using go modules in my project. I have shared code in the internal folder.

.
├── README.md
├── internal
│   └── shared
│       ├── request.go
│       └── request_test.go
└── web
    ├── README.md
    └── go
        └── src
            └── webservice
                ├── go.mod
                ├── go.sum
                └── main.go

I am not able to access the internal/shared from webservice while using go modules. I get the following error:

package internal/shared is not in GOROOT (/usr/local/go/src/internal/shared)

While importing from webservice in main.go:

import "internal/shared"

Note: I am trying to share internal/shared with another mod that is not listed above.

How to fix this issue?

Topee answered 20/4, 2020 at 17:38 Comment(1)
internal isn't part of the webservice module. Either move internal into the correct location, or make the entire project a single module. The code layout is quite unusual, is there a reason it's structured in this way?Canella
T
6

I ended up fixing by adding a go.mod to the internal/shared and editing the go.mod in webservice with the following:

module webservice

go 1.14

replace example.com/shared => ../../../../internal/shared/

require (
    github.com/gorilla/mux v1.7.4
    github.com/spf13/viper v1.6.3
    github.com/stretchr/testify v1.5.1
    example.com/shared v0.0.0-00010101000000-000000000000
)

example.com/shared v0.0.0-00010101000000-000000000000 was generated by "go mod init webservice"

Topee answered 24/4, 2020 at 22:15 Comment(0)
D
11

Your go.mod inside web/go/src/webservice indicates that this package is located in a different module than your internal/shared package. It should work when you move your go.mod and go.sum at the root of the whole project. Then the web/go/src/webservice and internal/shared packages will be inside one go module.

This worked for me:

    .
    ├── go.mod
    ├── go.sum
    ├── internal
    │   └── shared
    │       └── request.go
    │  
    └── web
        └── go
            └── src
                └── webservice
                    └── main.go

And you should include the whole go-module path when importing the internal/shared package in your main.go.

So, inside your main.go the import should look like import "$your-go-module/internal/shared"

More info on internal packages here

Denice answered 20/4, 2020 at 21:55 Comment(0)
T
6

I ended up fixing by adding a go.mod to the internal/shared and editing the go.mod in webservice with the following:

module webservice

go 1.14

replace example.com/shared => ../../../../internal/shared/

require (
    github.com/gorilla/mux v1.7.4
    github.com/spf13/viper v1.6.3
    github.com/stretchr/testify v1.5.1
    example.com/shared v0.0.0-00010101000000-000000000000
)

example.com/shared v0.0.0-00010101000000-000000000000 was generated by "go mod init webservice"

Topee answered 24/4, 2020 at 22:15 Comment(0)
E
1

In my case, the code was compiling fine, but the GoLand IDE was unable to recognise the imports. The issue was exactly as described here.

I'm using go modules and a directory outside of the GOPATH. External dependencies are recognized just fine, packages inside my projects "cannot be found" by GoLand.

The fix is to tick the checkbox for Enable Go Modules (vgo) integration under Settings/Preference -> Go -> Go Modules (vgo).

Here is the screenshot for the same.

enter image description here

Extradition answered 20/5, 2021 at 5:7 Comment(0)
A
0

If you want to share libraries in Monorepo, we use go mod edit -require and go mod edit -replace to place each of these dependencies in the go.mod files for each of the services that require the shared packages.

Given

monorepo/
        |_service-1
                |_api/
                |_main.go
                |_go.mod
                |_go.sum
        |_service-2
                |_api/
                |_main.go
                |_go.mod
                |_go.sum
        |_shared_package_1
                |_helpers.go
                |_go.mod
                |_go.sum
        |_shared_package_2
                |common.go
                |_go.mod
                |_go.sum
cd service-1
go mod edit -require=passage.id/[email protected]
go mod edit -replace=passage.id/[email protected]=../shared_package_1
go mod edit -require=passage.id/[email protected]
go mod edit -replace=passage.id/[email protected]=../shared_package_1

After doing this, we are able to use any of the functions declared in any of these shared packages inside of the service-1 microservice the same way we would an external package.

Refer to this doc

Angelesangelfish answered 7/4, 2022 at 23:49 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.