简体   繁体   中英

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:

  • The go command is now unable to locate all the sub-packages in internal and pkg
  • VSCode is now lost and executing tests is impossible for some reasons (Mainly because all sub-packages are not found).

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

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).

These two requirements are contradictory. You have to let go of one.

Especially the second one is unfounded: Do not use go run, use go build. Make the path to look for the.env file a command line option to your program (Go is not PHP or JavaScript, there simply is no project or source root for the executing binary). Or build the executable somewhere but execute it in you project root.

Note that having a src folder is -- to put it mildly -- uncommon .

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:

Well, start by not using go run at all, use go build . And then try building the actual main package. All the go tooling works best on packages , not on file system folders. If your module is named playing.hardball/for-unspecific-reasons and package main is in src try go build playing.hardball/for-unspecific-reasons/src .

Takeaways even if this doesn't work out the way you want:

  • Do not use go run . The reasons are manyfold, it is useful to run single file scripts and a loaded footgun for basically every other use case.
  • The go tool works on import paths . In simple cases the import path can be inferred from the filesystem.
  • A compiled executable has no notion of a "project directory", "source", "classpath" or whatever, it is a standalone executable runnable everywhere and completely detached from its sources.
  • Make all filesystem lookup path a configuration option (cmdline flag or environment variable); provide practical defaults (eg ./ ); use that when running your executable to announce where to find static stuff like.env files, templates, icons, css files, etc.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM