我已经开始重构auto
maven
插件以尝试与auto
的其余部分更加一致。 在这样做的过程中,我得出了一些结论。
maven
插件对auto
的当前要求是项目使用maven-release-plugin
。 这有几个后果,使其不适合auto
。
maven-release-plugin
的主要功能通过release:prepare
执行以下步骤:
然后通过release:perform
:
deploy
site-deploy
)为了确保插件的行为方式与auto
,当前的实现使用了一些 git 黑客来处理release:prepare
目标所做的提交。 换句话说, maven-release-plugin
正在执行auto
设计的工作,因此必须以一种不太优雅的方式“解决”。
同样重要的是用来提取库和作者信息的方法-目前的maven
插件使用<scm/>
和<developers/>
的部分中的pom.xml
来推导那个信息。 这与auto
其余部分使用的方法不同,后者使用 git 元数据。 目前的实现有几个问题:
author
经由设置<developers/>
的部分pom.xml
,这意味着人做的提交可以不相同,所选择的author
。 没有尝试将 git commit 作者与<developers/>
信息对齐。owner
和repo
信息是通过<scm/>
部分设置的,这可能与当前克隆的实际存储库和所有者不同。在对插件进行更深入的研究并将其与gradle
插件进行比较时,似乎maven-release-plugin
中唯一有用的目标是release:update-versions
目标。 这个目标很容易被一些简单的 XML 处理所取代。
考虑到维护maven-release-plugin
的开销和最小的优势,我认为应该取消该要求,并且auto
maven
插件应该在更多auto
本土时尚。
我完全同意!
我从 pom.xml 中获得的大部分信息点可能与我对这些字段的误解有关。 这里的任何更改都非常受欢迎。
我完全支持我们必须做的任何重大改变。 我们可能会推出一些在 #1156 中详述的较小的突破性更改
看起来我关于<scm/>
和<developers/>
两点是不正确的。 npm
插件从package.json
提取。 这是否意味着它们_应该_位于pom.xml
?
如果这些是 npm repository
和author
字段的pom
等价物,那么是的。
作者是通过设置
pom.xml 的一部分,这意味着执行提交的人可能与选定的作者不同。 没有尝试将 git commit 作者与 信息。
这对于 npm 插件也是如此。 本地自动不会覆盖您的git
配置,但在 CI 环境中,它可能必须将author
为 commit`。
所有者和回购信息通过
部分,这可能与当前克隆的实际存储库和所有者不同。
这会有所不同吗? 在 npm 世界中, repository
字段通常指向包的代码。 在实践中,人们通常不会运行auto
上的fork
,如果他们要我希望他们更新repository
场他们叉
好的,这是有道理的 - 所以正确的行为是寻找那些东西(当前),如果它们在pom.xml
没有找到,返回并假设它们已经被设置在.autorc
(新行为)。
目前,如果它没有找到该插件将错误<scm/>
和<developers/>
的部分pom.xml
。
啊,是的,这绝对是一个错误。 它不应该抛出错误https://github.com/intuit/auto/blob/master/plugins/npm/src/index.ts#L504
有没有办法以机器可读的方式从auto
获取版本号? 我很惊讶auto version
命令产生版本凹凸的类型,而不是数字。
您可以使用--quiet
并且它只会打印命令生成的版本。 或将其与--dry-run
配对,您可以查看接下来将发布的版本。
我可能愿意添加一个标志以使version
吐出实际版本。 这在多包场景中变得很奇怪
我知道。 最好将它留给调用者来确定它正在寻找哪个版本。
您关于多包场景的观点在这里很重要 - maven-release-plugin 支持这种类型的场景,即开即用。 这让我怀疑我是否想要重现该作品。 我发现自己陷入了僵局 - 一方面,我不使用 maven-release-plugin 的论点是有效的,而另一方面,像子模块版本管理这样的事情是一个不平凡的用例应该被解决,并且被 maven-release-plugin 覆盖。
我发现了两种使用 maven-release-plugin 的方法,可以用来防止 maven 插件在release:prepare
期间修改存储库,并将在今天晚些时候测试它们。
@hipstersmoothie我有一个关于getAuthor
、 getRepo
等钩子行为的问题 - RE:关于https://github.com/intuit/auto/issues/1260#issuecomment的评论 - 634280655,我正在查看测试,它们似乎与此相矛盾。
因此,当我返回undefined
AuthorInformation
不会引发任何错误。
关于我可能做错了什么的任何建议,或者我是否应该将throw
重新引入我的钩子处理?
考虑到所有其他插件的工作方式,这绝对是错误的。 返回 undefined 是正确的方法。 这样core
可以回退到本地配置的git
用户,如果需要的话
Gotcha - 这就是我的想法,所以我修改了测试以确保失败的钩子返回undefined
。
看起来 gradle 和 cocoapods 插件如果找不到版本都会抛出错误。 我为 gradle 插件创建了一个错误 - 你想要另一个用于 cocoapods 的吗?
只是在这个问题上留下一个不。 感谢您的捕获!
我正在努力寻找一种在hooks.beforeRun
期间测试值初始化的好方法。 具体来说,我有以下代码,当在调试下成功提取hooks.beforeRun
期间的作者信息时,但测试失败:
test("should get author from pom.xml", async () => {
mockRead(`
<project
xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<developers>
<developer>
<name>Andrew Lisowski</name>
<email>[email protected]</email>
</developer>
</developers>
</project>
`);
await hooks.beforeRun.promise({} as any);
expect(await hooks.getAuthor.promise()).toStrictEqual(
expect.objectContaining({
email: "[email protected]",
name: "Andrew Lisowski",
})
);
});
什么情况是,测试得到的getAuthor
前的钩beforeRun
挂钩运行。 我看过其他测试这个的代码(gradle,s3),但我没有任何运气。
基本上,我需要一种方法来确定性地执行beforeRun
钩子,但不知道该怎么做。
推一个分支,我可以检查一下
@hipstersmoothie这是分支: https :
我已经注释掉了将我的更改推送到中央存储库的代码,以便我可以在真实项目上测试代码而不会污染远程历史记录。
非常感谢您可以为我提供的任何帮助 - 我希望能够使用测试来检查我修改 pom.xml 文件的能力,而不是诉诸于“针对真实文件,检查真实文件,运行git reset --hard HEAD~1
以消除更改,冲洗并重复。”
此外,为了在 IntelliJ 中运行 Jest 测试,我必须对与根package.json
不兼容的本地package.json
进行一些更改 - 有什么指导可以给我,还是应该“开箱即用”?
具体来说,当在 maven 插件目录中并运行npm test
- 所有测试最终都会运行,因为"test": "jest --maxWorkers=2 --config ../../package.json"
。
如果我尝试从编辑器中使用 IntelliJ 测试运行器,我会得到:
● Test suite failed to run
SyntaxError: /home/rbellamy/Development/Terradatum/auto/plugins/maven/__tests__/maven.test.ts: Unexpected token, expected "," (15:24)
13 | }));
14 |
> 15 | const mockRead = (result: string) =>
| ^
16 | jest
17 | .spyOn(fs, "readFile")
18 | // @ts-ignore
at Parser._raise (../../node_modules/@babel/parser/src/parser/location.js:241:45)
at Parser._raise [as raiseWithData] (../../node_modules/@babel/parser/src/parser/location.js:236:17)
at Parser.raiseWithData [as raise] (../../node_modules/@babel/parser/src/parser/location.js:220:17)
at Parser.raise [as unexpected] (../../node_modules/@babel/parser/src/parser/util.js:149:16)
at Parser.unexpected [as expect] (../../node_modules/@babel/parser/src/parser/util.js:129:28)
at Parser.expect [as parseParenAndDistinguishExpression] (../../node_modules/@babel/parser/src/parser/expression.js:1293:14)
at Parser.parseParenAndDistinguishExpression [as parseExprAtom] (../../node_modules/@babel/parser/src/parser/expression.js:1029:21)
at Parser.parseExprAtom [as parseExprSubscripts] (../../node_modules/@babel/parser/src/parser/expression.js:539:23)
at Parser.parseExprSubscripts [as parseMaybeUnary] (../../node_modules/@babel/parser/src/parser/expression.js:519:21)
at Parser.parseMaybeUnary [as parseExprOps] (../../node_modules/@babel/parser/src/parser/expression.js:311:23)
我可以通过添加jest.config.ts
文件来解决 IntelliJ 的问题:
module.exports = {
clearMocks: true,
moduleFileExtensions: ['js', 'ts'],
testEnvironment: 'node',
testMatch: ['**/*.test.ts'],
testRunner: 'jest-circus/runner',
transform: {
'^.+\\.ts$': 'ts-jest'
},
verbose: true
}
然后将jest-circus
到 root 或 maven package.json
文件中。
只是注意到xml2js
不会完成这项工作,因为它会在 XML => JSON => XML 转换期间默默地删除所有 XML 注释。 我一直在努力让它发挥作用,就像拔牙一样。 无法保证在通过xml2js
转换时 XML 看起来会像原始文件一样,这是一个交易破坏者。
为了仅对一个插件运行测试,我从根目录运行它。
yarn test plugins/maven
这就引出了一个问题,即您是否可以轻松地显示您将要进行的所有更改或将要构建的工件,而无需实际进行一些更改。
这似乎是一个非常大的破坏者。 java 环境中是否有任何标准 CLI 允许编辑该文件?
对于没有配置文件解析器的插件(例如:ruby) auto
主要使用正则表达式来更新文件。
你有机会看看beforeRun
问题吗? 我有一个解决方法,但感觉真的很糟糕......
我真的不喜欢在 XML 中使用正则表达式的想法 - 它容易出错且脆弱。 然而,试图使用DOMParser
或XMLSerializer
只是为了修改版本似乎也很复杂,这就是我首先尝试使用xml2js
的原因。
现在看这个!
问题是您正在执行“同步”点击并在其中执行异步工作
改变这个
auto.hooks.beforeRun.tap(this.name, async () => {
对此
auto.hooks.beforeRun.tapPromise(this.name, async () => {
啊,之前的运行钩子现在是同步的,这才是真正的问题。 如果它变成AsyncSeriesHook
而不是SyncHook
它不会改变任何东西。 如果不清楚我在说什么,我可以将提交推送到您的分支
请做...让我让你成为贡献者。
前进!
刚推。 运行测试,现在只有两个失败。 beforeRun 钩子按预期工作。
@hipstersmoothie我没有看到对 terradatum/auto repo 的承诺?
现在我实际上已经推动了
这会导致当前使用同步点击的任何插件发生重大变化吗?
不。 同步水龙头应该工作相同。 这只是增加了点击承诺的能力
我已经使用脆弱/容易出错的正则表达式成功地完成了这项工作。 我担心的是<version/>
元素在pom.xml
文件中无处不在 - 用于工件版本以及依赖项和插件。 换句话说,正则表达式很可能会无意中更改它不应该更改的版本。
在尝试使用 XML DOM(通过 xmldom、xmldom-ts、xml2js、xml2json 等)时,我发现自己陷入了史无前例的泥潭。 我绝不认为自己是打字稿或 javascript 专家,所以也许这就是我失败的地方。
有两件事让我很生气:
Document
,然后使用 xpath 选择“/project/version”和“/project/parent/version”节点。在这两个问题之间,我可能总共花了 12 到 16 个小时,我真的很沮丧。 我一直工作到今天早上 #1,我认为 #2 应该相对简单,但它似乎每时每刻都在与我作斗争。
我倾向于回到使用 maven-release-plugin 的原因是它为我处理更新 pom.xml 文件的可笑的简单原因。
我不知道如何让 IntelliJ 在调试模式下运行 Maven 测试(并且只运行 Maven 测试)。 有时它有效,有时它不起作用。
对不起,我在这里没有更多帮助。 我使用 VSCode 并且很少调试测试。 你能用yarn test plugins/maven
从 root 运行吗?
将 pom.xml 加载到 Document 中,然后使用 xpath 选择“/project/version”和“/project/parent/version”节点。
这似乎是一个很好的方法。 如果这可以工作,那看起来不错。
我倾向于回到使用 maven-release-plugin 的原因是它为我处理更新 pom.xml 文件的可笑的简单原因。
是否只有基于插件的东西,如https://stackoverflow.com/questions/5726291/updating-version-numbers-of-modules-in-a-multi-module-maven-project可用于 maven? 一个低级别的基于 mvn 的东西将是完美的。
顺便说一句,感谢您花这么多时间在这上面!
感谢您的反馈和支持。 抱歉之前的评论。
关于versions-maven-plugin 的一个要点——我以前没有使用过它,也不知道它存在。 这肯定会让我更轻松......这是 maven-release-plugin 和尝试通过自动插件管理 pom.xml 文件之间的完美折衷。
我可以让yarn test plugins/maven
工作。 我也非常喜欢使用调试器来检查东西,而不是更传统的console.log
,所以这可能是我让自己比我需要的更胃灼热的地方......
经过漫长而艰辛的旅程,我几乎有了我认为的完整解决方案,要么直接修改pom.xml
文件,要么使用versions-maven-plugin
设置版本。
有一些注意事项。 用于修改pom.xml
的代码正在使用 DOM,这会产生以下后果:
tsconfig.json
处理中存在一个错误,要求"dom"
库位于"es2017"
中的"compilerOptions"
:作品:
"compilerOptions": [ "dom", "es2017" ]
不起作用:
"compilerOptions": [ "es2017", "dom" ]
如果没有“修复”,则会发生以下情况:
$ tsc -b tsconfig.dev.json
node_modules/@types/jsdom/index.d.ts:28:40 - error TS2304: Cannot find name 'DocumentFragment'.
28 static fragment(html: string): DocumentFragment;
~~~~~~~~~~~~~~~~
node_modules/@types/jsdom/index.d.ts:45:28 - error TS2304: Cannot find name 'Node'.
45 nodeLocation(node: Node): ElementLocation | null;
~~~~
node_modules/@types/jsdom/index.d.ts:188:19 - error TS2304: Cannot find name 'HTMLScriptElement'.
188 element?: HTMLScriptElement | HTMLLinkElement | HTMLIFrameElement | HTMLImageElement;
~~~~~~~~~~~~~~~~~
node_modules/@types/jsdom/index.d.ts:188:39 - error TS2304: Cannot find name 'HTMLLinkElement'.
188 element?: HTMLScriptElement | HTMLLinkElement | HTMLIFrameElement | HTMLImageElement;
~~~~~~~~~~~~~~~
<snip - numerous other errors>
jest
测试需要testEnvironment: 'jsdom'
而不是'node'
。如果没有“修复”,则会发生以下情况:
$ jest --runInBand plugins/maven
FAIL plugins/maven/__tests__/maven.test.ts
maven
updatePomVersion
✕ should replace the previousVersion with the newVersion (39ms)
● maven › updatePomVersion › should replace the previousVersion with the newVersion
ReferenceError: XPathEvaluator is not defined
51 | ) => {
52 | const pomDom = new jsdom.JSDOM(content, {contentType: "text/xml"}).window.document;
> 53 | const evaluator = new XPathEvaluator();
| ^
54 | const resolver = evaluator.createNSResolver(pomDom.documentElement);
55 | const expression = evaluator.createExpression("/project/version", resolver);
56 | const versionNode = expression.evaluate(pomDom.documentElement, XPathResult.FIRST_ORDERED_NODE_TYPE);
at Object.exports.updatePomVersion (plugins/maven/src/index.ts:53:21)
at Object.test (plugins/maven/__tests__/maven.test.ts:53:26)
无论是上述的“修复”的工作时,在插件的根配置,如设置为既不plugins/maven/tsconfig.json
也不是jest
的配置在plugins/maven/package.json
。 对根配置文件进行更改似乎不会对测试或功能产生负面影响。
这是在你的分支上吗? 我大概可以解决这个问题
还没有......我确保所有测试(和新测试)在推送之前通过。 当他们准备好供您查看时,我会通知您。
我只是将 master 重新定位到我的分支上,现在我遇到了几个构建错误。
首先yarn.lock
文件因为合并冲突而被 borked,所以我不得不删除并重建它:
error Incorrect integrity when fetching from the cache for "babel-plugin-jest-hoist". Cache has "sha512-u+/W+WAjMlvoocYGTwthAiQSxDcJAyHpQ6oWlHdFZaaN+Rlk8Q7iiwDPg2lN/FyJtAYnKjFxbn7xus4HCFkg5g== sha1-EpyAulx/x1uvOkW5Pi43LVfKJnc=" and remote has "sha512-+AuoehOrjt9irZL7DOt2+4ZaTM6dlu1s5TTS46JBa0/qem4dy7VNW3tMb96qeEqcIh20LD73TVNtmVEeymTG7w==". Run `yarn cache clean` to fix the problem
一旦我这样做了,现在我收到@octokit/graphql
错误:
$ tsc -b tsconfig.dev.json
packages/core/src/auto.ts:2018:13 - error TS2571: Object is of type 'unknown'.
2018 if (result?.[`hash_${commit}`]) {
~~~~~~
packages/core/src/auto.ts:2019:27 - error TS2571: Object is of type 'unknown'.
2019 const number = (result[`hash_${commit}`] as ISearchResult).edges[0]
~~~~~~
packages/core/src/release.ts:286:52 - error TS2769: No overload matches this call.
Overload 1 of 2, '(o: ArrayLike<unknown> | { [s: string]: unknown; }): [string, unknown][]', gave the following error.
Argument of type 'unknown' is not assignable to parameter of type 'ArrayLike<unknown> | { [s: string]: unknown; }'.
Type 'unknown' is not assignable to type '{ [s: string]: unknown; }'.
Overload 2 of 2, '(o: {}): [string, any][]', gave the following error.
Argument of type 'unknown' is not assignable to parameter of type '{}'.
286 (acc, result) => [...acc, ...(Object.entries(result) as QueryEntry[])],
~~~~~~
packages/core/src/__tests__/git.test.ts:209:12 - error TS2571: Object is of type 'unknown'.
209 expect(result!.data).not.toBeUndefined();
~~~~~~~
Found 4 errors.
error Command failed with exit code 2.
我非常希望我能够为此创建一个 PR - 但我担心它还没有准备好。
好的,我想出了我需要做的事情 - 我刚刚从master
查看了yarn.lock
文件,然后重新运行了yarn clean && yarn install && yarn build && yarn test plugins/maven
,我想我很好-走。
惊人的! 我今天会回顾一下。 抱歉我周末没有回复!
:rocket: 问题已在v9.40.0
:rocket: