从远程 Go 包中拉取文件

huangapple go评论91阅读模式
英文:

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.gofunctions.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代码文件的方式(尽管现在有一个官方的解决方案,类似于其他解决方案...请参见下文)。

在你的特定情况下,至少有两种可能的解决方案/解决方法可能对你有用。

  1. 如果数据像你所说的那样小,那么将文件内容作为const声明嵌入到Go文件中可能会起作用。作为Go源文件,它将被包含在包中,而不是从文件加载,只需使用声明的const的内容即可。

  2. 在源代码中硬编码文件内容之外,更好的方法是将内容保存在单独的文件中,但使用某个外部工具在需要时创建代码表示。这样可以使用工具来确保外部文件的有效性(例如语法检查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.

  1. 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 declared const.

  2. 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.

huangapple
  • 本文由 发表于 2023年2月24日 09:17:48
  • 转载请务必保留本文链接:https://go.coder-hub.com/75551817.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定