mirror of
https://github.com/renovatebot/renovate.git
synced 2026-10-27 07:50:47 +00:00
e0cec3dc95
feat(lint): add `types-location` rule and enable it for `lib/modules`
Reviewers consistently ask for exported types to be moved into a
colocated `types.ts`. Add a `renovate/types-location` oxlint rule that
reports `export interface` / `export type` declarations outside such a
file, and turn it on across `lib/modules`.
Re-exports (`export type { X }`, `export type *`), file-local types, and
values (enums, classes, functions) are left alone. `schema.ts` files and
`schema/` directories are excluded via config, matching how
`zod-schema-location` is configured — inferred types belong next to the
schema they are derived from.
Relocating the 87 existing violations means:
- new `types.ts` files for the modules that had none
- `terragrunt/common.ts` folded into its `types.ts`, as it held nothing
else
- `RangeBound` in `versioning/gradle/compare.ts` un-exported, since only
a file-local interface referenced it
- `bazel-module/parser/fragments.ts` split from its inferred types, which
now live in `parser/types.ts` and infer through a namespace import so
each schema keeps its merged name
114 lines
3.7 KiB
TypeScript
114 lines
3.7 KiB
TypeScript
import upath from 'upath';
|
|
import { logger } from '../../../logger/index.ts';
|
|
import { isNotNullOrUndefined } from '../../../util/array.ts';
|
|
import { regEx } from '../../../util/regex.ts';
|
|
import { LooseArray } from '../../../util/schema-utils/index.ts';
|
|
import { getDep } from '../dockerfile/extract.ts';
|
|
import type {
|
|
ExtractConfig,
|
|
PackageDependency,
|
|
PackageFileContent,
|
|
} from '../types.ts';
|
|
import * as bazelrc from './bazelrc.ts';
|
|
import { RuleToCratePackageDep } from './parser/crate.ts';
|
|
import { parse } from './parser/index.ts';
|
|
import { RuleToMavenPackageDep, fillRegistryUrls } from './parser/maven.ts';
|
|
import { RuleToDockerPackageDep } from './parser/oci.ts';
|
|
import type { ResultFragment } from './parser/types.ts';
|
|
import * as rules from './rules.ts';
|
|
import {
|
|
GitRepositoryToPackageDep,
|
|
RuleToBazelModulePackageDep,
|
|
} from './rules.ts';
|
|
import { transformRulesImgCalls } from './rules-img.ts';
|
|
|
|
export async function extractPackageFile(
|
|
content: string,
|
|
packageFile: string,
|
|
config?: ExtractConfig,
|
|
): Promise<PackageFileContent | null> {
|
|
try {
|
|
const records = parse(content);
|
|
const pfc = await extractBazelPfc(records, packageFile);
|
|
const gitRepositoryDeps = extractGitRepositoryDeps(records);
|
|
const mavenDeps = extractMavenDeps(records);
|
|
const dockerDeps = LooseArray(RuleToDockerPackageDep)
|
|
.transform((deps) =>
|
|
deps.map((dep) => {
|
|
// Reconstruct the image reference from parsed data
|
|
const imageRef = `${dep.packageName}${dep.currentValue ? `:${dep.currentValue}` : ''}${dep.currentDigest ? `@${dep.currentDigest}` : ''}`;
|
|
// Use getDep to handle registry aliases properly
|
|
const processedDep = getDep(imageRef, false, config?.registryAliases);
|
|
return {
|
|
...processedDep,
|
|
depType: 'oci_pull',
|
|
depName: dep.depName, // Keep the original name field from bazel
|
|
replaceString: dep.replaceString, // Keep the original replace string
|
|
};
|
|
}),
|
|
)
|
|
.parse(records);
|
|
const rulesImgDeps = transformRulesImgCalls(records);
|
|
const crateDeps = LooseArray(RuleToCratePackageDep).parse(records);
|
|
|
|
if (gitRepositoryDeps.length) {
|
|
pfc.deps.push(...gitRepositoryDeps);
|
|
}
|
|
|
|
if (mavenDeps.length) {
|
|
pfc.deps.push(...mavenDeps);
|
|
}
|
|
|
|
if (dockerDeps.length) {
|
|
pfc.deps.push(...dockerDeps);
|
|
}
|
|
|
|
if (rulesImgDeps.length) {
|
|
pfc.deps.push(...rulesImgDeps);
|
|
}
|
|
|
|
if (crateDeps.length) {
|
|
pfc.deps.push(...crateDeps);
|
|
}
|
|
|
|
return pfc.deps.length ? pfc : null;
|
|
} catch (err) {
|
|
logger.debug({ err, packageFile }, 'Failed to parse bazel module file.');
|
|
return null;
|
|
}
|
|
}
|
|
|
|
async function extractBazelPfc(
|
|
records: ResultFragment[],
|
|
packageFile: string,
|
|
): Promise<PackageFileContent> {
|
|
const pfc: PackageFileContent = LooseArray(RuleToBazelModulePackageDep)
|
|
.transform(rules.toPackageDependencies)
|
|
.transform((deps) => ({ deps }))
|
|
.parse(records);
|
|
|
|
const registryUrls = (await bazelrc.read(upath.dirname(packageFile)))
|
|
// Ignore any entries for custom configurations
|
|
.filter((ce) => ce.config === undefined)
|
|
.map((ce) => ce.getOption('registry')?.value)
|
|
.map((url) => url?.replace(regEx(/^["']|["']$/g), ''))
|
|
.filter(isNotNullOrUndefined);
|
|
if (registryUrls.length) {
|
|
pfc.registryUrls = registryUrls;
|
|
}
|
|
|
|
return pfc;
|
|
}
|
|
|
|
function extractGitRepositoryDeps(
|
|
records: ResultFragment[],
|
|
): PackageDependency[] {
|
|
return LooseArray(GitRepositoryToPackageDep).parse(records);
|
|
}
|
|
|
|
function extractMavenDeps(records: ResultFragment[]): PackageDependency[] {
|
|
return LooseArray(RuleToMavenPackageDep)
|
|
.transform(fillRegistryUrls)
|
|
.parse(records);
|
|
}
|