golang,docker,gradle的项目结构

我刚刚开始使用Go(golang),并希望为将要使用Gradle构build并部署到Docker映像的项目设置新的项目文件夹结构。 我正在努力确定这个项目结构可能是什么样子,主要是因为GOPATH结构和Go语言工具看起来与使用Gradle或configuration可被克隆的项目(Git)相反的事实。

该项目最终将包含用Go编写的各种服务器端代码,用HTML和JavaScript编写的客户端代码,所以我需要一个可以很好地用于Gradle构build和打包所有这些types的项目结构。

有没有人有一个良好的工作结构和工具的build议呢?

当我开始使用Go时,我从各种各样的构build工具中摆弄出来,从maven到gulp 。

事实certificate,至less对我来说,他们做的不是好事,所以我开始使用Go的表面上看起来不具有影响力,但真正深思熟虑的function。 其中之一是go generate 。 添加简单的shell脚本或偶尔使用Makefiles进行自动化。

示例项目

我已经把一个样本项目放在一起,使这个更清楚

 /Users/you/go/src/bitbucket.org/you/hello/ ├── Dockerfile ├── Makefile ├── _templates │  └── main.html └── main.go 

main.go

这是一个简单的networking服务器,服务“你好,世界!” 使用优秀的go.rice工具使用embedded到二进制文件中的模板:

 //go:generate rice embed-go package main import ( "html/template" "log" "net/http" rice "github.com/GeertJohan/go.rice" ) func main() { templateBox, err := rice.FindBox("_templates") if err != nil { log.Fatal(err) } // get file contents as string templateString, err := templateBox.String("main.html") if err != nil { log.Fatal(err) } // parse and execute the template tmplMessage, err := template.New("message").Parse(templateString) if err != nil { log.Fatal(err) } http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { if err := tmplMessage.Execute(w, map[string]string{"Greeting": "Hello, world!"}); err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) } }) log.Fatal(http.ListenAndServe("127.0.0.1:8080", nil)) } 

注意行

 //go:generate rice embed-go 

当你打电话go generate你的源文件将被扫描这样的行和相应的命令将被执行。 在这种情况下,会生成一个名为rice-embed.go的文件,您的目录将如下所示:

 /Users/you/go/src/bitbucket.org/you/hello/ ├── Dockerfile ├── Makefile ├── _templates │  └── main.html ├── main.go └── rice-box.go 

你可以调用webpack //go generate创build一个例子,让你的东西在一起,另一个产生从结果创build一个rice-box.go 。 这样,所有的东西都会被embedded到你的二进制文件中,并且很容易部署。

Dockerfile

我在这个例子中使用了一个相当简单的Dockerfile:

 FROM alpine:latest MAINTAINER You <you@example.com> COPY hello /usr/bin EXPOSE 8080 CMD ["/usr/bin/hello"] 

然而,这给我们带来了一个问题:我们不能使用go:generate来生成docker镜像,就像我们需要调用go:generate ,新的二进制文件还没有go:generate 。 这会让我们做丑陋的事情

 go generate && go build && go generate 

导致docker图像build立两次,而不是。 所以我们需要一个不同的解决scheme

解决schemeA:一个shell脚本

我们当然可以拿出类似的东西:

 #!/bin/bash # Checks for existence omitted for brevity GO=$(which go) DOCKER=$(which docker) $GO generate $GO test $GO build $DOCKER -t you/hello . 

但是,这带来了一个问题:您将始终使用shell脚本执行整个序列。 即使你只是想运行testing,你最终会build立docker图像。 随着时间的推移,这加起来。 在这种情况下,我倾向于使用

解决schemeB:一个Makefile

Makefile是GNU make的configuration文件

  CC = $(shell which go 2>/dev/null) DOCKER = $(shell which docker 2>/dev/null) ifeq ($(CC),) $(error "go is not in your system PATH") else $(info "go found") endif ifeq ($(DOCKER),) $(error "docker not in your system path") else $(info "docker found") endif .PHONY: clean generate tests docker all all: clean generate tests hello docker clean: $(RM) hello rice-box.go cover.out generate: $(CC) generate tests: generate $(CC) test -coverprofile=cover.out hello: tests $(CC) build docker: hello $(DOCKER) build -t sosample/hello . 

一个完整的解释超出了这个答案的范围,但你基本上可以在这里做的是,你可以调用makeall目标将被构build:从旧版本的文件被删除( clean ),一个新的rice-box.go生成( generate )等等。 但是,如果你只想运行testing例如,调用make test只会执行目标cleangeneratetests

你可以看看我的方法来构build你的项目https://github.com/alehano/gobootstrap这是一个Web框架&#x3002;