Files
renovate/lib/modules/versioning/docker/index.ts
T
Sergei Zharinov 41bfb8678e refactor(lint): use oxlint for type-aware rules (#41739)
* feat: enable oxlint type-aware linting

Move type-aware typescript-eslint rules from ESLint to oxlint,
leveraging oxlint-tsgolint for type information. This removes
the need for ESLint's projectService and parserOptions.

- Add `options.typeAware: true` to .oxlintrc.json with all
  type-aware rules (recommendedTypeChecked + stylisticTypeChecked)
- Switch ESLint to non-type-aware configs (recommended, stylistic)
- Remove projectService/parserOptions from ESLint config
- Drop @typescript-eslint/naming-convention (no oxlint equivalent)
- Update oxlint/eslint-plugin-oxlint to 1.51.0
- Add oxlint-tsgolint dependency
- Convert eslint-disable comments to oxlint-disable for type-aware rules
- Fix prefer-optional-chain violations newly caught by oxlint

* fix: revert unnecessary code changes, suppress with oxlint-disable instead

* fix: suppress remaining prefer-optional-chain violations

* fix: suppress last prefer-optional-chain violation

* fix: remove redundant --type-aware CLI flag, use config instead
2026-03-09 12:51:12 +00:00

102 lines
3.1 KiB
TypeScript

import { regEx } from '../../../util/regex.ts';
import { coerceString } from '../../../util/string.ts';
import type { GenericVersion } from '../generic.ts';
import { GenericVersioningApi } from '../generic.ts';
import type { VersioningApi } from '../types.ts';
export const id = 'docker';
export const displayName = 'Docker';
export const urls = [
'https://docs.docker.com/engine/reference/commandline/tag/',
];
export const supportsRanges = false;
const versionPattern = regEx(/^(?<version>\d+(?:\.\d+)*)(?<prerelease>\w*)$/);
const commitHashPattern = regEx(/^[a-f0-9]{7,40}$/);
const numericPattern = regEx(/^[0-9]+$/);
class DockerVersioningApi extends GenericVersioningApi {
protected _parse(version: string): GenericVersion | null {
if (!version) {
return null;
}
if (commitHashPattern.test(version) && !numericPattern.test(version)) {
return null;
}
const versionPieces = version.replace(regEx(/^v/), '').split('-');
const [prefix, ...suffixPieces] = versionPieces;
const matchGroups = prefix?.match(versionPattern)?.groups;
if (!matchGroups) {
return null;
}
const { version: ver, prerelease } = matchGroups;
const release = ver.split('.').map(Number);
return { release, suffix: suffixPieces.join('-'), prerelease };
}
protected override _compare(version: string, other: string): number {
const parsed1 = this._parse(version);
const parsed2 = this._parse(other);
// istanbul ignore if
if (!(parsed1 && parsed2)) {
return 1;
}
const length = Math.max(parsed1.release.length, parsed2.release.length);
for (let i = 0; i < length; i += 1) {
const part1 = parsed1.release[i];
const part2 = parsed2.release[i];
// shorter is bigger 2.1 > 2.1.1
if (part1 === undefined) {
return 1;
}
if (part2 === undefined) {
return -1;
}
if (part1 !== part2) {
return part1 - part2;
}
}
if (parsed1.prerelease !== parsed2.prerelease) {
// unstable is lower
if (!parsed1.prerelease && parsed2.prerelease) {
return 1;
}
if (parsed1.prerelease && !parsed2.prerelease) {
return -1;
}
// alphabetic order
if (parsed1.prerelease && parsed2.prerelease) {
return parsed1.prerelease.localeCompare(parsed2.prerelease);
}
}
// equals
const suffix1 = coerceString(parsed1.suffix);
const suffix2 = coerceString(parsed2.suffix);
return suffix2.localeCompare(suffix1);
}
override isCompatible(version: string, current: string): boolean {
const parsed1 = this._parse(version);
const parsed2 = this._parse(current);
/* oxlint-disable typescript/prefer-optional-chain */
return !!(
parsed1 &&
parsed2 &&
parsed1.suffix === parsed2.suffix &&
parsed1.release.length === parsed2.release.length
);
/* oxlint-enable typescript/prefer-optional-chain */
}
valueToVersion(value: string): string {
// Remove any suffix after '-', e.g. '-alpine'
return value ? value.split('-')[0] : value;
}
}
export const api: VersioningApi = new DockerVersioningApi();
export default api;