gogopath

Is there a way to run a Go module from another directory


I have the following project structure, outside of GOPATH.

. // Project root
├── Dockerfile
├── .env
├── README.md
└── src
    ├── main.go
    ├── go.mod
    ├── go.sum
    ├── internal
    │   ├── somepackage
    │   │   ├── main.go
    │   │   └── types.go
    │   ├── someother
    │   │   ├── main.go
    │   │   ├── oauth.go
    │   │   └── types.go
    │   └── models
    │       └── main.go
    └── pkg
        ├── somepackage
        │   └── main.go
        └── anotherpackage
            └── main.go

I want to run my Go module code located in the src directory. When I cd into the src directory and go run . or go build . my code, it works perfectly.

When I stand at the root of my project, I am unable to run go run ./src or go build ./src. I get the following error.

src/service.go:8:2: cannot find package "web-service/internal/auth" in any of:
        /usr/lib/go/src/web-service/internal/auth (from $GOROOT)
        /home/miloertas/Packages/go/src/web-service/internal/auth (from $GOPATH)
src/endpoints.go:3:8: cannot find package "web-service/internal/handlers" in any of:
        /usr/lib/go/src/web-service/internal/handlers (from $GOROOT)
        /home/miloertas/Packages/go/src/web-service/internal/handlers (from $GOPATH)

It's important that my source code remains in this src directory. It is equally important that I am able to run and build my code from the root of my project (For example the .env file is located at the root of the repository).

I am therefore looking for a way to run or build my code in the src directory from the root of my project.

I tried moving the go.mod at the root of the project and running and ran go run ./src but this causes issues of its own:


Solution

  • Since Go 1.18, it's now possible to achieve this with Go workspaces.

    Using the following directory structure

    parent-dir/
    └─ go.work
       hello-world/
       ├─ go.mod
       └─ main.go
    

    You can run the hello-world module from the parent-dir using go run hello-world.

    go.work

    go 1.18
    
    use ./hello-world
    

    go.mod

    module hello-world
    
    go 1.18
    

    Note: it is possible, not recommended as pointed out by @Volker