英文:
Pulling a file from a remote go package
问题
我有一个小数据集(无论是yaml/json/txt都不重要),它会定期更新(变得更大),位于go包中的以下位置:
github.com/abc-company/repoA/package-with-data/data.yml
目前,我正在开发一个服务,该服务在不同的仓库中使用这个文件,比如:
github.com/abc-company/repoB/functions.go
。functions.go
文件中有很多函数,其中一个函数将使用data.yml
,但我不知道如何导入它。通常的import github.com/abc-company/repoA/package-with-data
然后go mod vendor
并不能访问到这个文件,它似乎只能访问函数和方法等,这可能是预期的行为。而且,我对Go和GitHub的知识都很基础。
这个文件本身很小,只包含几十个字段,它会从完全不同的服务中定期更新,所以将这个文件复制粘贴到我的工作仓库是一个不太好的解决方案。在这种情况下,最简单的处理方法是什么?我已经搜索过了,但都是关于导入Go包的内容,而且前几个结果都不适用于我的情况。
英文:
I have a small dataset (yaml/json/txt whichever is not important) that periodically gets updated (gets bigger) in a go package at:
github.com/abc-company/repoA/package-with-data/data.yml
. Currently, I am working on a service that uses this file specifically in a different repo, say:
github.com/abc-company/repoB/functions.go
. The functions.go
file has many functions and one of them will use the data.yml
and I am stuck on how to import this. The usual import github.com/abc-company/repoA/package-with-data
and then go mod vendor
does not give access to this file - it only seems to give access to functions and methods etc, which is probably what is intended. It also does not help I am a complete beginner to go and github stuff in general.
The file itself is tiny and only holds a few dozen fields which gets periodically updated from different service altogether, so just copying and pasting this file to my working repo is an ugly solution. What is the easiest to handle this situation ? I did my googling but it's all about importing Go package stuff that shows up and the top few results are not applicable to my situation.
答案1
得分: 1
Go语言没有提供一种打包非Go代码文件的方式(尽管现在有一个官方的解决方案,类似于其他解决方案...请参见下文)。
在你的特定情况下,至少有两种可能的解决方案/解决方法可能对你有用。
-
如果数据像你所说的那样小,那么将文件内容作为
const
声明嵌入到Go文件中可能会起作用。作为Go源文件,它将被包含在包中,而不是从文件加载,只需使用声明的const
的内容即可。 -
在源代码中硬编码文件内容之外,更好的方法是将内容保存在单独的文件中,但使用某个外部工具在需要时创建代码表示。这样可以使用工具来确保外部文件的有效性(例如语法检查yaml编辑器/插件等)。
对于第二种方法,通过embed
包(自Go 1.16起)提供了“官方”支持这种机制。
另外,go-bindata是一个非常简单的工具,我使用过非常成功。
除了将文件内容转换为代码外,它还提供了一个Asset()
函数来“加载内容”;你的代码仍然看起来像是从文件加载,而go-bindata
具有机制,允许在某些情况下实际从文件加载,如果这是你的用例的一部分(有关详细信息,请参阅非常好的go-bindata
文档)。
你应该了解一些与go-bindata
项目来源相关的历史。该文章提供了一个相当歇斯底里的标题,即该项目的(现在的)维护者没有“良好意图的保证”,尽管可以说,努力保持项目活跃是这种良好意图的证据。然而,对于原始作者(或者说几乎任何开源项目),也没有这样的保证。关键是,在这种情况下没有恶意意图的证据。一如既往,请谨慎行事。
如果embed
对你的需求来说太笨重/有限,而go-bindata
的历史让你感到不安,那么实现类似功能但以不同方式的替代方案包括:
我自己没有使用过这两个(或embed
),所以无法说它们是否比go-bindata
更好,但你可能想要查看它们。
英文:
Go does not provide a way to package non-go code files (though it does now have an official work-around comparable to other solutions… see below).
There are at least two possible solutions/work-arounds which you might find useful in your particular context.
-
If the data is as small as you suggest, then simply embedding the file content as a
const
declaration in a go file might work. As a go source file, it will be included in the package and instead of loading from a file, simply use the contents of the declaredconst
. -
A step up from hard-coding the file content in your source yourself would be to keep the content in a separate file but use some external tool to create an in-code representation as and when required. This allows you to use tooling to ensure your external files are valid (e.g. syntax checking yaml editors/plugins etc).
For the 2nd approach, there is “official” support for just such a mechanism via the embed
package (since Go 1.16).
Alternatively go-bindata is a very simple tool that I've used very successfully.
As well as converting file content to code, it provides an Asset()
function to "load the content"; your code continues to look like it is loading from a file and go-bindata
has mechanisms to allow you to actually load from a file under certain circumstances, if that is part of your use case (see the very good go-bindata
docs for details).
You should be aware of some history relating to the provenance of the go-bindata
project. The article provides the rather hysterical headline that there is no “guarantee of good intentions” with the (now) maintainer of that project, although one might argue that trying to keep the project alive is evidence of such good intentions. However, there was also no such guarantee regarding the original author (or for that matter of just about any OSS project). Crucially there appears to be no evidence of bad intentions in this case. As always, exercise due care and diligence.
If embed
is too clunky/limited for your needs and the history of go-bindata
makes you nervous, alternatives that achieve much the same thing but in different ways include:
I have not used either of these myself (or embed
) so cannot say whether they are better than go-bindata
, but you might want to check them out.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论