Allow a Link trailer to be used as an alternative change ID trailer In some projects it may be desirable for the trailer to contain a link to the Gerrit review page so that it is convenient to access the review page starting from the commit message. The Link trailer is a standard trailer used for inserting links in the commit message, which has been adopted by the Linux kernel among other projects. For example, the Linux kernel has a policy about linking to the mailing list archive with Link trailers: https://www.kernel.org/doc/html/latest/maintainer/configure-git.html#creating-commit-links-to-lore-kernel-org This change makes Gerrit interoperate well with the Link trailer. Specifically, it teaches the Gerrit server to recognize trailers of the form: Link: https://gerrit-review.googlesource.com/id/I78e884a944cedb5144f661a057e4829c8f84e933 as well as the existing Change-Id trailer, teaches the server to recognize /id/ as a search prefix for change IDs and modifies the commit-msg hook to optionally add a Link trailer (using a server URL provided in the property gerrit.reviewUrl) instead of the Change-Id trailer. Change-Id: I78e884a944cedb5144f661a057e4829c8f84e933
diff --git a/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view.js b/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view.js index 1094809..38f7c06 100644 --- a/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view.js +++ b/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view.js
@@ -78,7 +78,8 @@ MISMATCH: 'mismatch', MISSING: 'missing', }; -const CHANGE_ID_REGEX_PATTERN = /^Change-Id\:\s(I[0-9a-f]{8,40})/gm; +const CHANGE_ID_REGEX_PATTERN = + /^(Change-Id\:\s|Link:.*\/id\/)(I[0-9a-f]{8,40})/gm; const MIN_LINES_FOR_COMMIT_COLLAPSE = 30; const DEFAULT_NUM_FILES_SHOWN = 200; @@ -1316,7 +1317,7 @@ let changeIdArr; while (changeIdArr = CHANGE_ID_REGEX_PATTERN.exec(commitMessage)) { - changeId = changeIdArr[1]; + changeId = changeIdArr[2]; } if (changeId) {
diff --git a/polygerrit-ui/app/elements/core/gr-router/gr-router.ts b/polygerrit-ui/app/elements/core/gr-router/gr-router.ts index 3ffd819..5261426 100644 --- a/polygerrit-ui/app/elements/core/gr-router/gr-router.ts +++ b/polygerrit-ui/app/elements/core/gr-router/gr-router.ts
@@ -160,6 +160,8 @@ */ QUERY_LEGACY_SUFFIX: /^\/q\/.+,n,z$/, + CHANGE_ID_QUERY: /^\/id\/(I[0-9a-f]{40})$/, + // Matches /c/<changeNum>/[<basePatchNum>..][<patchNum>][/]. CHANGE_LEGACY: /^\/c\/(\d+)\/?(((-?\d+|edit)(\.\.(\d+|edit))?))?\/?$/, CHANGE_NUMBER_LEGACY: /^\/(\d+)\/?/, @@ -1018,6 +1020,8 @@ this._mapRoute(RoutePattern.QUERY, '_handleQueryRoute'); + this._mapRoute(RoutePattern.CHANGE_ID_QUERY, '_handleChangeIdQueryRoute'); + this._mapRoute(RoutePattern.DIFF_LEGACY_LINENUM, '_handleLegacyLinenum'); this._mapRoute( @@ -1510,6 +1514,16 @@ }); } + _handleChangeIdQueryRoute(data: PageContextWithQueryMap) { + // TODO(pcc): This will need to indicate that this was a change ID query if + // standard queries gain the ability to search places like commit messages + // for change IDs. + this._setParams({ + view: GerritNav.View.SEARCH, + query: data.params[0], + }); + } + _handleQueryLegacySuffixRoute(ctx: PageContextWithQueryMap) { this._redirect(ctx.path.replace(LEGACY_QUERY_SUFFIX_PATTERN, '')); }
diff --git a/polygerrit-ui/app/elements/core/gr-router/gr-router_test.js b/polygerrit-ui/app/elements/core/gr-router/gr-router_test.js index a931aac..5ee58c9 100644 --- a/polygerrit-ui/app/elements/core/gr-router/gr-router_test.js +++ b/polygerrit-ui/app/elements/core/gr-router/gr-router_test.js
@@ -182,6 +182,7 @@ '_handleBranchListFilterOffsetRoute', '_handleBranchListFilterRoute', '_handleBranchListOffsetRoute', + '_handleChangeIdQueryRoute', '_handleChangeNumberLegacyRoute', '_handleChangeRoute', '_handleCommentRoute', @@ -739,6 +740,14 @@ }); }); + test('_handleChangeIdQueryRoute', () => { + const data = {params: ['I0123456789abcdef0123456789abcdef01234567']}; + assertDataToParams(data, '_handleChangeIdQueryRoute', { + view: GerritNav.View.SEARCH, + query: 'I0123456789abcdef0123456789abcdef01234567', + }); + }); + suite('_handleRegisterRoute', () => { test('happy path', () => { const ctx = {params: ['/foo/bar']};