I am new to go and trying to use a gocenter remote repo (Artifactory 6.8) for dependency resolution. Despite setting GOPROXY env var my gocenter-cache repo remains empty.
Here's my go code.
package main
import (
"fmt"
"github.com/naoina/go-stringutil"
)
func main() {
var str string = "hello_world_go"
fmt.Println(stringutil.ToUpperCamelCase(str)) //prints HelloWorldGo
}
The dependency I am trying to resolve is here: https://search.gocenter.io/github.com~2Fnaoina~2Fgo-stringutil/versions
Here's my GOPROXY env var:
$ echo $GOPROXY
https://<<my Artifactory URL>>/api/go/gocenter
Here's a truncated version of the gocenter repo definition. I used the jfrog docs for setting this up:
{
"key" : "gocenter",
"packageType" : "go",
"url" : "https://gocenter.io/",
"rclass" : "remote"
}
When I run "go get" the dependency resolves...
$ go get -v github.com/naoina/go-stringutil
github.com/naoina/go-stringutil (download)
but gocenter-cache is empty, telling me it wasn't used.
{
"repo" : "gocenter-cache",
"path" : "/",
"created" : "2019-04-17T16:35:37.586Z",
"lastModified" : "2019-04-17T16:35:37.586Z",
"lastUpdated" : "2019-04-17T16:35:37.586Z",
"children" : [ ],
"uri" : "https://<<REDACTED>>/api/storage/gocenter-cache"
}
Perhaps my "go get" should have a different target? I am just using what exists in gocenter: https://search.gocenter.io/github.com~2Fnaoina~2Fgo-stringutil/versions
Any help in pointing out what I am doing wrong would be greatly appreciated. I haven't gone into modules yet or anything like that, as I am an artifactory admin and not a go developer. I am just trying to prototype this functionality so we can help advise our users with what to do.
--UPDATE: I found https://golang.org/cmd/go/#hdr-Module_proxy_protocol and then tried this:
$ echo $GOPROXY; go get $GOPROXY/github.com/naoina/go-stringutil
https://<<REDACTED>>/api/go/gocenter
package https:/<<REDACTED>>/api/go/gocenter/github.com/naoina/go-stringutil: https:/<<REDACTED>>/api/go/gocenter/github.com/naoina/go-stringutil: invalid import path: malformed import path "https:/<<REDACTED>>/api/go/gocenter/github.com/naoina/go-stringutil": invalid char ':'
So the colon between my protocol and my url is an invalid character? Also why is it removing one of my forward slashes?
--UPDATE2: I got "go mod init" to work, kind of:
$ go mod init
go: creating new go.mod: module example/hello
$ ls
go.mod hello.go
$ go build
build example/hello: cannot load github.com/naoina/go-stringutil: cannot find module providing package github.com/naoina/go-stringutil
$ cat go.mod
module example/hello
go 1.12
$ echo $GOPROXY
https://<<REDACTED>>/api/go/gocenter
--UPDATE 3:
$ cat go.mod
module example/hello
go 1.12
require github.com/naoina/go-stringutil v0.1.0
$ go build
hello.go:6:2: cannot find package "github.com/naoina/go-stringutil" in any of:
C:\Go\src\github.com\naoina\go-stringutil (from $GOROOT)
C:\Users\samuelm\go\src\github.com\naoina\go-stringutil (from $GOPATH)
$ echo $GOPROXY
https://<<REDACTED>>/api/go/gocenter
--UPDATE 4: it appears I'm still not using modules?
$ go list -m all
go list -m: not using modules
--UPDATE 5, re: retgits Your steps helped, but I'm still not all the way there.
$ find .
.
./bin
./src
./src/example.com
./src/example.com/hello
./src/example.com/hello/hello.go
$ cd src/
$ go mod init example.com/hello
go: creating new go.mod: module example.com/hello
$ cat go.mod
module example.com/hello
go 1.12
$ go get -v github.com/naoina/go-stringutil
Fetching https://<<REDACTED>>/api/go/gocenter/github.com/naoina/go-stringutil/@v/list
Fetching https://<<REDACTED>>/api/go/gocenter/github.com/naoina/@v/list
Fetching https://<<REDACTED>>/api/go/gocenter/github.com/@v/list
go get github.com/naoina/go-stringutil: unexpected status (https://<<REDACTED>>/api/go/gocenter/github.com/naoina/go-stringutil/@v/list): 404 Not Found
$ go build example.com/hello
can't load package: package example.com/hello: unknown import path "example.com/hello": cannot find module providing package example.com/hello
$ cd example.com/hello/
$ go build
build example.com/hello/example.com/hello: cannot load github.com/naoina/go-stringutil: cannot find module providing package github.com/naoina/go-stringutil
I am not providing credentials in my GOPROXY, because our end-users do not have accounts, we're inside a firewalled env and allow full anon read access. If we have to provide user accts then we cannot support Go.
--FINAL UPDATE: Removing my local proxy resolved the 404 issue, retgits solution works.
You mentioned you're not a Go developer so let me walk you through all the steps. I realize it might be a little overkill to some of the devs here, but it might help you.
Depending on where you've put your source code you will need to set the environment variable GO111MODULE
. Since go 1.11 it's recommended to not put your source code in your $GOPATH anymore. If you put your code there and want to use Go modules you'll have to set the GO111MODULE
to true
(personally I keep all my Go code outside of the $GOPATH). On Windows you'll have to create the environment variable first and set it accordingly (and restart your terminal).
To create a Go module you'll have to run the command go mod init <name of your module>
. In my case, I've ran the command go mod init github.com/retgits/bla
which created a go.mod
file with
module github.com/retgits/bla
go 1.12
Adding modules will now be as simple as running go get
. If you want to use GoCenter or Artifactory to help resolve your modules.
To help resolve modules there are two options you might want to look at:
goc
Using goc
The goc utility automatically sets GOPROXY to GoCenter, bypassing other proxies like Artifactory. The current behavior of the Go client is to look at one single proxy and fail your build if not all modules are resolved from there. goc
will look at GoCenter first and if the module isn't in GoCenter it will get the module from its original place (like GitHub)
Using Artifactory
If you want to use Artifactory to resolve, and cache, your Go modules you'll have to create a remote repository with the settings for GoCenter (which are in the documentation as you mentioned). You'll have to include that remote repository into a virtual one for it to work.
Setting GoCenter as GOPROXY
A third option would be to only use GoCenter (the public registry created by JFrog), but that might defeat your original question:
export GOPROXY="https://gocenter.io"
go get -v github.com/naoina/go-stringutil
No matter which of the options you choose it will update the go.mod
to
module github.com/retgits/bla
go 1.12
require github.com/naoina/go-stringutil v0.1.0 // indirect
The indirect
is because I've not yet created a .go
file with the code that uses this import.
If I now create a main.go
sample with
package main
import (
"fmt"
"github.com/naoina/go-stringutil"
)
func main() {
str := stringutil.ToSnakeCase("HelloWorld")
fmt.Println(str)
}
// Running go run main.go would result in
// hello_world
it will remove the indirect
from the go.mod file because I now have code that relies on my module.