Importing subdirectory as go module - go

I'm trying to import go module from subdirectory. My repository looks like
+$ tree .
.
└── bar
├── bar.go
└── go.mod
1 directory, 2 files
+$ cat bar/go.mod
module github.com/graywolf/foo/bar
go 1.13
+$ cat bar/bar.go
package bar
func Bar() string {
return "bar"
}
when pushed to github this source code runs fine
+$ cat github.go
package main
import (
"fmt"
"github.com/graywolf/foo/bar"
)
func main() {
fmt.Println(bar.Bar())
}
+$ go run github.go
go: finding github.com/graywolf/foo latest
go: finding github.com/graywolf/foo/bar latest
go: downloading github.com/graywolf/foo v0.0.0-20191019144834-ffb419608ae6
go: extracting github.com/graywolf/foo v0.0.0-20191019144834-ffb419608ae6
bar
However it stops working when I push it to different git hosting. I tweak the url
diff --git a/bar/go.mod b/bar/go.mod
index 7407848..6134a24 100644
--- a/bar/go.mod
+++ b/bar/go.mod
## -1,3 +1,3 ##
-module github.com/graywolf/foo/bar
+module git.sr.ht/~graywolf/foo/bar
go 1.13
commit and push it and try to run it
+$ cat sr.go
package main
import (
"fmt"
"git.sr.ht/~graywolf/foo/bar"
)
func main() {
fmt.Println(bar.Bar())
}
+$ go run sr.go
go: finding git.sr.ht/~graywolf/foo latest
go: downloading git.sr.ht/~graywolf/foo v0.0.0-20191019153505-33a4721605aa
go: extracting git.sr.ht/~graywolf/foo v0.0.0-20191019153505-33a4721605aa
build command-line-arguments: cannot load git.sr.ht/~graywolf/foo/bar: module git.sr.ht/~graywolf/foo#latest (v0.0.0-20191019153505-33a4721605aa) found, but does not contain package git.sr.ht/~graywolf/foo/bar
It looks like github and source hut provide different go-import meta tag, notice the missing .git for source hut.
+$ curl -sSf https://github.com/graywolf/foo?go-get=1 | grep -A1 go-import
<meta name="go-import" content="github.com/graywolf/foo git https://github.com/graywolf/foo.git">
+$ curl -sSf https://git.sr.ht/~graywolf/foo?go-get=1 | grep -A1 go-import
<meta name="go-import"
content="git.sr.ht/~graywolf/foo git https://git.sr.ht/~graywolf/foo">
When I edit the source code to use foo.git it does find the module, but provide different error message:
+$ go run sr.go
go: finding git.sr.ht/~graywolf/foo.git latest
go: finding git.sr.ht/~graywolf/foo.git/bar latest
go: downloading git.sr.ht/~graywolf/foo.git v0.0.0-20191019153505-33a4721605aa
go: downloading git.sr.ht/~graywolf/foo.git/bar v0.0.0-20191019153505-33a4721605aa
go: extracting git.sr.ht/~graywolf/foo.git v0.0.0-20191019153505-33a4721605aa
go: extracting git.sr.ht/~graywolf/foo.git/bar v0.0.0-20191019153505-33a4721605aa
go: git.sr.ht/~graywolf/foo.git/bar: git.sr.ht/~graywolf/foo.git/bar#v0.0.0-20191019153505-33a4721605aa: parsing go.mod:
module declares its path as: git.sr.ht/~graywolf/foo/bar
but was required as: git.sr.ht/~graywolf/foo.git/bar
Btw both (github and source hut) works fine when the go.mod is in the root of the repository, issue happens only when it is in a subdirectory.
I guess my question is what can I do about it. Did anyone run into something like this? Why doesn't go just clone the ~graywolf/foo and not check the bar subdirectory?

Related

Can't load package in brand new Go project

I'm trying modules in Go. I'm outside the GOPATH and using version 1.12.6:
GOBIN="/home/x80486/Workshop/go/bin/"
GOPATH="/home/x80486/Workshop/go/"
GOROOT="/home/x80486/.asdf/installs/golang/1.12.6/go/"
I created a new project and initialized it as a module inside: /home/x80486/Workshop/Development/gauge-basics. I then created a file example_spec.go with this content:
package stepImpl
import (
"github.com/getgauge-contrib/gauge-go/gauge"
)
var _ = gauge.Step("Run me before any other", func() {})
...and I ran go test:
[x80486#uplink gauge-basics]$ go test
go: finding github.com/getgauge-contrib/gauge-go/gauge latest
go: finding github.com/getgauge/common latest
go: finding github.com/golang/protobuf/proto latest
go: finding github.com/dmotylev/goproperties latest
? github.com/x80486/gauge-basics [no test files]
Everything is somehow OK, but as soon as I move this file into a folder named stepImpl, nothing works:
[x80486#uplink gauge-basics]$ go build
can't load package: package github.com/x80486/gauge-basics: unknown import path "github.com/x80486/gauge-basics": cannot find module providing package github.com/x80486/gauge-basics
I can't understand why moving a file to a folder with the package name would break the project.
This is the generated go.mod file:
module github.com/x80486/gauge-basics
go 1.12
require (
github.com/dmotylev/goproperties v0.0.0-20140630191356-7cbffbaada47 // indirect
github.com/getgauge-contrib/gauge-go v0.1.3 // indirect
github.com/getgauge/common v0.0.0-20190514095629-619e107433ce // indirect
github.com/golang/protobuf v1.3.2 // indirect
)
There are no .go files under github.com/x80486/gauge-basics, because you moved them under a different directory. You can run go build under the directory containing the source files or add another .go in the gauge-basics directory importing them.

Go Modules - how to reference a branch in GitHub

I'm using Coreos OIDC library and would like to know how to reference (in go.mod file) a branch, since they don't develop under master but use v2 instead.
I tried github.com/coreos/go-oidc#v2 but I get:
go: github.com/coreos/go-oidc#v2#v2.0.0+incompatible: invalid github.com/ import path "github.com/coreos/go-oidc#v2"
go: error loading module requirements
The phrase import path in the error message suggests that somewhere in your code you have written something like:
import "github.com/coreos/go-oidc#v2"
But the import path of a Go package does not include its version: only the entries in the go.mod and go.sum files do.
So instead you should write:
import "github.com/coreos/go-oidc"
and update your go.mod and go.sum files by running
go get -d github.com/coreos/go-oidc#v2
That should result in an entry in your go.mod file like:
require github.com/coreos/go-oidc v2.0.0+incompatible

How to import specific package from Go module?

Golang 1.11beta2 introduced experimental support for Modules.
I am failing to import a specific package from a go module.
This is the error when building the application:
$ go install
go: downloading github.com/udhos/modhello/modlib/lib v1.0.0
go: finding github.com/udhos/modhello latest
go: import "github.com/udhos/modhello/modapp" ->
import "github.com/udhos/modhello/modlib/lib": cannot find module providing package github.com/udhos/modhello/modlib/lib
Why is the import shown above failing?
This is the package 'lib' from module 'modlib':
# repo: modhello
# module: modlib
# package: lib
$ cat modhello/modlib/lib/modlib.go
package lib
func Sum(a, b int) int {
return a + b
}
$ cat modhello/modlib/go.mod
module github.com/udhos/modhello/modlib
This is the application 'modapp' :
$ cat modhello/modapp/main.go
package main
import (
"log"
"github.com/udhos/modhello/modlib/lib"
)
func main() {
run(1, 2)
}
func run(a, b int) {
log.Printf("Sum(%d,%d) = %d", a, b, lib.Sum(a, b))
}
$ cat modhello/modapp/go.mod
module github.com/udhos/modhello/modapp
require github.com/udhos/modhello/modlib v1.0.0
The git repository is tagged with 'modlib/v1.0.0'. This is how one publishes a version for a module.
Go version:
$ go version
go version go1.11beta2 linux/amd64
$ git --version
git version 2.18.0
I have posted this doubt also on golang-nuts: Host two distinct modules in one git repo?
go clean -modcache fixed the issue.
More details here: https://github.com/golang/go/issues/26695

Can't build golang project with absolute package path

I am struggling with my travis-ci build.
Here the arborescence of my project:
- github.com
- src
- MyLib
- MyLibImpl.go
- main.go
The main.go is referencing MyLib like this
package main
import "fmt"
import MyLib "github.com/hako910/GolangTest/src/MyLib"
func main() {
fmt.Printf("%v", MyLib.HelloWorld())
}
It works great on my machine but fails in travis-ci with this message:
$ go get -t -v ./...
github.com/hako910/GolangTest (download)
package github.com/hako910/GolangTest/src/MyLib: /home/travis/gopath/src/github.com/hako910/GolangTest exists but /home/travis/gopath/src/github.com/hako910/GolangTest/.git does not - stale checkout?
The command "eval go get -t -v ./... " failed. Retrying, 2 of 3.
Here is my source code https://github.com/hako910/GolangTest and here is my travis-ci build https://travis-ci.org/hako910/GolangTest/jobs/348845103
What is wrong with my configuration?

go get/build can't resolve a local-only project package

project.go:6:2: cannot find package "example.com/project/package" in any of:
/usr/local/Cellar/go/1.1.2/libexec/src/pkg/example.com/project/package (from $GOROOT)
/Users/me/go/src/example.com/project/package (from $GOPATH)
Fetching https://example.com/project/package?go-get=1
ignoring https fetch with status code 404 Fetching http://example.com/project/package?go-get=1
Parsing meta tags from http://example.com/project/package?go-get=1 (status code 404)
import "example.com/project/package": parse http://example.com/project/package?go-get=1: no go-import meta tags
package example.com/project/package: unrecognized import path "example.com/project/package"
Why can't go get/build find the local package. I understand go get will fail on my repo because it's bare, but it seems like go get is completely ignoring the local file, forcing me to commit and push my code before I can compile it. This is, per the snippet, OSX 10.8 and Go 1.1.2 installed via brew. GOPATH is set to /Users/me/go and GOROOT is empty.
I should note that I don't have this problem at all when using go get in gitbash on my Windows machine. I've tried all the google-fu I can think of to search this, but everyone claims you can use relative "project/package" imports, which also completely fail in this case.
Upgrading from go1.1.2 to go1.2 through brew upgrade go fixed this problem
You can work with code locally without having pushed it - you just need your folder structure to mimic the import path.
Put your library code inside a src/ directory, with a folder structure mimicking the import path:
[15:42] foa:home $ tree
.
├── myprogram.go
└── src
└── example.com
└── project
└── mypackage
└── mypackage.go
Then set GOPATH to the directory that has src/ in it, and you'll be able to build the project:
[15:42] foa:home $ export GOPATH=`pwd`
[15:42] foa:home $ go build
Here's myprogram.go:
package main
import "example.com/project/mypackage"
func main() {
mypackage.Run()
}
And mypackage.go:
package mypackage
import "fmt"
func Run() {
fmt.Println("It works.")
}
It's common to lay out your working directories like this, and then root the actual git repositories at the lowest level (e.g. in src/example.com/project/mypackage) so that they work cleanly with go get and go install for other users.

Resources