mirror of
https://github.com/renovatebot/renovate.git
synced 2026-11-02 02:29:51 +00:00
55a7341be2
* test(manager): close azure-pipelines, bundler and cocoapods gaps Adds a pipeline whose step task is not versioned, so nothing is extracted, and a gem lock line carrying no version, which is skipped. Marks four guards that cannot be false: `extractContainer()` always returns a dep, `getLockFilePath()` always returns a path, and the cocoapods dep name, spec name and git account all derive from values their enclosing check already proved present. Co-Authored-By: Claude Opus 5 <michael.kriese+claude-code@mend.io> * test(manager): close cargo, composer and cpanfile gaps Adds a composer repository map that disables something other than packagist, which is dropped rather than recorded. Marks five guards: the cargo warning only fires for a crate dep and its retry only runs when a dep was already current, a gitlab rule without a token never passes the auth check, and both cpanfile handlers run only once their match produced a value. Two implicit elses stay counted, in the cargo version resolver and the composer repository mapper, since a coverage-ignore hint does not attach to an `else if`. Co-Authored-By: Claude Opus 5 <michael.kriese+claude-code@mend.io> * test(manager): close deps-edn, docker-compose and dockerfile gaps Adds three extractions: a deps.edn alias whose value is not a map, a compose extension carrying no image, and a dockerfile escape directive naming a character other than a backtick, which leaves the default in place. Marks the deps-edn repository name check, since object keys are always strings, and notes the repository spec chain, where a coverage-ignore hint does not attach to an `else if`. Co-Authored-By: Claude Opus 5 <michael.kriese+claude-code@mend.io> * test(manager/flux): close the flux coverage gaps Adds two GitRepository resources whose url is ssh rather than http, one pinned to a tag and one to a commit. Neither yields a source url, since only http urls can be turned into one. Marks the Kustomization image guard: the schema rejects an image without a name, so `extractImage()` cannot return null there. Co-Authored-By: Claude Opus 5 <michael.kriese+claude-code@mend.io> * test(manager): mark github-actions, gitlabci and glasskube guards None of these six needs a test. A parsed action ref is either a docker or a repository ref, `getDep()` always returns a dep for a job container and a service, and the remaining three need a listed file that cannot be read, a listed file that yields no deps, or a manifest whose repositories match no name. The glasskube resource kind chain stays counted, since a coverage-ignore hint does not attach to an `else if`. Co-Authored-By: Claude Opus 5 <michael.kriese+claude-code@mend.io> * test(manager): mark gomod and gradle-wrapper guards Four guards that need setups no test provides: a removed dep that is not added back, a go.mod the replace massaging leaves unchanged, and a daemon-jvm file carrying no toolchain version. A parsed go directive always yields a version. The additional-dependency count chain stays counted, since a coverage-ignore hint does not attach to an `else if`. Co-Authored-By: Claude Opus 5 <michael.kriese+claude-code@mend.io> --------- Co-authored-by: Claude Opus 5 <michael.kriese+claude-code@mend.io>
142 lines
3.9 KiB
TypeScript
142 lines
3.9 KiB
TypeScript
import { diffLines } from 'diff';
|
|
import { markdownTable } from 'markdown-table';
|
|
import type { UpdateArtifactsConfig } from '../types.ts';
|
|
import { parseLine } from './line-parser.ts';
|
|
import type { ExtraDep } from './types.ts';
|
|
|
|
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, depType, currentValue } = res;
|
|
if (!depName || !currentValue) {
|
|
continue;
|
|
}
|
|
|
|
let expandedDepName = depName;
|
|
// NOTE: Right now the only special depType we care about is 'toolchain' because the table
|
|
// rendering prior to this change was ambiguous with regards to go version vs toolchain
|
|
// version updates.
|
|
if (depType === 'toolchain') {
|
|
expandedDepName = `${depName} (${depType})`;
|
|
}
|
|
|
|
if (added) {
|
|
addDeps[expandedDepName] = currentValue;
|
|
} else {
|
|
rmDeps[expandedDepName] = currentValue;
|
|
}
|
|
}
|
|
|
|
for (const [depName, currentValue] of Object.entries(rmDeps)) {
|
|
if (excludeDeps.includes(depName)) {
|
|
continue;
|
|
}
|
|
|
|
const newValue = addDeps[depName];
|
|
// v8 ignore else -- needs a removed dep that is not added back
|
|
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[],
|
|
{ minimumReleaseAge }: Pick<UpdateArtifactsConfig, 'minimumReleaseAge'>,
|
|
): 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 toolchainUpdated = extraDeps.some(
|
|
({ depName }) => depName === 'go (toolchain)',
|
|
);
|
|
const otherDepsCount =
|
|
extraDeps.length - (goUpdated ? 1 : 0) - (toolchainUpdated ? 1 : 0);
|
|
|
|
if (otherDepsCount === 1) {
|
|
noticeLines.push(`- ${otherDepsCount} additional dependency was updated`);
|
|
// NOTE: a zero count adds no line. A coverage-ignore hint cannot suppress
|
|
// the implicit else on an `else if`.
|
|
} else if (otherDepsCount > 1) {
|
|
noticeLines.push(
|
|
`- ${otherDepsCount} additional dependencies were updated`,
|
|
);
|
|
}
|
|
|
|
if (goUpdated) {
|
|
noticeLines.push(
|
|
'- The `go` directive was updated for compatibility reasons',
|
|
);
|
|
}
|
|
|
|
if (minimumReleaseAge) {
|
|
noticeLines.push('\n');
|
|
noticeLines.push(
|
|
`Due to Go's usage of [Minimal Version Selection (MVS)](https://go.dev/ref/mod#minimal-version-selection), these packages have been updated to the minimum version available, so will still abide by \`minimumReleaseAge=${minimumReleaseAge}\``,
|
|
);
|
|
}
|
|
|
|
noticeLines.push('\n');
|
|
noticeLines.push('Details:');
|
|
noticeLines.push('\n');
|
|
noticeLines.push(extraDepsTable(extraDeps));
|
|
|
|
return noticeLines.join('\n');
|
|
}
|