Reputation: 487
I have a package I want to break out my code with called foo
and it's in a subdirectory called utils
. When I try to import it to my main.go it can't find it. Not sure what I'm doing wrong.
Error when running go build
Error:
main.go:7:2: local import "./utils/csrf" in non-local package
So I have folder structured as:
github.com/project
/utils
foo.go
main.go
The package is written as so:
package foo
import (
"fmt"
)
func Bar() {
fmt.Printf("function")
}
Go Mod:
module github.com/project
go 1.15
And I'm trying to import is as so in my main.go
file.
import (
"fmt"
"github.com/project/utils/foo"
)
Upvotes: 0
Views: 1508
Reputation: 1
First, make a folder utils
somewhere. You don't need to do any
github.com/project
folder. Just simply make a utils
folder, and put it somewhere on your hard drive. Then go into that folder, and do go mod init github.com/project/utils
. Then make utils/foo.go
:
package utils
import "fmt"
func Bar() {
fmt.Println("function")
}
Then make a folder utils/utils
. Then make a file utils/utils/main.go
:
package main
import "github.com/project/utils"
func main() {
utils.Bar()
}
Then do go build
. Done.
Upvotes: 2
Reputation: 5197
The error message main.go:7:2: local import "./utils/csrf" in non-local package
comes from here. Barring an unexpected bug, it would imply that your main.go
does not look like:
import (
"fmt"
"github.com/project/utils/foo"
)
as you described, but, rather, something more like:
import (
"fmt"
"./utils/foo"
)
However, relative import paths cannot be used in import
statements in module mode. (The actual error message you get in module mode is somewhat confusing due to a bug in the go
command, for which I've filed https://golang.org/issue/47088.)
In module mode, the module path declared in the go.mod
file — presumably module github.com/project
for your example — is a prefix of the import path, and you are intended to use the complete path in import
statements.
So the solution here is likely:
cd
to the project
folder.go mod init github.com/project
.import
statements to use the full path instead of the relative one throughout the project:
$ sed -i 's,"\./utils,"github.com/project/utils,' $(find -name *.go)
That should change your main.go
to actually read:
import (
"fmt"
"github.com/project/utils/foo"
)
But now there is one more step: Go supports only one package per directory, and the package name declared with the package
directive in the .go
source file is (perhaps confusingly!) not a suffix of the package import path — it is completely independent.
So in order to make that import
statement work, you need an extra layer of directory structure:
mkdir utils/foo
mv utils/foo.go utils/foo/foo.go
Now you have a single module, github.com/project
, containing two packages: github.com/project
with source file ./main.go
, and github.com/project/utils/foo
with source file ./utils/foo/foo.go
.
Upvotes: 1