0

Envs

GO111MODULE=on
golang:1.15.2-alpine

What I want to do

I implemented some features in a local project and I want to confirm the behavior before pushing changes to the remote repo.
But my project can't access the new package.

Error text

When docker-compose run 'go build' I got his error.
Both 'github.com/Asuha-a/URLShortener/api/pb/url' and 'github.com/Asuha-a/URLShortener/api/utility' don't exist in the remote repo because it's not pushed yet.

main.go:10:2: module github.com/Asuha-a/URLShortener/api@latest found (v0.0.0-20201114002535-3dac2ebd322a), but does not contain package github.com/Asuha-a/URLShortener/api/pb/url
main.go:12:2: module github.com/Asuha-a/URLShortener/api@latest found (v0.0.0-20201114002535-3dac2ebd322a), but does not contain package github.com/Asuha-a/URLShortener/api/utility

Project architecture

I deleted some of the files look like not related to this issue.

$ tree                                                                                               
.                                                                                                    
├── api                                                                                                                                                                               
│   ├── Dockerfile                                                                                   
│   ├── go.mod                                                                                       
│   ├── go.sum
│   ├── main.go
│   ├── pb
│   │   ├── url // new package
│   │       ├── url_grpc.pb.go
│   │       ├── url.pb.go
│   │       └── url.proto
│   ├── services
│   │   ├── url
│   │   │   ├── db
│   │   │   │   ├── settings.go
│   │   │   │   └── url.go
│   │   │   ├── Dockerfile
│   │   │   ├── go.mod
│   │   │   ├── go.sum
│   │   │   └── main.go // failed building
│   └── utility // new package
│       ├── jwt.go
│       └── url.go
├── docker-compose.yml

What I tried

I found this issue.
Importing local changes of a package without pushing code in Go
That says I can access local packages by adding 'replace MODULE_URL => /PATH/TO/MODULE/DIR'.

I edited the 'api/services/url/go.mod' like this.

module github.com/Asuha-a/URLShortener/api/services/url

go 1.15

replace github.com/Asuha-a/URLShortener/api => ../../.
require (
    github.com/jackc/pgx/v4 v4.9.2 // indirect
    github.com/satori/go.uuid v1.2.0
    golang.org/x/crypto v0.0.0-20201112155050-0c6587e931a9 // indirect
    golang.org/x/text v0.3.4 // indirect
    golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
    google.golang.org/grpc v1.33.2
    gorm.io/datatypes v1.0.0
    gorm.io/driver/postgres v1.0.5
    gorm.io/gorm v1.20.6
)

But I got this error:

main.go:10:2: module github.com/Asuha-a/URLShortener/api@latest found (v0.0.0-20201114002535-3dac2ebd322a, replaced by ../../.), but does not contain package github.com/Asuha-a/URLShortener/api/pb/url
main.go:12:2: module github.com/Asuha-a/URLShortener/api@latest found (v0.0.0-20201114002535-3dac2ebd322a, replaced by ../../.), but does not contain package github.com/Asuha-a/URLShortener/api/utility

Then I tried the full path '/home/asuha/go/src/github.com/Asuha-a/URLShortener/api'.

But I got this error:

main.go:10:2: github.com/Asuha-a/URLShortener/api@v0.0.0-00010101000000-000000000000: replacement directory /home/asuha/go/src/github.com/Asuha-a/URLShortener/api does not exist
main.go:12:2: github.com/Asuha-a/URLShortener/api@v0.0.0-00010101000000-000000000000: replacement directory /home/asuha/go/src/github.com/Asuha-a/URLShortener/api does not exist

I want to know

How to fix this error?

Jonathan Hall
  • 75,165
  • 16
  • 143
  • 189
Asuha
  • 231
  • 1
  • 5
  • 16

1 Answers1

2

Some basics first:

  • A module is a set of packages versioned together.
  • A module has a name declared in the go.mod, e.g. github.com/anyone/someproject
  • A package is imported by its import path (the import path basically is package identity).
  • A package belonging to a module must have an import path beginning with the module name. In the example above any package belonging to the module github.com/anyone/someproject must have an import path like e.g. github.com/anyone/someproject/whatever/hierarchy/pkgname
  • You never need to replace packages from the same module. replace is for replacing other modules.

You declared the module

 module github.com/Asuha-a/URLShortener/api/services/url

That makes the name of your module "github.com/Asuha-a/URLShortener/api/services/url" and only packages with import path like module "github.com/Asuha-a/URLShortener/api/services/url/I/really/like/deeply/nested/stuff" would belong to that package.

Clearly you utility package (btw. don't do such packages, this is fundamental code smell!) doesn't belong to your module: You probably try to import it as "github.com/Asuha-a/URLShortener/api/utiliyt" but this is not part of the module "github.com/Asuha-a/URLShortener/api/services/url".

The fact that the folder utility is "below" the go.mod file in the filesystem doesn't overrule the fact that your module declares on its first line: "All my packages have import paths starting with github.com/Asuha-a/URLShortener/api/services/url! Anything else does not belong to me!"

You probably should name your module at least module github.com/Asuha-a/URLShortener/api (if not module github.com/Asuha-a/URLShortener).

I urge you to (re-)read "How to Write Go Code" and stick to it.

Takeaway: Modules are really just a set of packages with the same import path prefix (the module name) versioned together.

Volker
  • 40,468
  • 7
  • 81
  • 87
  • I understand that cause of failure of importing. I realized that my project architecture seems to get stuck soon. I will consider refactoring. Thank you. – Asuha Nov 17 '20 at 09:04