refactor(requirements): collapse single-use evaluation helpers (#129753)

This commit is contained in:
Peter Steinberger
2026-08-25 21:43:23 -07:00
committed by GitHub
parent bc792e5f30
commit 857f470c84
+49 -181
View File
@@ -31,135 +31,62 @@ type RequirementsEvaluationContext = {
isConfigSatisfied: (pathStr: string) => boolean;
};
type RequirementsEvaluationRemoteContext = {
hasRemoteBin?: (bin: string) => boolean;
hasRemoteAnyBin?: (bins: string[]) => boolean;
remotePlatforms?: string[];
};
/** Returns required binaries absent from both the local host and optional remote target. */
function resolveMissingBins(params: {
required: string[];
hasLocalBin: (bin: string) => boolean;
hasRemoteBin?: (bin: string) => boolean;
}): string[] {
const remote = params.hasRemoteBin;
return params.required.filter((bin) => {
if (params.hasLocalBin(bin)) {
return false;
}
if (remote?.(bin)) {
return false;
}
return true;
});
}
/** Treats an any-bin requirement as satisfied when any listed binary exists locally or remotely. */
function resolveMissingAnyBins(params: {
required: string[];
hasLocalBin: (bin: string) => boolean;
hasRemoteAnyBin?: (bins: string[]) => boolean;
}): string[] {
if (params.required.length === 0) {
return [];
}
if (params.required.some((bin) => params.hasLocalBin(bin))) {
return [];
}
if (params.hasRemoteAnyBin?.(params.required)) {
return [];
}
return params.required;
}
/** Resolves OS requirements against local and remote platforms, accepting macos as darwin. */
function resolveMissingOs(params: {
required: string[];
localPlatform: string;
remotePlatforms?: string[];
}): string[] {
if (params.required.length === 0) {
return [];
}
const localPlatform = normalizeOsRequirementPlatform(params.localPlatform);
const requiredPlatforms = new Set(
params.required.map((platform) => normalizeOsRequirementPlatform(platform)),
);
if (requiredPlatforms.has(localPlatform)) {
return [];
}
if (
params.remotePlatforms?.some((platform) =>
requiredPlatforms.has(normalizeOsRequirementPlatform(platform)),
)
) {
return [];
}
return params.required;
}
function normalizeOsRequirementPlatform(platform: string): string {
const normalized = platform.trim().toLowerCase();
return normalized === "macos" ? "darwin" : normalized;
}
/** Returns environment variable names whose caller-provided satisfaction check fails. */
function resolveMissingEnv(params: {
required: string[];
isSatisfied: (envName: string) => boolean;
}): string[] {
const missing: string[] = [];
for (const envName of params.required) {
if (params.isSatisfied(envName)) {
continue;
/** Evaluates entry requirements against the current host and optional remote capabilities. */
export function evaluateRequirementsFromMetadataWithRemote(
params: RequirementsEvaluationContext & {
metadata?: RequirementsMetadata;
remote?: RequirementRemote;
},
): {
required: Requirements;
missing: Requirements;
eligible: boolean;
configChecks: RequirementConfigCheck[];
} {
const required: Requirements = {
bins: params.metadata?.requires?.bins ?? [],
anyBins: params.metadata?.requires?.anyBins ?? [],
env: params.metadata?.requires?.env ?? [],
config: params.metadata?.requires?.config ?? [],
os: params.metadata?.os ?? [],
};
const hasRemoteBin = params.remote?.hasBin;
const hasRemoteAnyBin = params.remote?.hasAnyBin;
const missingBins = required.bins.filter(
(bin) => !params.hasLocalBin(bin) && !hasRemoteBin?.(bin),
);
const missingAnyBins =
required.anyBins.length === 0 ||
required.anyBins.some((bin) => params.hasLocalBin(bin)) ||
hasRemoteAnyBin?.(required.anyBins)
? []
: required.anyBins;
let missingOs: string[] = [];
if (required.os.length > 0) {
const localPlatform = normalizeOsRequirementPlatform(params.localPlatform);
const requiredPlatforms = new Set(required.os.map(normalizeOsRequirementPlatform));
if (
!requiredPlatforms.has(localPlatform) &&
!params.remote?.platforms?.some((platform) =>
requiredPlatforms.has(normalizeOsRequirementPlatform(platform)),
)
) {
missingOs = required.os;
}
missing.push(envName);
}
return missing;
}
/** Builds per-config-path status while preserving every declared path for UI diagnostics. */
function buildConfigChecks(params: {
required: string[];
isSatisfied: (pathStr: string) => boolean;
}): RequirementConfigCheck[] {
return params.required.map((pathStr) => {
const satisfied = params.isSatisfied(pathStr);
return { path: pathStr, satisfied };
});
}
/** Evaluates normalized requirements and returns missing categories plus config diagnostics. */
function evaluateRequirements(
params: RequirementsEvaluationContext &
RequirementsEvaluationRemoteContext & {
required: Requirements;
},
): { missing: Requirements; eligible: boolean; configChecks: RequirementConfigCheck[] } {
const missingBins = resolveMissingBins({
required: params.required.bins,
hasLocalBin: params.hasLocalBin,
hasRemoteBin: params.hasRemoteBin,
});
const missingAnyBins = resolveMissingAnyBins({
required: params.required.anyBins,
hasLocalBin: params.hasLocalBin,
hasRemoteAnyBin: params.hasRemoteAnyBin,
});
const missingOs = resolveMissingOs({
required: params.required.os,
localPlatform: params.localPlatform,
remotePlatforms: params.remotePlatforms,
});
const missingEnv = resolveMissingEnv({
required: params.required.env,
isSatisfied: params.isEnvSatisfied,
});
const configChecks = buildConfigChecks({
required: params.required.config,
isSatisfied: params.isConfigSatisfied,
});
const missingEnv = required.env.filter((envName) => !params.isEnvSatisfied(envName));
const configChecks = required.config.map((path) => ({
path,
satisfied: params.isConfigSatisfied(path),
}));
const missingConfig = configChecks.filter((check) => !check.satisfied).map((check) => check.path);
// `always` bypasses runtime requirements, but OS remains a hard compatibility boundary.
@@ -179,64 +106,5 @@ function evaluateRequirements(
missing.env.length === 0 &&
missing.config.length === 0));
return { missing, eligible, configChecks };
}
/** Converts entry metadata into the canonical requirement shape before evaluation. */
function evaluateRequirementsFromMetadata(
params: RequirementsEvaluationContext &
RequirementsEvaluationRemoteContext & {
metadata?: RequirementsMetadata;
},
): {
required: Requirements;
missing: Requirements;
eligible: boolean;
configChecks: RequirementConfigCheck[];
} {
const required: Requirements = {
bins: params.metadata?.requires?.bins ?? [],
anyBins: params.metadata?.requires?.anyBins ?? [],
env: params.metadata?.requires?.env ?? [],
config: params.metadata?.requires?.config ?? [],
os: params.metadata?.os ?? [],
};
const result = evaluateRequirements({
always: params.always,
required,
hasLocalBin: params.hasLocalBin,
hasRemoteBin: params.hasRemoteBin,
hasRemoteAnyBin: params.hasRemoteAnyBin,
localPlatform: params.localPlatform,
remotePlatforms: params.remotePlatforms,
isEnvSatisfied: params.isEnvSatisfied,
isConfigSatisfied: params.isConfigSatisfied,
});
return { required, ...result };
}
/** Convenience wrapper for callers that receive remote capability checks as one object. */
export function evaluateRequirementsFromMetadataWithRemote(
params: RequirementsEvaluationContext & {
metadata?: RequirementsMetadata;
remote?: RequirementRemote;
},
): {
required: Requirements;
missing: Requirements;
eligible: boolean;
configChecks: RequirementConfigCheck[];
} {
return evaluateRequirementsFromMetadata({
always: params.always,
metadata: params.metadata,
hasLocalBin: params.hasLocalBin,
hasRemoteBin: params.remote?.hasBin,
hasRemoteAnyBin: params.remote?.hasAnyBin,
localPlatform: params.localPlatform,
remotePlatforms: params.remote?.platforms,
isEnvSatisfied: params.isEnvSatisfied,
isConfigSatisfied: params.isConfigSatisfied,
});
return { required, missing, eligible, configChecks };
}