cmd/go: [modules + integration] go mod discover, discover a set of unpacked modules within a directory

jjjwad0x  于 5个月前  发布在  Go
关注(0)|答案(8)|浏览(65)

本报告是一系列报告的一部分,应@mdempsky的要求编写,重点在于使Go模块集成器友好。

在确保阅读并理解general context之前,请勿关闭或将其标记为重复。 精确识别问题点花费了很多工作。

需要的功能

Go需要一个官方的go mod discover命令,该命令可以处理解压后的Go代码目录,并在其中识别有效的Go模块。

约束条件

  • 输出应该是一个可读的机器列表:
  • 模块路径
  • 模块版本
  • 文件系统路径
  • 如果不同的文件系统路径声明相同的模块和版本,命令应该发出警告。
  • 该功能还应作为官方Go API中的函数公开,返回一个go对象(Map、列表、结构体等)
  • 发现不应咨询缓存或互联网,只应咨询提供的目录
  • 目录中可能包含紧挨着相应mod文件的info文件,或者没有

动机

  • 已创建了打包 GOPATH/vendor模式下的现有软件基线
  • go允许在项目根目录之外的其他地方创建go.mod文件
  • go允许嵌套模块
  • go允许模块名称与项目url不匹配(并要求版本>1)
  • testdatavendor这样的细节意味着一些go.mod文件不被视为模块描述符,而只是数据,因此基本的find无法正常工作
  • 未来的语言演变可能会给“有效模块”的概念添加更多扭曲

所有这些都使得模块发现变得非常繁琐,应该由通用工具来处理。

rseugnpd

rseugnpd1#

It would help if you could trim down the redundant boilerplate text from each of your posts into a single sentence + link for more details (e.g., a Gist or meta-issue or something). The added verbosity makes it more difficult to quickly identify the unique details of each individual issue. Thanks.

vulvrdjw

vulvrdjw2#

Go需要一个官方的go mod discover命令,该命令可以处理解压后的Go代码目录,并识别此目录中的有效Go模块。

在这里,什么意味着“有效”的Go模块?

例如,您建议在testdata和/或vendor子目录中的go.mod文件无效。为什么会出现这种情况?

col17t5w

col17t5w3#

It would help if you could trim down the redundant boilerplate text from each of your posts into a single sentence + link for more details (e.g., a Gist or meta-issue or something). The added verbosity makes it more difficult to quickly identify the unique details of each individual issue. Thanks.
Done. Thanks for the comment. Do ping me if you find more things to improve.

1l5u6lss

1l5u6lss4#

Go 需要一个官方的 go mod 发现命令,该命令可以处理解包的 Go 代码目录,并识别此目录中的有效 Go 模块。

在这里,什么情况下一个 Go 模块被认为是“有效”的?
短期来看,可能只是指模块描述符可以在 Go 中解析而不出错。长期来看,是语言希望对其模块施加的任何合理规则。

例如,你建议 testdata 和/或 vendor 子目录中的 go.mod 文件无效。这是为什么呢?
对于 vendor,这是因为当前的 Go 模块设计似乎忽略了 vendoring,除非传递了特定的模式切换(我可能误解了这一点,我没有仔细研究 vendoring,我们的集成最佳实践要求在集成第一步中删除 vendor)。如果你不忽略 vendoring,你必须处理模块冲突,因为相同的模块会在不同的 vendor 目录中被多次打包。
对于 testdata,这是因为项目将损坏的文件打包到 testdata 中是很常见的。损坏的文件可能包括损坏的模块描述符文件,或者包含 go mod tidy 中损坏的包树的模块描述符对 testdata 来说没有意义。实际上,我在测试我的玩具实现在实际的 Go 项目之前忘记了这一点,并在一些项目的 vendor 中发现它在损坏和不符合规范的模块描述符上爆炸。
无论如何,默认情况下在遍历目录树时忽略 testdatavendor 并不是限制性的。您仍然可以直接指向 testdata 或 x1m9n1x 目录,因为它不会通过遍历到达这里。遍历保护不会适用。

7z5jn7bk

7z5jn7bk5#

短期内,可能只是模块描述符可以被Go解析而不出错。今天你可以通过运行go mod edit -json path/to/go.mod >/dev/null并查看它是否退出0或1来检查这一点。

zaqlnxep

zaqlnxep6#

@mdempsky,你忘记了查找部分,然后是tesdata/vendor的魔术规则,将它们加入混合中,你会发现这并不简单。

uqzxnwby

uqzxnwby7#

你忘记了查找部分,
这与Go语言无关,但没关系:

find . -name go.mod -print0 | xargs -0 -n1 sh -c 'go mod edit -print "$1" >/dev/null && echo "$1"' --

然后是tesdata/vendor的魔术规则,
你将"有效"定义为"模块描述可以被Go解析,没有错误",我找到了一个命令来区分这一点。但现在听起来你想要求得更细致一些。如果你能清楚、简洁地明确说明你想要什么,那就太好了。
或者,找出一些示例Go代码仓库和其中的go.mod文件,看看它们是否应该或不应该被认为是"有效"。

h79rfbju

h79rfbju8#

@mdempsky 在第一条消息中我定义了发现功能,你试图分别做一些部分,结果仍然是一些部分。更微妙的部分就是应用所有的Go源代码规则。已经有很多规则在vendor和testdata中了。将来可能会有更多的规则。当你的shell代码片段添加了更多的规则,当它已经超过一行时,你会维护你的代码片段吗?

你的代码片段也没有输出与mod文件对应的模块名称。这是另一个不能从go.mod文件路径轻易推断出来的事情(有时候看起来可以从文件路径推断出来,但仍然错误,所以推断是有风险的)

相关问题