Rearranged the code and added CLI that installs tools locally.
All checks were successful
Test Action / test (push) Successful in 3s

This commit is contained in:
2026-01-11 10:54:25 +01:00
parent ef971a6da4
commit 620da93338
12 changed files with 559 additions and 188 deletions

67
src/core/matcher.ts Normal file
View File

@@ -0,0 +1,67 @@
import { PlatformInfo } from './platform';
export interface MatchOptions {
fileName?: string;
fileType?: string;
}
export function getMatchingAsset(assets: any[], platform: PlatformInfo, options: MatchOptions): any {
const { fileName, fileType = 'archive' } = options;
let extPattern: string;
if (fileType === 'archive') {
extPattern = '\\.(zip|tar\\.gz|tar|tgz|7z)';
} else if (fileType === 'package') {
extPattern = '\\.(deb|rpm|pkg)';
} else {
extPattern = fileType;
}
if (!fileName) {
// Rule 1: Default matching rule
const pattern = `${platform.systemPattern}[_-]${platform.archPattern}.*${extPattern}$`;
const regex = new RegExp(pattern, 'i');
const matchingAssets = assets.filter((a: any) => regex.test(a.name));
if (matchingAssets.length === 0) {
throw new Error(`No assets matched the default criteria: ${pattern}`);
}
if (matchingAssets.length > 1) {
throw new Error(`Multiple assets matched the default criteria: ${matchingAssets.map((a: any) => a.name).join(', ')}`);
}
return matchingAssets[0];
} else if (fileName.startsWith('~')) {
// Rule 3: Regex matching rule
let pattern = fileName.substring(1);
const hasSystem = pattern.includes('{{SYSTEM}}');
const hasArch = pattern.includes('{{ARCH}}');
const hasExt = pattern.includes('{{EXT_PATTERN}}');
const hasEnd = pattern.endsWith('$');
if (!hasSystem && !hasArch && !hasExt && !hasEnd) {
pattern += `.*{{SYSTEM}}[_-]{{ARCH}}.*{{EXT_PATTERN}}$`;
} else if (hasSystem && hasArch && !hasExt && !hasEnd) {
pattern += `.*{{EXT_PATTERN}}$`;
}
const finalPattern = pattern
.replace(/{{SYSTEM}}/g, platform.systemPattern)
.replace(/{{ARCH}}/g, platform.archPattern)
.replace(/{{EXT_PATTERN}}/g, extPattern);
const regex = new RegExp(finalPattern, 'i');
const matchingAssets = assets.filter((a: any) => regex.test(a.name));
if (matchingAssets.length === 0) {
throw new Error(`No assets matched the regex: ${finalPattern}`);
}
if (matchingAssets.length > 1) {
throw new Error(`Multiple assets matched the criteria: ${matchingAssets.map((a: any) => a.name).join(', ')}`);
}
return matchingAssets[0];
} else {
// Rule 2: Literal matching rule
const asset = assets.find((a: any) => a.name === fileName);
if (!asset) {
throw new Error(`No asset found matching the exact name: ${fileName}`);
}
return asset;
}
}