mirror of
https://github.com/renovatebot/renovate.git
synced 2026-10-31 17:51:49 +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
92 lines
3.2 KiB
TypeScript
92 lines
3.2 KiB
TypeScript
import { isUndefined } from '@sindresorhus/is';
|
|
import { CONFIG_VALIDATION } from '../../../constants/error-messages.ts';
|
|
import { regEx } from '../../../util/regex.ts';
|
|
import { GenericVersioningApi } from '../generic.ts';
|
|
import type { VersioningApiConstructor } from '../types.ts';
|
|
import type { RegExpVersion } from './types.ts';
|
|
|
|
export const id = 'regex';
|
|
export const displayName = 'Regular Expression';
|
|
export const urls = [];
|
|
export const supportsRanges = false;
|
|
|
|
export class RegExpVersioningApi extends GenericVersioningApi<RegExpVersion> {
|
|
// config is expected to be overridden by a user-specified RegExp value
|
|
// sample values:
|
|
//
|
|
// * emulates the "semver" configuration:
|
|
// RegExp('^(?<major>\\d+)\\.(?<minor>\\d+)\\.(?<patch>\\d+)(-(?<prerelease>.*))?$')
|
|
// * emulates the "docker" configuration:
|
|
// RegExp('^(?<major>\\d+)\\.(?<minor>\\d+)\\.(?<patch>\\d+)(-(?<compatibility>.*))?$')
|
|
// * matches the versioning approach used by the Python images on DockerHub:
|
|
// RegExp('^(?<major>\\d+)\\.(?<minor>\\d+)\\.(?<patch>\\d+)(?<prerelease>[^.-]+)?(-(?<compatibility>.*))?$');
|
|
// * matches the versioning approach used by the Bitnami images on DockerHub:
|
|
// RegExp('^(?<major>\\d+)\\.(?<minor>\\d+)\\.(?<patch>\\d+)(:?-(?<compatibility>.*-r)(?<build>\\d+))?$');
|
|
protected readonly _config: RegExp;
|
|
|
|
constructor(_new_config: string | undefined) {
|
|
super();
|
|
const new_config = _new_config ?? '^(?<major>\\d+)?$';
|
|
|
|
// without at least one of {major, minor, patch} specified in the regex,
|
|
// this versioner will not work properly
|
|
if (
|
|
!new_config.includes('<major>') &&
|
|
!new_config.includes('<minor>') &&
|
|
!new_config.includes('<patch>')
|
|
) {
|
|
const error = new Error(CONFIG_VALIDATION);
|
|
error.validationSource = new_config;
|
|
error.validationError =
|
|
'regex versioning needs at least one major, minor or patch group defined';
|
|
throw error;
|
|
}
|
|
|
|
// TODO: should we validate the user has not added extra unsupported
|
|
// capture groups? (#9717)
|
|
this._config = regEx(new_config);
|
|
}
|
|
|
|
// convenience method for passing a string into a Version given current config.
|
|
protected _parse(version: string): RegExpVersion | null {
|
|
const groups = this._config?.exec(version)?.groups;
|
|
if (!groups) {
|
|
return null;
|
|
}
|
|
|
|
const { major, minor, patch, build, revision, prerelease, compatibility } =
|
|
groups;
|
|
const release = [
|
|
isUndefined(major) ? 0 : Number.parseInt(major, 10),
|
|
isUndefined(minor) ? 0 : Number.parseInt(minor, 10),
|
|
isUndefined(patch) ? 0 : Number.parseInt(patch, 10),
|
|
];
|
|
|
|
if (build) {
|
|
release.push(Number.parseInt(build, 10));
|
|
if (revision) {
|
|
release.push(Number.parseInt(revision, 10));
|
|
}
|
|
}
|
|
|
|
return {
|
|
release,
|
|
prerelease,
|
|
compatibility,
|
|
};
|
|
}
|
|
|
|
override isCompatible(version: string, current: string): boolean {
|
|
const parsedVersion = this._parse(version);
|
|
const parsedCurrent = this._parse(current);
|
|
return !!(
|
|
parsedVersion &&
|
|
parsedVersion.compatibility === parsedCurrent?.compatibility
|
|
);
|
|
}
|
|
}
|
|
|
|
export const api: VersioningApiConstructor = RegExpVersioningApi;
|
|
|
|
export default api;
|