mirror of
https://github.com/renovatebot/renovate.git
synced 2026-11-02 10:33:39 +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>
133 lines
3.1 KiB
TypeScript
133 lines
3.1 KiB
TypeScript
import { newlineRegex } from '../../../util/regex.ts';
|
|
import type { PackageDependency, PackageFileContent } from '../types.ts';
|
|
import {
|
|
endBlockRegex,
|
|
excludeBlockStartRegex,
|
|
parseLine,
|
|
} from './line-parser.ts';
|
|
|
|
function findMatchingModule(
|
|
tool: PackageDependency,
|
|
deps: PackageDependency[],
|
|
): PackageDependency | undefined {
|
|
let bestMatch: PackageDependency | undefined;
|
|
const normalizedTool = `${tool.depName!}/`;
|
|
|
|
// Find the longest matching prefix for the tool within the dependencies
|
|
for (const dep of deps) {
|
|
if (
|
|
normalizedTool.startsWith(`${dep.depName!}/`) &&
|
|
dep.depName!.length > (bestMatch?.depName!.length ?? 0)
|
|
) {
|
|
bestMatch = dep;
|
|
}
|
|
}
|
|
|
|
return bestMatch;
|
|
}
|
|
|
|
export function extractPackageFile(content: string): PackageFileContent | null {
|
|
const deps: PackageDependency[] = [];
|
|
const tools: PackageDependency[] = [];
|
|
let inExcludeBlock = false;
|
|
|
|
const lines = content.split(newlineRegex);
|
|
for (let lineNumber = 0; lineNumber < lines.length; lineNumber += 1) {
|
|
const line = lines[lineNumber];
|
|
const dep = parseLine(line);
|
|
|
|
if (inExcludeBlock) {
|
|
if (endBlockRegex.test(line)) {
|
|
inExcludeBlock = false;
|
|
}
|
|
continue;
|
|
}
|
|
|
|
if (!dep) {
|
|
if (excludeBlockStartRegex.test(line)) {
|
|
inExcludeBlock = true;
|
|
}
|
|
continue;
|
|
}
|
|
|
|
if (dep.depType === 'tool') {
|
|
tools.push(dep);
|
|
continue;
|
|
}
|
|
|
|
dep.managerData ??= {};
|
|
dep.managerData.lineNumber = lineNumber;
|
|
|
|
deps.push(dep);
|
|
}
|
|
|
|
for (const tool of tools) {
|
|
const match = findMatchingModule(tool, deps);
|
|
if (match?.depType === 'indirect') {
|
|
delete match.enabled;
|
|
}
|
|
}
|
|
|
|
if (!deps.length) {
|
|
return null;
|
|
}
|
|
|
|
const packageFile: PackageFileContent = {
|
|
deps,
|
|
};
|
|
|
|
const goDirective = packageFile.deps.find(
|
|
(dep) =>
|
|
dep.depName === 'go' &&
|
|
dep.depType === 'golang' &&
|
|
dep.datasource === 'golang-version',
|
|
);
|
|
if (goDirective?.currentValue) {
|
|
packageFile.extractedConstraints ??= {};
|
|
const range = convertGoDirectiveToSemVerRange(goDirective.currentValue);
|
|
// v8 ignore else -- a parsed go directive always yields a version
|
|
if (range.version) {
|
|
packageFile.extractedConstraints['%goMod'] = range.version;
|
|
|
|
packageFile.constraintsVersioning ??= {};
|
|
packageFile.constraintsVersioning['%goMod'] = range.versioning;
|
|
}
|
|
}
|
|
|
|
const toolchainDirective = packageFile.deps.find(
|
|
(dep) =>
|
|
dep.depName === 'go' &&
|
|
dep.depType === 'toolchain' &&
|
|
dep.datasource === 'golang-version',
|
|
);
|
|
if (toolchainDirective?.currentValue) {
|
|
packageFile.extractedConstraints ??= {};
|
|
packageFile.extractedConstraints.golang = toolchainDirective.currentValue;
|
|
}
|
|
|
|
return packageFile;
|
|
}
|
|
|
|
export function convertGoDirectiveToSemVerRange(
|
|
goDirective: string | undefined,
|
|
):
|
|
| {
|
|
version: string;
|
|
versioning: string;
|
|
}
|
|
| {
|
|
version: undefined;
|
|
} {
|
|
if (!goDirective) {
|
|
return {
|
|
version: undefined,
|
|
};
|
|
}
|
|
|
|
const parts = goDirective.split('.');
|
|
return {
|
|
version: `~${parts[0]}.${parts[1]}.x`,
|
|
versioning: 'semver-coerced',
|
|
};
|
|
}
|