前往:独立的自定义工作区
[edit: fixed some formatting and indentations]
TL; DR:
直到并包括 go1.13.7
, $GOP新高
, $GOBIN
和 Go toolchain
很难隔离 Go Workspace
适用于外部的任何开发/生产/运行时环境 Go Contributers'
意识形态的议程和范围。
本文试图说明如何解决这些严重问题 Go
环境限制。我也是 golang
我想在更广泛,更通用的现实环境中使用它。
- 首先,我将在提供通用解决方案时尝试描述问题。随着本文的进展,解决方法将更加具体。
有什么问题?
但这是 Go
,我们很特别
不,Go并不特殊。这是一个一流的开发平台,但是迫使程序员和管理员对它加以特殊对待不仅令人讨厌,而且使人们讨厌它。管理员和开发人员不需要特殊的东西,他们需要能够实现和使用Go,而无需重新构建整个工作流程和环境。
此hack的功能
- 能够设置自定义工作区根目录(即,来自自定义路径的正确依赖项解析)
-
go build
和go build
从自定义工作区根目录开始工作 -
go test
和go test -v --bench . --banchmem
从自定义工作区根目录开始工作 -
go install
将在自定义工作区根目录中安装一个内置的二进制文件bin/
目录- 创建一个正确命名的二进制文件,我建议您使用
go build [-i] -o bin/
- 依赖项将安装在
pkg/
自定义工作区根目录的子目录
当前Go工作区的障碍:
- 确实发生了生产编码灾难
Go
工具链强制执行工作区会增加实时执行的复杂性(并因此而导致延迟)hot fixes
在生产系统上- 当您只需要在当下最忙的地方将文件拖放到某个地方时,最后要做的就是与开发工具的环境作斗争。
- 除非开发人员,测试人员和管理员都同意构建/开发布局,否则协作容器化环境将被破坏
- 由于工作流的游牧性质,像Singularity这样的特定容器化工作环境会受到影响
- 灵活的工作区布局,例如
Go
在协作过程中迫使开发人员,测试人员和管理员增加了产品生产时间
- CI / CD操作被迫为各种开发,产品和测试工件保留单独的文件路径-再次增加了复杂性和可能的技术负担
- 开发,测试,生产和管理一次过复杂,需要太多的环境知识才能有效
- 请参阅下面的“丑陋的现实世界示例”,在其中我仅添加了一个
main.go
在一个平面目录结构中Go
代码挑战 - 如果没有共享完整的环境
Go
尝试测试一些代码时变得非常麻烦 - 并非每个人都有时间或耐心去学习如何
Go's
可以正确处理特殊的环境需求-必须找到便宜的解决方法…
- 请参阅下面的“丑陋的现实世界示例”,在其中我仅添加了一个
强制执行Go工作区环境的问题的详细信息:
-
$GOP新高
和$GOBIN
需要为隔离的项目根手动设置-
修复/破解:为此使用环境脚本(从项目根目录执行)
# build_env # from project root run: `source
` # only use this from the project root !!!! THIS_PROJECT_P新高=$(pwd) export GOP新高=$GOP新高:$THIS_PROJECT_P新高 mkdir -k $THIS_PROJECT_P新高/bin export GOBIN=$THIS_PROJECT_P新高/bin -
-
软件包要求目录名称必须与软件包名称相同
- 虽然可以为包和模块使用自定义路径-
PITA
。 -
哈克:如果需要,可通过符号链接解决
- 虽然可以为包和模块使用自定义路径-
-
程序包和模块是硬编码在
Go
工具链下$GOP新高/src
- 您可以在此处阅读有关此干扰行为的各种观点和示例
- 基本上,您会在这方面看到很多类似的“习惯”态度
-
哈克:如果需要,可通过符号链接解决
-
import
模块的路径需要一个.
(点)在最上面的目录中// REQUIRED '.' notation import "example.com/myuser/myproject/platform"
- 没有可以更改此行为的设置
- 请参阅:Go编程语言-非公共模块的模块配置
- 该标准可能会很快更改
- cmd / go:导入丢失的软件包时出现令人困惑的错误“第一个路径元素中缺少点”问题#35273
-
哈克:如果需要,可通过符号链接解决
-
环境变量
$GOBIN
是放置可执行构建工件的单一路径- 这将可执行文件从项目强制执行以下任一操作:
- 全部驻留在一个风俗
$GOBIN
- 安装在
$GOROOT/bin
- 全部驻留在一个风俗
-
$GOBIN
没有解决方法go install
。有效地使go install
无用- 保持的唯一方法
$GOROOT/bin
被污染是使用单个自定义“用户空间范围”$GOBIN
- 保持的唯一方法
- 可以使用任何目标路径构建二进制文件
go build [-i] -o
- 这将可执行文件从项目强制执行以下任一操作:
EEEP使用符号链接解决路径问题:
整篇文章的开头都是关于如何使exercism.io使用的平面结构作为文档的个人注释。 git
支持的工作空间 Go
以及我计划在该站点上练习的其他语言。我已经在工作区环境问题/烦恼中挣扎了一段时间,所以我最终决定只看一看完全自定义的 Go
工作区中尽可能少的步骤。
答案是,符号链接。我提出的任何其他修复措施都太复杂(IMHO)或具有侵入性。这是一种方法 just get it over with
。
- 在以下示例中,请务必注意
exercism
是一个自包含的二进制文件,它将来自exercism.io的代码挑战下载到不可配置的目录路径中(~/exercism
),并采用如图所示的目录结构(减去我创建的符号链接)。 - 这是一个程序,它强加了这些使
Go
整体上很难使用或尝试。这只是一种情况。
丑陋的现实世界示例:
- 要求
目录结构可以通过使用符号链接来解决。/src/ - 我们使用符号链接来满足模块和盘点要求
- 在下面的目录树中,我们看到
exercism
二进制强制目录结构go
基于代码的挑战。 - 为了保持兼容
exercism
和go
工具链中,我们使用符号链接使go模块和包在src/
目录。 - 另外,我们添加了一个链接,
greeting
为了满足命名约定,go用于软件包及其各自的目录名称。 - 的
main.go
该文件旨在用于按需执行代码挑战
~/exercism:
├── go
│ ├── .git # the git repo dir
│ ├── bin
│ ├── greeting -> hello-world # package name link to satisfy `greeting`
│ ├── hello-world # A project (package/module `greeting`)
│ │ ├── go.mod # `greeting` module file
│ │ ├── hello_world.go # `greeting` package file
│ │ ├── hello_world_test.go # `greeting` module test file
│ │ └── README.md
│ ├── local.localhost -> . # `greeting` module path
│ ├── main.go # project main
│ ├── README.md
│ ├── src -> . # link to satisfy packages and modules are under `$GOP新高/src/`
│ └── util
│ └── build_env # script to set environment variables
└── README.md
- 在这种情况下,盘点
import
看起来像这样
package main
import (
"fmt"
"greeting"
)
func main() {
fmt.Println(greeting.HelloWorld())
}
- 一个模块
import
看起来像这样
package main
import (
"fmt"
"local.localhost/greeting"
)
func main() {
fmt.Println(greeting.HelloWorld())
}
-
供参考的是下面的软件包和模块文件
hellow-world
目录- 注意
hello-world
链接为greeting
并且我们已经创建了一个链接src/
以及-全部都在同一“工作区树”下 -
hello-world/go.mod
module greeting go 1.13
-
hello-world/hello_world.go
package greeting func HelloWorld() string { return "Hello, World!" }
- 注意