-
Notifications
You must be signed in to change notification settings - Fork 2.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(gomod): Notify extra packages updated by "go get" (#28938)
Signed-off-by: Quentin BERTRAND <[email protected]> Co-authored-by: Michael Kriese <[email protected]> Co-authored-by: Rhys Arkins <[email protected]> Co-authored-by: Quentin BERTRAND <[email protected]> Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Miles Budnek <[email protected]> Co-authored-by: Alex Kessock <[email protected]> Co-authored-by: HonkingGoose <[email protected]> Co-authored-by: Florian Greinacher <[email protected]> Co-authored-by: ddovile <[email protected]> Co-authored-by: Dovile Dikoviciute <[email protected]> Co-authored-by: lstoeferle <[email protected]> Co-authored-by: Stéphane Goetz <[email protected]>
- Loading branch information
1 parent
1965526
commit cc5f68e
Showing
7 changed files
with
325 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,138 @@ | ||
import { codeBlock } from 'common-tags'; | ||
import { | ||
extraDepsTable, | ||
getExtraDeps, | ||
getExtraDepsNotice, | ||
} from './artifacts-extra'; | ||
import type { ExtraDep } from './types'; | ||
|
||
describe('modules/manager/gomod/artifacts-extra', () => { | ||
const goModBefore = codeBlock` | ||
go 1.22.0 | ||
require ( | ||
github.com/foo/foo v1.0.0 | ||
github.com/bar/bar v2.0.0 | ||
) | ||
replace baz/baz => qux/qux | ||
`; | ||
|
||
const goModAfter = codeBlock` | ||
go 1.22.2 | ||
// Note the order change | ||
require ( | ||
github.com/bar/bar v2.2.2 | ||
github.com/foo/foo v1.1.1 | ||
) | ||
replace baz/baz => quux/quux | ||
`; | ||
|
||
describe('getExtraDeps', () => { | ||
it('detects extra dependencies', () => { | ||
const excludeDeps = ['github.com/foo/foo']; | ||
|
||
const res = getExtraDeps(goModBefore, goModAfter, excludeDeps); | ||
|
||
expect(res).toEqual([ | ||
{ | ||
depName: 'go', | ||
currentValue: '1.22.0', | ||
newValue: '1.22.2', | ||
}, | ||
{ | ||
depName: 'github.com/bar/bar', | ||
currentValue: 'v2.0.0', | ||
newValue: 'v2.2.2', | ||
}, | ||
] satisfies ExtraDep[]); | ||
}); | ||
}); | ||
|
||
describe('extraDepsTable', () => { | ||
it('generates a table', () => { | ||
const extraDeps: ExtraDep[] = [ | ||
{ | ||
depName: 'github.com/foo/foo', | ||
currentValue: 'v1.0.0', | ||
newValue: 'v1.1.1', | ||
}, | ||
{ | ||
depName: 'github.com/bar/bar', | ||
currentValue: 'v2.0.0', | ||
newValue: 'v2.2.2', | ||
}, | ||
]; | ||
|
||
const res = extraDepsTable(extraDeps); | ||
|
||
expect(res).toEqual( | ||
[ | ||
'| **Package** | **Change** |', | ||
'| :------------------- | :------------------- |', | ||
'| `github.com/foo/foo` | `v1.0.0` -> `v1.1.1` |', | ||
'| `github.com/bar/bar` | `v2.0.0` -> `v2.2.2` |', | ||
].join('\n'), | ||
); | ||
}); | ||
}); | ||
|
||
describe('getExtraDepsNotice', () => { | ||
it('returns null when one of files is missing', () => { | ||
expect(getExtraDepsNotice(null, goModAfter, [])).toBeNull(); | ||
expect(getExtraDepsNotice(goModBefore, null, [])).toBeNull(); | ||
}); | ||
|
||
it('returns null when all dependencies are excluded', () => { | ||
const excludeDeps = ['go', 'github.com/foo/foo', 'github.com/bar/bar']; | ||
const res = getExtraDepsNotice(goModBefore, goModAfter, excludeDeps); | ||
expect(res).toBeNull(); | ||
}); | ||
|
||
it('returns a notice when there are extra dependencies', () => { | ||
const excludeDeps = ['go', 'github.com/foo/foo']; | ||
|
||
const res = getExtraDepsNotice(goModBefore, goModAfter, excludeDeps); | ||
|
||
expect(res).toEqual( | ||
[ | ||
'In order to perform the update(s) described in the table above, Renovate ran the `go get` command, which resulted in the following additional change(s):', | ||
'', | ||
'', | ||
'- 1 additional dependency was updated', | ||
'', | ||
'', | ||
'Details:', | ||
'| **Package** | **Change** |', | ||
'| :------------------- | :------------------- |', | ||
'| `github.com/bar/bar` | `v2.0.0` -> `v2.2.2` |', | ||
].join('\n'), | ||
); | ||
}); | ||
|
||
it('adds special notice for updated `go` version', () => { | ||
const excludeDeps = ['github.com/foo/foo']; | ||
|
||
const res = getExtraDepsNotice(goModBefore, goModAfter, excludeDeps); | ||
|
||
expect(res).toEqual( | ||
[ | ||
'In order to perform the update(s) described in the table above, Renovate ran the `go get` command, which resulted in the following additional change(s):', | ||
'', | ||
'', | ||
'- 1 additional dependency was updated', | ||
'- The `go` directive was updated for compatibility reasons', | ||
'', | ||
'', | ||
'Details:', | ||
'| **Package** | **Change** |', | ||
'| :------------------- | :------------------- |', | ||
'| `go` | `1.22.0` -> `1.22.2` |', | ||
'| `github.com/bar/bar` | `v2.0.0` -> `v2.2.2` |', | ||
].join('\n'), | ||
); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
import { diffLines } from 'diff'; | ||
import markdownTable from 'markdown-table'; | ||
import { parseLine } from './line-parser'; | ||
import type { ExtraDep } from './types'; | ||
|
||
export function getExtraDeps( | ||
goModBefore: string, | ||
goModAfter: string, | ||
excludeDeps: string[], | ||
): ExtraDep[] { | ||
const result: ExtraDep[] = []; | ||
|
||
const diff = diffLines(goModBefore, goModAfter, { | ||
newlineIsToken: true, | ||
}); | ||
|
||
const addDeps: Record<string, string> = {}; | ||
const rmDeps: Record<string, string> = {}; | ||
for (const { added, removed, value } of diff) { | ||
if (!added && !removed) { | ||
continue; | ||
} | ||
|
||
const res = parseLine(value); | ||
if (!res) { | ||
continue; | ||
} | ||
|
||
const { depName, currentValue } = res; | ||
if (!depName || !currentValue) { | ||
continue; | ||
} | ||
|
||
if (added) { | ||
addDeps[depName] = currentValue; | ||
} else { | ||
rmDeps[depName] = currentValue; | ||
} | ||
} | ||
|
||
for (const [depName, currentValue] of Object.entries(rmDeps)) { | ||
if (excludeDeps.includes(depName)) { | ||
continue; | ||
} | ||
|
||
const newValue = addDeps[depName]; | ||
if (newValue) { | ||
result.push({ | ||
depName, | ||
currentValue, | ||
newValue, | ||
}); | ||
} | ||
} | ||
|
||
return result; | ||
} | ||
|
||
export function extraDepsTable(extraDeps: ExtraDep[]): string { | ||
const tableLines: string[][] = []; | ||
|
||
tableLines.push(['**Package**', '**Change**']); | ||
|
||
for (const { depName, currentValue, newValue } of extraDeps) { | ||
const depNameQuoted = `\`${depName}\``; | ||
const versionChangeQuoted = `\`${currentValue}\` -> \`${newValue}\``; | ||
tableLines.push([depNameQuoted, versionChangeQuoted]); | ||
} | ||
|
||
return markdownTable(tableLines, { | ||
align: ['l', 'l'], | ||
}); | ||
} | ||
|
||
export function getExtraDepsNotice( | ||
goModBefore: string | null, | ||
goModAfter: string | null, | ||
excludeDeps: string[], | ||
): string | null { | ||
if (!goModBefore || !goModAfter) { | ||
return null; | ||
} | ||
|
||
const extraDeps = getExtraDeps(goModBefore, goModAfter, excludeDeps); | ||
if (extraDeps.length === 0) { | ||
return null; | ||
} | ||
|
||
const noticeLines: string[] = [ | ||
'In order to perform the update(s) described in the table above, Renovate ran the `go get` command, which resulted in the following additional change(s):', | ||
'\n', | ||
]; | ||
|
||
const goUpdated = extraDeps.some(({ depName }) => depName === 'go'); | ||
const otherDepsCount = extraDeps.length - (goUpdated ? 1 : 0); | ||
|
||
if (otherDepsCount > 0) { | ||
noticeLines.push(`- ${otherDepsCount} additional dependency was updated`); | ||
} | ||
|
||
if (goUpdated) { | ||
noticeLines.push( | ||
'- The `go` directive was updated for compatibility reasons', | ||
); | ||
} | ||
|
||
noticeLines.push('\n'); | ||
noticeLines.push('Details:'); | ||
noticeLines.push(extraDepsTable(extraDeps)); | ||
|
||
return noticeLines.join('\n'); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.