我经常使用 gorelease
作为 ci 的一部分来测试是否有人引入了破坏性更改。这个方法很好用,但是它是一个单独的工作流程,我需要在已经进行的所有linting之外再运行它。如果能简单地将一个阶段添加到我当前运行的 []*analysis.Analyzer
中并重用已经完成的解析,那就更好了。
据我所知,这需要获取前一个版本的AST作为 analysis.Fact
,所以我不确定这是否可行或高效,但它有助于更好地集成到现有的 metalinters 中。
编辑:在 #37561 之后,这可能价值不大,但重新解析AST确实会带来成本,所以无论如何都是一件好事。
7条答案
按热度按时间o2rvlv0m1#
/cc @jayconrod @jadekler
zqry0prt2#
Jay 肯定是这里的Maven,但是
在我的当前运行中添加一个阶段[]*analysis.Analyzer并重用已经完成的解析
你能告诉我这是什么意思吗?你有一些现有的工具 - 也许 gopls - 正在进行 AST 解析,你想将这个 AST 提供给 gorelease 而不是重新解析它?
好处是什么 - 是一些性能提升吗?如果是的话,你预计能获得多少提升?这是一个锦上添花的功能,还是阻碍了你的工作流程?
(我对更广泛的工具基础设施知之甚少,正在学习,所以这些问题是针对这些的 :) )
zdwk9cvp3#
你能告诉我这是什么意思吗?你有一些现有的工具,比如gopls,它正在进行AST解析,你想将AST传递给gorelease,而不是重新解析?
是的,我使用
golangci-lint
,一个metalinter,它使用analysis.Analyzer
接口将所有的govet检查和其他来自社区的第三方检查组合在一起。向该项目添加一个新的gorelease
linter是非常简单的。好处是什么?是性能提升吗?如果是的话,你预计能获得多少提升?这是一个锦上添花的功能,还是阻碍了你的工作流程?
在一个最糟糕的例子中,20万行代码需要49秒。虽然
golangci-lint
可能需要几分钟,但我猜大部分gorelease
的延迟是由于文件读取和AST解析。此外,golangci-lint
有一个很好的差异功能,可以只对更改的行进行lint,这对于在推送到ci之前进行本地检查非常有用。话虽如此,我们现在有一个工作流程,有了#37561,我们实际上可以像今天的
golangci-lint
一样自动化报告。0lvr5msh4#
我喜欢这个想法,即有一个分析器可以防止不兼容的更改。从架构上来看,我想这应该介于
gorelease
和apidiff
之间。现在那里没有一个层,所以这是一个相当大的改变。我想知道它是否应该只是gorelease
的一个单独工具?我认为奇怪的一点是,分析器需要一个基本版本来进行比较,这可能需要将模块下载到缓存中。对于
gorelease
来说,这是可以的,但对于分析器来说似乎有些不寻常。jaxagkaj5#
是的,将这个放在一个新的包或apidiff中对我来说是可以接受的。你并没有错,但它确实感觉像是一个
Analysis.Fact
或者analysis.Analyser.ResultType
,我认为我可以为它提供一个坚实的理由。而且我已经从分析团队得到了一些更奇怪的要求的支持,#44753。vshtjzan6#
这将是一个相当重要的变化。分析器一次处理一个包。它们可以使用从导入的包(在同一分析器内)中获取的事实边缘和同一包中的分析器之间的结果进行通信。{single,multi}checker.Main()接受一个包列表和一个分析器列表,并输出诊断信息(以及一些额外的输出)。包使用packages.Load()加载。
我正在考虑让分析支持运行根包列表。包和分析器列表以及返回根操作的事实和诊断信息。(暴露Results与unitchecker的要求相冲突。)调用这个函数很可能发生在{single,multi}checker.Main()之外。我怀疑这与您的所有目标并不完全兼容。
在分析包中尝试这样做的主要问题是它缺少信息。您需要加载pkg@123和pkg@234,并编码pkg@123和pkg@234之间存在关系。您需要使这些信息对单个Pass可用,即(分析器,包)对,这样可以一次性看到所有这些信息。您打算如何使所有这些信息对Pass可用?
8mmmxcuj7#
这将是一些努力的重复,但我认为,对于给定的
pkg@234
:仓库中的当前代码,单个analysis.Analyzer
可以计算并解析相同软件包的信息,从给定模块的当前发布版本pkg@123
开始,然后analysis.Analyzers
查看与“最新发布”相比可以依赖于该软件包并进行差异比较,gorelease
是其中之一。(我假设一些团队可能希望引入不同的兼容性保证,因为我已经看到过这种证据,并且希望使我的抽象设计可扩展。)如果有一个模块级别的“根软件包.Packages”,我认为可以用你的术语来计算“最新发布”,然后每个软件包都可以从这个基础上生成,但是“获取最新发布”相当便宜,而且你仍然可以在软件包级别对旧版本进行抽象语法解析。
@timothy-king:如果你觉得不清楚或者需要更多的细节,请告诉我。