gpt4 book ai didi

docker - golang、docker、gradle的项目结构

转载 作者:IT王子 更新时间:2023-10-29 01:04:46 28 4
gpt4 key购买 nike

我刚开始使用 Go (golang),想要为将使用 Gradle 构建并部署到 Docker 镜像的项目设置一个新的项目文件夹结构。我正在努力确定这个项目结构可能是什么样子,主要是因为 GOPATH 结构以及 Go 语言工具似乎与使用 Gradle 或配置可克隆项目 (Git) 对立的事实。

该项目最终将包含各种用 Go 编写的服务器端代码、用 HTML 和 JavaScript 编写的客户端代码,因此我需要一个适合 Gradle 的项目结构来构建和打包所有这些类型的部分。

有人对此有良好的工作结构和工具建议吗?

最佳答案

当我开始使用 Go 时,我摆弄了各种各样的构建工具,来自 mavengulp .

事实证明,至少对我来说,它们弊大于利,所以我开始使用 Go 看似不起眼但经过深思熟虑的功能。其中之一是 go generate .添加简单的 shell 脚本或偶尔添加 Makefile 以实现自动化。

示例项目

我整理了一个示例项目来使这一点更清楚

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

main.go

这是一个简单的网络服务器,服务于“Hello, World!”使用一个模板,该模板使用优秀的 go.rice 嵌入到二进制文件中工具:

//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

例如,您可以在 //go generate 中调用 webpack,将您的东西放在一起,然后另一个 generate 从结果中创建一个 rice-box.go。这样,您所有的东西都将嵌入到您的二进制文件中,并且可以轻而易举地进行部署。

Docker文件

我在这个例子中使用了一个相当简单的 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 build && go generate

导致 docker 镜像构建两次等等。所以,我们需要一个不同的解决方案

解决方案 A: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 脚本完成整个序列。即使您只想运行测试,最终也会构建 docker 镜像。随着时间的推移,这会加起来。在这种情况下,我倾向于使用

解决方案 B:Makefile

Makefile 是 GNU make 的配置文件

    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 .

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

关于docker - golang、docker、gradle的项目结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45425749/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com