Go: local import in non-local package

Go

Go Problem Overview


I have the following file structure:

.
├── bin
│   └── hello
├── pkg
└── src
    └── jacob.uk.com
        ├── greeting
        │   └── greeting.go
        └── helloworld.go

5 directories, 3 files

With the following GOPATH

/Users/clarkj84/Desktop/LearningGo

Upon executing /usr/local/go/bin/go install jacob.uk.com within the src folder, I get the error local import "./greeting" in non-local package

helloworld.go:

package main;
import "./greeting"

func main() {
   
}

Go Solutions


Solution 1 - Go

You can't use local import when specifying a non-local package to go install. If you want the local import to work, first change working directory to src/jacob.uk.com then execute go install (without specifying the package).

Of course having the helloworld.go you provided you will get an compile error: imported and not used. But once you use something from the imported greeting package, it should compile.

But you shouldn't use local imports at all. Instead write:

import "jacob.uk.com/greeting"

And doing so you will be able to compile/run/install it from anywhere.

Solution 2 - Go

Typing go build does not work with relative import paths; you must type go build main.go.

go install does not work at all with relative import paths.

It is documented at https://golang.org/cmd/go/#hdr-Relative_import_paths

See

for explanation.

Solution 3 - Go

You can add the local packages using replace in go 1.11<= go to your go.mod and use "replace" keyword, as below, (you do not need to create a github repo, just add the lines like this)

module github.com/yourAccount/yourModule

go 1.15

require (
	github.com/cosmtrek/air v1.21.2 // indirect
	github.com/creack/pty v1.1.11 // indirect
	github.com/fatih/color v1.9.0 // indirect
	github.com/imdario/mergo v0.3.11 // indirect
	github.com/julienschmidt/httprouter v1.3.0
	github.com/mattn/go-colorable v0.1.7 // indirect
	github.com/pelletier/go-toml v1.8.0 // indirect
	go.uber.org/zap v1.15.0
	golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a // indirect
)

replace (
	github.com/yourAccount/yourModule/localFolder =>"./yourModule/localFolder"
	github.com/yourAccount/yourModule/localFolder =>"./yourModule/localFolder"
)

Then in your main.go =>

import (
	alog "github.com/yourAccount/yourModule/localFolder"
	slog "github.com/yourAccount/yourModule/localFolder"
)

Solution 4 - Go

you can bypass this using the vendor feature
change import "./greeting" to import "greeting"
create the vendor directory mkdir vendor and create a symlink ln -s ../greeting vendor/greeting

Solution 5 - Go

There may several thing going wrong. I will provide following setup.

Check your GOPATH environment variable

The GOPATH variable defines your workspace. You can easily identify the current value if you type "go env".

If you install Go under Windows the GOPATH environment variable is set up automatically during installation process. Nevertheless: It could be that this default path is not your preferred choice. You may safely set this variable to a target directory to your wish.

To change environment variables in Windows look here: https://www.architectryan.com/2018/08/31/how-to-change-environment-variables-on-windows-10/

Check Workspace Layout

If you have decided where your workspace should reside and set up the GOPATH environemnt variable you should create three folders within the workspace:

src, pkg, bin

The folder "src" is the on where your source code reside. "pkg" includes external imports. "bin" contains the compiled sources.

Example Project

Layout within your workspace:

<workspace directory>
--> src
    --> oopexpertutil
        --> x.go
    --> y.go
--> pkg
    --> ...
--> bin
    --> ...

File "x.go"

package oopexpertutil

func checkMe(e error) {
	if e != nil {
		panic(e)
	}
}

File "y.go"

package main

import (
	"fmt"
	"io/ioutil"
	"oopexpertutil"
)

func main() {

	var data string = "Hello World!"
	var dataAsBytes = []byte(data)

	fmt.Println(data)

	err := ioutil.WriteFile("hello_world.txt", dataAsBytes, 0644)

	fmt.Println(err)

	oopexpertutil.checkMe(err)

}

Disappointment...

This setup is still not working. You may have tried out all other answers that stick to workspace or package layout or "go modules" subject. The final point to consider to make this work is:

Change the name of the "checkMe" function of the referenced package to "CheckMe" and update the usage as well...

Go has some convention identifying exported functions from not exported functions of a package by a starting capital letter.

Solution 6 - Go

Name of module has to be a unique string. I think that's why we use a domain name for a module name a lot.

// go.mod
module very-unique

go 1.17

In that module name is very unique, I tried package name I have locally like follows.

import "very-unique/packagename"

And (obviously) I had a file (it was packagename.go in my case) with this line on top.

package packagename

But it didn't work! It finally worked when I made a directory named packagename and moved the file into that directory.

I personally like this solution than using replace. Usually I think we should use replace when we try a copy of existing library locally (with a path).

Solution 7 - Go

If you just want to share code between separate files and not separate packages, here's how to do it:

You don't need to import, you just have to put the source files in the same directory and specify the same package name at the top of each file, and then you can access all the public (Uppercase) functions and types, by referencing them directly, that is, SomeFunction() and not somepackage.SomeFunction()

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionJacob ClarkView Question on Stackoverflow
Solution 1 - GoiczaView Answer on Stackoverflow
Solution 2 - Gouser7610View Answer on Stackoverflow
Solution 3 - GoLinuxView Answer on Stackoverflow
Solution 4 - Gonnnn20430View Answer on Stackoverflow
Solution 5 - GooopexpertView Answer on Stackoverflow
Solution 6 - GokangkyuView Answer on Stackoverflow
Solution 7 - Go1j01View Answer on Stackoverflow