mirror of
https://github.com/renovatebot/renovate.git
synced 2026-10-25 23:11:31 +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
74 lines
2.1 KiB
TypeScript
74 lines
2.1 KiB
TypeScript
import { regEx } from '../../../util/regex.ts';
|
|
import { GenericVersioningApi } from '../generic.ts';
|
|
import type { GenericVersion, VersioningApi } from '../types.ts';
|
|
|
|
export const id = 'devbox';
|
|
export const displayName = 'devbox';
|
|
export const urls = [];
|
|
export const supportsRanges = false;
|
|
|
|
const validPattern = regEx(/^((\d|[1-9]\d*)(\.(\d|[1-9]\d*)){0,2})$/);
|
|
const versionPattern = regEx(/^((\d|[1-9]\d*)(\.(\d|[1-9]\d*)){2})$/);
|
|
|
|
class DevboxVersioningApi extends GenericVersioningApi {
|
|
protected _parse(version: string): GenericVersion | null {
|
|
const matches = validPattern.exec(version);
|
|
if (!matches) {
|
|
return null;
|
|
}
|
|
const release = matches[0].split('.').map(Number);
|
|
return { release };
|
|
}
|
|
|
|
override isValid(version: string): boolean {
|
|
if (version === 'latest') {
|
|
return true;
|
|
}
|
|
return this._parse(version) !== null;
|
|
}
|
|
|
|
override isVersion(version: string): boolean {
|
|
if (version === 'latest') {
|
|
return false;
|
|
}
|
|
const matches = versionPattern.exec(version);
|
|
return !!matches;
|
|
}
|
|
|
|
override matches(version: string, range: string): boolean {
|
|
return this.isVersion(version) && this.equals(version, range);
|
|
}
|
|
|
|
protected override _compare(version: string, other: string): number {
|
|
const parsed1 = this._parse(version);
|
|
const parsed2 = this._parse(other);
|
|
|
|
// Treat "latest" as * and always return equal
|
|
if (other === 'latest' && parsed1) {
|
|
return 0;
|
|
}
|
|
|
|
// If either version is invalid, return unequal
|
|
if (!(parsed1 && parsed2)) {
|
|
return 1;
|
|
}
|
|
// support variable length compare
|
|
const length = Math.max(parsed1.release.length, parsed2.release.length);
|
|
for (let i = 0; i < length; i += 1) {
|
|
// 2.1 and 2.1.0 are equivalent
|
|
const part1 = parsed1.release[i];
|
|
const part2 = parsed2.release[i];
|
|
// if part1 or part2 is undefined, we should treat them as equal
|
|
// e.g. 1.0.0 === 1.0
|
|
if (part1 !== undefined && part2 !== undefined && part1 !== part2) {
|
|
return part1 - part2;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
export const api: VersioningApi = new DevboxVersioningApi();
|
|
|
|
export default api;
|