Vendoring in Go 1.6 - go

I’ve read as many docs and StackOverflow articles as I can find, yet I am having no luck importing using the new vendor feature in Go 1.6.
Here's a sample project I put together with Goji to test. The directory structure is as such:
.
└── src
├── main.go
└── vendor
└── github.com
└── zenazn
└── goji
├── LICENSE
├── README.md
├── bind
├── default.go
├── example
├── goji.go
├── graceful
├── serve.go
├── serve_appengine.go
└── web
And main.go, the sole file in the project, is as such:
package main
import (
"fmt"
"net/http"
"github.com/zenazn/goji"
"github.com/zenazn/goji/web"
)
func hello(c web.C, w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello, %s!", c.URLParams["name"])
}
func main() {
goji.Get("/hello/:name", hello)
goji.Serve()
}
My environment variables are as such:
export GOPATH=~/.go
export GOBIN=$GOPATH/bin
export PATH=$PATH:/usr/local/opt/go/libexec/bin:$GOBIN
I’ve tried the most simple build commands, with no luck:
go run ./src/main.go
go build ./src/main.go
I’ve also attempted to build with:
$GOPATH=`pwd`
...to no avail. Am I totally missing something? Any advice is appreciated.

I suggest you to read https://golang.org/doc/code.html. It requires a day or two to digest but after you understand how go tools work with the source code and GOPATH it is really easy to use them.
Back to your question. To build a simple go program you need to:
create directory under $GOPATH/src, e.g. mkdir $GOPATH/src/myprogram
put all the source code (including vendor directory) there: $GOPATH/src/myprogram/main.go, $GOPATH/src/myprogram/vendor.
run go install myprogram to build your application and put the resulting myprogram binary to $GOPATH/bin/myprogram

Related

SIMPLE godoc Hello world

Trying to serve a godoc on a simple, flat code folder. The online docs do not explain how to achieve this SIMPLE task.
So, creating this simple structure,
/tmp/testgodoc$ tree
.
└── src
├── main (just the binary)
└── main.go
1 directory, 2 files
where main.go is simply
/tmp/testgodoc$ cat src/main.go
// Hello godoc
package main
import "fmt"
// Say Hello
func main() {
fmt.Println("Hello")
}
When running either in GOPATH or module modes, opening localhost:6060 in a browser does not give the expected result of documenting current folder.
Running in module mode give this output and result:
/tmp/testgodoc$ ~/go/bin/godoc -goroot=. -http=:6060
using module mode; GOMOD=/dev/null
(when Ctrl-C:) cannot find package "." in:
/src/main
^C
And running in GOPATH mode seems to point to the local standard library:
/tmp/testgodoc$ GO111MODULE=off ~/go/bin/godoc -goroot=. -http=:6060
using GOPATH mode
^C
You should put your main package into a subdirectory, maybe like this:
~/go/src/testGoDoc$ tree
├── cmd
│ └── main.go
├── go.mod
└── pkg
└── test1
└── test_package.go
and by this you can run both commands:
godoc -http=:6060 #http://localhost:6060/pkg/<module name inside go.mod>/
and
GO111MODULE=off godoc -http=:6060 #http://localhost:6060/pkg/testGoDoc/

How can I resolve dependencies in nested application binary in Go project?

This sounds stupid, but I am trying for build my new golang project for a while now and I am stuck with following error
can't load package: package github.com/kuskmen/yamq/cmd/yamq-client: found packages main (main.go) and yamqclient (yamq-client.go) in C:\projects\yamq\cmd\yamq-client
I know this should be straightforward to fix, but I come from .NET and I am still not experienced in Go projects and its dependency resolution model hence the struggle.
My project structure looks like so
/yamq
/cmd
/yamq-client // yamq client application binary
main.go // package main
yamq-client.go // package yamqclient
/yamq-server // yamq server application binary
main.go // package main
yamq-server.go // package yamqserver
go.mod // contains only "module github.com/kuskmen/yamq" for now
... // some library files that will probably be moved to /shared folder
so far so good, when I do go build in outermost directory ( /yamq ) it is building successfully (or at least it is not showing any errors), but when I try to build either yamq-client or yamq-server binaries I get the aforementioned error and every time I try to google it or find something useful I got some old article or answer that dates back 2013-2016 that suggests something about $GOPATH and etc which shouldn't be the case here since I am trying to use go modules.
Help a fellow .NET developer join Go community by explaining him how exactly modules work cause I found this and this useless or at least I am missing the point, thanks in advance!
To follow up from my comment above:
From https://golang.org/doc/code.html:
Go programmers typically keep all their Go code in a single workspace.
A workspace contains many version control repositories (managed by Git, for example).
Each repository contains one or more packages.
Each package consists of one or more Go source files in a single directory.
The path to a package's directory determines its import path.
For your project, I'd do something like this:
$ tree
.
├── clientlib
│   └── lib.go
├── cmd
│   ├── client
│   │   └── main.go
│   └── server
│   └── main.go
├── go.mod
└── serverlib
└── lib.go
5 directories, 5 files
$ cat go.mod
module myproject.com
The module name is arbitrary (could be github.com/yourname/yourproject).
For the server side:
$ cat serverlib/lib.go
package serverlib
import "fmt"
func Hello() {
fmt.Println("Hello from serverlib.Hello")
}
$ cat cmd/server/main.go
package main
import (
"fmt"
"myproject.com/serverlib"
)
func main() {
fmt.Println("Running server")
serverlib.Hello()
}
And now we can build and run it:
$ go build -o server cmd/server/main.go
$ ./server
Running server
Hello from serverlib.Hello
The client side looks symmetrical.
Variations: you could name the .go files in cmd/... by their actual binary names - like server.go and client.go. The package in each is still main, but then go build creates an executable with the file's name (sans the .go) without needing to -o explicitly.

Confused how the golang project-layout repo works in practice

This question is in reference to the popular project-layout.
Is this simply a way to lay out the code, but the actual compilation of a binary will be in the
/cmd/app1/
/cmd/app2/
So if I have a website, it would still be considered a cmd application that would simply start the http listener etc.
Or are there several "entry" points throughout the layout and not just in the cmd folders?
How exactly would you actual build and run your application using this layout? (or one of them since from what I understand it supports multiple)
is it like:
go build cmd/app1/*.go ?
You can just
go build ./cmd/app/
For example I have this module
├── cmd
│   ├── cli
│   │   └── main.go
│   └── web
│   └── main.go
├── go.mod
└── service
└── service.go
go.mod is just
module example
service.go:
package service
import "fmt"
func DoSomething() {
fmt.Println("service processing")
}
cmd/web/main.go:
package main
import (
"example/service"
"fmt"
)
func main() {
fmt.Println("starting web program")
service.DoSomething()
}
cmd/cli/main.go:
package main
import (
"example/service"
"fmt"
)
func main() {
fmt.Println("starting cli program")
service.DoSomething()
}
Build (From root)
Build web:
go build ./cmd/web/
This will create binary file web
run web
./web
// output:
// starting web program
// service processing
Build cli:
go build ./cmd/cli/
run web
./web
// output:
// starting cli program
// service processing
If you want to build all of your apps inside a folder you can do like this :
go install ./...
this will build all your apps in bin folder inside GOPATH then you can run whatever app you like.
But if you want to build and run a specific app you can go to that folder and simply run.
go build
As long as there is a main package in that folder you can build your program.

Structuring a multi-executable Go project

I am trying to build a micro-services architecture project in Go. I am currently using Go 1.11 which supports modules, so I put my root directory in an arbitrary chosen directory, outside of GOPATH.
If I am getting the micro-services architecture concepts right, although my microservices need to be independent, they can share dependencies (and I don't see another way to do stuff, is it?)
Below is my directory structure:
.
├── go.mod
├── lambda
│   └── account_create
│   └── main.go
├── readme.md
└── types
├── account.go
├── location.go
├── order.go
├── pricing.go
├── product.go
└── types.go
Now the behavior I expected was to be able to run go build lambda/account_create and get an executable with that functionality so I can supply it to the respective AWS Lambda function.
However, when I run the command, I get:
can't load package: package lambda/account_create: unknown import path "lambda/account_create": cannot find module providing package lambda/account_create
Please explain me why this does not work and give me some advice on how a project like this should look.
Thank you very much!
Edit Here is my lambda/account_create/main.go file contents:
package account_create
import (
"fmt"
"roasted.ro/pkg/types"
)
func main() {
account := types.UserAccount{Name: "Victor"}
fmt.Printf("Welcome %s", account.Name)
}
To answer the latter part of your question (as the first half is more about preference), you need to do:
go build ./lambda/account_create
Notice the ./. go build takes in a package name or a path. If you don't prepend the path with a ./, it assumes you are giving it a package name.
Edit: the package has to be main if you want an executable. According to the docs, you always have to use package main for projects that build an executable:
Executable commands must always use package main.
Edit: I'll add some opinions on layout:
Consider which parts of your project are exported to other go projects. Meaning someone could import your package and expect to gain value and not have their code break when yours changes.
That should be either in a github.com/you/pkg/somepath package or just github.com/you/somepath.
Anything else (other than main packages) should be under a /internal package.
I typically make a /cmd/myexecurable1 /cmd/myexecurable2 and so forth for each executable.

using libraries in Golang

First of all and to be clear I come from the Java world, and I have been programming on go for a while and I really love it.
I have a small question about the packaging system and the imports, if I am importing a library which uses another library and I am already using that library in my project, how can I eliminate the duplication(if its possible),
in other words:
A is a the main program, C and B are libraries, and then:
C was added to A
B uses C
and then
B was also added to A
AProject/
src/
LibC/
src/
somefiles.go
LibB/
src/
LibC
somefiles.go
app.go
So now I have two libraries of C one in A since the beginning and one in B because B is dependent on C.
I know its a little bit confusing but in the Java world we have Ant and Maven and those build tools make it really easy to us to handle the dependencies.
Any thoughts?
In Go, there is no duplication of packages.
First, you should read about Go workspaces in How to Write Go Code.
From your question, your directory structure should look something like this:
gopath (gopath is the path of a directory in your $GOPATH list)
├── bin
│   └── projecta
├── pkg
│   └── linux_amd64
│   └── projecta
│   ├── libb.a
│   └── libc.a
└── src
└── projecta
   ├── a.go
   ├── libb
   │   └── b.go
   └── libc
   └── c.go
Where,
gopath/src/projecta/a.go:
package main
import (
"projecta/libb"
"projecta/libc"
)
func a() {
libb.B()
libc.C()
}
func main() { a() }
gopath/src/projecta/libb/b.go:
package libb
import (
"projecta/libc"
)
func B() { libc.C() }
gopath/src/projecta/libc/c.go:
package libc
func C() {}
If you are talking about third-party libraries, in go is very simple to do that,
just put the import in your source code, like:
import "github.com/somepackage/somelib"
and from the command line in your working directory run:
go get
the the source code of the libraries will be downloaded in the src directory of your $GOPATH.
If you want to create your own lib instead, just create the folder named as the lib in $GOPATH/src and put the code in this folder.
The folders structure is:
$GOPATH/
src/
github.com/
somepackage/
somelib/
somelib.go
yourlibB/
yourlibB.go -> //import somelib here
yourlibC/
yourlibC.go -> //import libB here
yourmainprogramA/
yourmainprogramA.go -> //import somelib, libC and libB here

Resources