mirror of
https://github.com/astral-sh/ruff-action.git
synced 2026-08-10 19:27:03 +00:00
163 lines
4.4 KiB
TypeScript
163 lines
4.4 KiB
TypeScript
import * as core from "@actions/core";
|
|
import { findPyprojectToml } from "../utils/pyproject-finder";
|
|
import { getParsedVersionFile } from "./file-parser";
|
|
import { normalizeVersionSpecifier } from "./specifier";
|
|
import type {
|
|
ParsedVersionFile,
|
|
ResolveRuffVersionOptions,
|
|
VersionRequest,
|
|
} from "./types";
|
|
|
|
export interface VersionRequestResolver {
|
|
resolve(context: VersionRequestContext): VersionRequest | undefined;
|
|
}
|
|
|
|
export class VersionRequestContext {
|
|
readonly sourceDirectory: string;
|
|
readonly version: string | undefined;
|
|
readonly versionFile: string | undefined;
|
|
readonly workspaceRoot: string;
|
|
|
|
private readonly parsedFiles = new Map<
|
|
string,
|
|
ParsedVersionFile | undefined
|
|
>();
|
|
|
|
constructor(
|
|
version: string | undefined,
|
|
versionFile: string | undefined,
|
|
sourceDirectory: string,
|
|
workspaceRoot: string,
|
|
) {
|
|
this.version = version;
|
|
this.versionFile = versionFile;
|
|
this.sourceDirectory = sourceDirectory;
|
|
this.workspaceRoot = workspaceRoot;
|
|
}
|
|
|
|
getVersionFile(filePath: string): ParsedVersionFile | undefined {
|
|
const cachedResult = this.parsedFiles.get(filePath);
|
|
if (cachedResult !== undefined || this.parsedFiles.has(filePath)) {
|
|
return cachedResult;
|
|
}
|
|
|
|
const result = getParsedVersionFile(filePath);
|
|
this.parsedFiles.set(filePath, result);
|
|
return result;
|
|
}
|
|
|
|
getWorkspacePyprojectPath(): string | undefined {
|
|
return findPyprojectToml(this.sourceDirectory, this.workspaceRoot);
|
|
}
|
|
}
|
|
|
|
export class ExplicitInputVersionResolver implements VersionRequestResolver {
|
|
resolve(context: VersionRequestContext): VersionRequest | undefined {
|
|
if (context.version === undefined) {
|
|
return undefined;
|
|
}
|
|
|
|
return {
|
|
source: "input",
|
|
specifier: normalizeVersionSpecifier(context.version),
|
|
};
|
|
}
|
|
}
|
|
|
|
export class VersionFileVersionResolver implements VersionRequestResolver {
|
|
resolve(context: VersionRequestContext): VersionRequest | undefined {
|
|
if (context.versionFile === undefined) {
|
|
return undefined;
|
|
}
|
|
|
|
const versionFile = context.getVersionFile(context.versionFile);
|
|
if (versionFile === undefined) {
|
|
core.warning(
|
|
`Could not parse version from ${context.versionFile}. Using latest version.`,
|
|
);
|
|
return undefined;
|
|
}
|
|
|
|
return {
|
|
format: versionFile.format,
|
|
source: "version-file",
|
|
sourcePath: context.versionFile,
|
|
specifier: versionFile.specifier,
|
|
};
|
|
}
|
|
}
|
|
|
|
export class WorkspaceVersionResolver implements VersionRequestResolver {
|
|
resolve(context: VersionRequestContext): VersionRequest | undefined {
|
|
const pyprojectPath = context.getWorkspacePyprojectPath();
|
|
if (!pyprojectPath) {
|
|
core.info("Could not find pyproject.toml. Using latest version.");
|
|
return undefined;
|
|
}
|
|
|
|
const versionFile = context.getVersionFile(pyprojectPath);
|
|
if (versionFile === undefined) {
|
|
core.info(
|
|
`Could not parse version from ${pyprojectPath}. Using latest version.`,
|
|
);
|
|
return undefined;
|
|
}
|
|
|
|
return {
|
|
format: versionFile.format,
|
|
source: "pyproject.toml",
|
|
sourcePath: pyprojectPath,
|
|
specifier: versionFile.specifier,
|
|
};
|
|
}
|
|
}
|
|
|
|
export class LatestVersionResolver implements VersionRequestResolver {
|
|
resolve(): VersionRequest {
|
|
return {
|
|
source: "default",
|
|
specifier: "latest",
|
|
};
|
|
}
|
|
}
|
|
|
|
const VERSION_REQUEST_RESOLVERS: VersionRequestResolver[] = [
|
|
new ExplicitInputVersionResolver(),
|
|
new VersionFileVersionResolver(),
|
|
new WorkspaceVersionResolver(),
|
|
new LatestVersionResolver(),
|
|
];
|
|
|
|
export function resolveVersionRequest(
|
|
options: ResolveRuffVersionOptions,
|
|
): VersionRequest {
|
|
const version = emptyToUndefined(options.version);
|
|
const versionFile = emptyToUndefined(options.versionFile);
|
|
|
|
if (version !== undefined && versionFile !== undefined) {
|
|
throw new Error(
|
|
"It is not allowed to specify both version and version-file",
|
|
);
|
|
}
|
|
|
|
const context = new VersionRequestContext(
|
|
version,
|
|
versionFile,
|
|
options.sourceDirectory,
|
|
options.workspaceRoot,
|
|
);
|
|
|
|
for (const resolver of VERSION_REQUEST_RESOLVERS) {
|
|
const request = resolver.resolve(context);
|
|
if (request !== undefined) {
|
|
return request;
|
|
}
|
|
}
|
|
|
|
throw new Error("Could not resolve a requested Ruff version.");
|
|
}
|
|
|
|
function emptyToUndefined(value: string | undefined): string | undefined {
|
|
return value === undefined || value === "" ? undefined : value;
|
|
}
|