mirror of
https://github.com/renovatebot/renovate.git
synced 2026-10-25 15:01:49 +00:00
312c380926
* fix(util/http): make the legacy `headers` getter configurable Every other property defined on `HttpError.prototype` in this file is `configurable`, but `headers` was not. That makes the module fail with `TypeError: Cannot redefine property: headers` whenever a test resets the module registry and re-imports anything that pulls in `got.ts`. Co-authored-by: Claude Opus 5 <michael.kriese+claude-code@mend.io> * test(manager/pre-commit): cover the suppress-warning env var `defaultConfig.prBodyNotes` drops the unsupported-manager warning when `RENOVATE_X_SUPPRESS_PRE_COMMIT_WARNING` is set. Since the value is computed at module load, the new spec resets the module registry and re-imports the manager with the variable stubbed. The `istanbul ignore next` on that arm is dropped because the branch is now exercised. Co-authored-by: Claude Opus 5 <michael.kriese+claude-code@mend.io> * refactor(manager): remove unreachable fallbacks Drop three defensive fallbacks that can never be taken: - `docker-compose`: `config.services ?? config` always yields an object, so the `|| {}` guard behind it is dead - `git-submodules`: `git.raw()` resolves to a string, so the `?? ''` never applies - `maven`: the only site that builds a `MavenProp` always passes a `packageFile` string, so narrow the type and drop the `?? undefined` Co-authored-by: Claude Opus 5 <michael.kriese+claude-code@mend.io> --------- Co-authored-by: Claude Opus 5 <michael.kriese+claude-code@mend.io>
134 lines
3.6 KiB
TypeScript
134 lines
3.6 KiB
TypeScript
import type { SimpleGit } from 'simple-git';
|
|
import upath from 'upath';
|
|
import { GlobalConfig } from '../../../config/global.ts';
|
|
import { logger } from '../../../logger/index.ts';
|
|
import { createSimpleGit } from '../../../util/git/index.ts';
|
|
import { getHttpUrl } from '../../../util/git/url.ts';
|
|
import { regEx } from '../../../util/regex.ts';
|
|
import { GitRefsDatasource } from '../../datasource/git-refs/index.ts';
|
|
import * as semVerVersioning from '../../versioning/semver/index.ts';
|
|
import type { ExtractConfig, PackageFileContent } from '../types.ts';
|
|
import type { GitModule } from './types.ts';
|
|
|
|
async function getUrl(
|
|
git: SimpleGit,
|
|
gitModulesPath: string,
|
|
submoduleName: string,
|
|
): Promise<string> {
|
|
const path = (
|
|
await createSimpleGit().raw([
|
|
'config',
|
|
'--file',
|
|
gitModulesPath,
|
|
'--get',
|
|
`submodule.${submoduleName}.url`,
|
|
])
|
|
)?.trim();
|
|
if (!path?.startsWith('../') && !path?.startsWith('./')) {
|
|
return path;
|
|
}
|
|
const remoteUrl = (
|
|
await git.raw(['config', '--get', 'remote.origin.url'])
|
|
).trim();
|
|
return new URL(path, `${remoteUrl}/`).href;
|
|
}
|
|
|
|
async function getBranch(
|
|
git: SimpleGit,
|
|
gitModulesPath: string,
|
|
submoduleName: string,
|
|
): Promise<string | null> {
|
|
const branchFromConfig = (
|
|
await createSimpleGit().raw([
|
|
'config',
|
|
'--file',
|
|
gitModulesPath,
|
|
'--get',
|
|
`submodule.${submoduleName}.branch`,
|
|
])
|
|
).trim();
|
|
|
|
return branchFromConfig === '.'
|
|
? (await git.branch(['--list'])).current.trim()
|
|
: branchFromConfig || null;
|
|
}
|
|
|
|
async function getModules(
|
|
git: SimpleGit,
|
|
gitModulesPath: string,
|
|
): Promise<GitModule[]> {
|
|
const res: GitModule[] = [];
|
|
try {
|
|
const modules = (
|
|
await git.raw([
|
|
'config',
|
|
'--file',
|
|
gitModulesPath,
|
|
'--get-regexp',
|
|
'\\.path',
|
|
])
|
|
)
|
|
.trim()
|
|
.split(regEx(/\n/))
|
|
.filter((s) => !!s);
|
|
|
|
for (const line of modules) {
|
|
const [, name, path] = line.split(
|
|
regEx(/submodule\.(?<name>.+?)\.path\s(?<path>.+)/),
|
|
);
|
|
res.push({ name, path });
|
|
}
|
|
} catch (err) /* istanbul ignore next */ {
|
|
logger.warn({ err }, 'Error getting git submodules during extract');
|
|
}
|
|
return res;
|
|
}
|
|
|
|
export default async function extractPackageFile(
|
|
_content: string,
|
|
packageFile: string,
|
|
_config: ExtractConfig,
|
|
): Promise<PackageFileContent | null> {
|
|
const localDir = GlobalConfig.get('localDir');
|
|
const git = createSimpleGit({ config: { baseDir: localDir } });
|
|
const gitModulesPath = upath.join(localDir, packageFile);
|
|
|
|
const depNames = await getModules(git, gitModulesPath);
|
|
|
|
if (!depNames.length) {
|
|
return null;
|
|
}
|
|
|
|
const deps = [];
|
|
for (const { name, path } of depNames) {
|
|
try {
|
|
const [currentDigest] = (
|
|
await git.subModule(['status', '--cached', path])
|
|
)
|
|
.trim()
|
|
.replace(regEx(/^[-+]/), '')
|
|
.split(regEx(/\s/));
|
|
const subModuleUrl = await getUrl(git, gitModulesPath, name);
|
|
const httpSubModuleUrl = getHttpUrl(subModuleUrl);
|
|
const branch = await getBranch(git, gitModulesPath, name);
|
|
deps.push({
|
|
depName: path,
|
|
packageName: httpSubModuleUrl,
|
|
sourceUrl: httpSubModuleUrl.replace(regEx(/\.git$/), ''),
|
|
currentValue: branch ?? undefined,
|
|
currentDigest,
|
|
...(semVerVersioning.api.isVersion(branch)
|
|
? { versioning: semVerVersioning.id }
|
|
: {}),
|
|
});
|
|
} catch (err) /* istanbul ignore next */ {
|
|
logger.warn(
|
|
{ err, packageFile },
|
|
'Error mapping git submodules during extraction',
|
|
);
|
|
}
|
|
}
|
|
|
|
return { deps, datasource: GitRefsDatasource.id };
|
|
}
|