Using subpackages with go mod locally
Asked Answered
G

2

16

I have a go package located on my filesystem (not in the $GOPATH), called bitbucket.org/me/awesome.

~/awesome> tree
.
├── main.go
├── go.mod
├── go.sum
├── subpackageA
│   └── main.go

My go.mod looks like:

module bitbucket.org/me/awesome

require (
       ... # lots of external dependencies
)

replace bitbucket.org/me/awesome => ./

In main.go in my top-level directory, I call a subpackage like follows:

import "bitbucket.org/me/awesome/subpackageA"

which all seems pretty normal. go get works. However, when I clone this entire repository somewhere else (say in a Docker image) and run go get for the first time, I get errors like:

package bitbucket.org/me/awesome/subpackageA: https://api.bitbucket.org/2.0/repositories/me/awesome?fields=scm: 403 Forbidden,

which means it's not using the local filesystem version of the packages, even though I told it to with the replace directive in the go.mod file.

What am I doing wrong? How do I ensure that subpackages are used from the filesystem instead of attempting to be fetched from the internet?

Giaour answered 18/11, 2018 at 21:50 Comment(5)
Yoe seem to have a replace directive for bitbucket.org/me/awesome only but the problem is with bitbucket.org/me/awesome/subpackageA. Do not think of a package in a folder as a subpackage: It is not. It is a standalone package without any relation to what is in the "parent" folder.Outcast
@Outcast thanks, that was the tip that fixed this problem for me (adding other replace lines for subpackages). Do you want to add your comment as an answer?Giaour
I don't quite understand this problem statement. It seems all the packages in question here are all in the same bitbucket.org/me/awesome module, and packages within the same module should find each other automatically without needing a replace directive.Aeon
(Also, replace directives only operate on modules as the left-side and right-side arguments, and not on subpackages or packages, unless a package is in the root of the module, in which case the package path and module path are the same, but even then the replace directive is really operating at the module level).Aeon
There is a bit more here on how packages find each other within the same module, and how that relates overall module structure.Aeon
O
16

Go has no (real) notion of "subpackage". All packages are basically treated equal. This means that a replace bitbucket.org/me/awesome does not influence package bitbucket.org/me/awesome/subpackageA as these are two individual, unrelated packages. The folder layout does not introduce a relation of subpackageA to awsome, or the other way around *).

So you need to add an individual replace directive for subpackageA

replace bitbucket.org/me/awesome/subpackageA => ./subpackageA

*) Nitpicking for absolute correctness: Folder layout does have influence for folders named internal (cannot be imported from other projects), for folders named vendor (which may contain vendored packages) and searching for a go.mod file stops at the repo root.

Outcast answered 19/11, 2018 at 9:28 Comment(2)
Where should I put this code: replace bitbucket.org/me/awesome/subpackageA => ./subpackageA Or is it just a step? Pls be clear.Dodson
@RajeshPaul in go.mod. Please read the Tutorials in go.dev/doc carefully (once more).Outcast
S
3

For another approach, you can have go.mod like this:

module awesome

Then call subpackage like this:

import "awesome/subpackageA"

https://golang.org/doc/code.html

Selassie answered 30/12, 2020 at 17:43 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.