feat(docker): add Docker test file support and runtime adapter

This commit is contained in:
2025-10-26 19:35:10 +00:00
parent 1ea3b37d18
commit 592a4f33c0
5 changed files with 392 additions and 8 deletions

View File

@@ -29,7 +29,7 @@ export interface ParserConfig {
const KNOWN_RUNTIMES: Set<string> = new Set(['node', 'chromium', 'deno', 'bun']);
const KNOWN_MODIFIERS: Set<string> = new Set(['nonci']);
const VALID_EXTENSIONS: Set<string> = new Set(['ts', 'tsx', 'mts', 'cts']);
const VALID_EXTENSIONS: Set<string> = new Set(['ts', 'tsx', 'mts', 'cts', 'sh']);
const ALL_RUNTIMES: Runtime[] = ['node', 'chromium', 'deno', 'bun'];
// Legacy mappings for backwards compatibility
@@ -228,3 +228,81 @@ export function getLegacyMigrationTarget(fileName: string): string | null {
return parts.join('.');
}
/**
* Docker test file information
*/
export interface DockerTestFileInfo {
baseName: string;
variant: string;
isDockerTest: true;
original: string;
}
/**
* Check if a filename matches the Docker test pattern: *.{variant}.docker.sh
* Examples: test.latest.docker.sh, test.integration.npmci.docker.sh
*/
export function isDockerTestFile(fileName: string): boolean {
// Must end with .docker.sh
if (!fileName.endsWith('.docker.sh')) {
return false;
}
// Extract filename from path if needed
const name = fileName.split('/').pop() || fileName;
// Must have at least 3 parts: [baseName, variant, docker, sh]
const parts = name.split('.');
return parts.length >= 4 && parts[parts.length - 2] === 'docker' && parts[parts.length - 1] === 'sh';
}
/**
* Parse a Docker test filename to extract variant and base name
* Pattern: test.{baseName}.{variant}.docker.sh
* Examples:
* - test.latest.docker.sh -> { baseName: 'test', variant: 'latest' }
* - test.integration.npmci.docker.sh -> { baseName: 'test.integration', variant: 'npmci' }
*/
export function parseDockerTestFilename(filePath: string): DockerTestFileInfo {
// Extract just the filename from the path
const fileName = filePath.split('/').pop() || filePath;
const original = fileName;
if (!isDockerTestFile(fileName)) {
throw new Error(`Not a valid Docker test file: "${fileName}". Expected pattern: *.{variant}.docker.sh`);
}
// Remove .docker.sh suffix
const withoutSuffix = fileName.slice(0, -10); // Remove '.docker.sh'
const tokens = withoutSuffix.split('.');
if (tokens.length === 0) {
throw new Error(`Invalid Docker test file: empty basename in "${fileName}"`);
}
// Last token before .docker.sh is the variant
const variant = tokens[tokens.length - 1];
// Everything else is the base name
const baseName = tokens.slice(0, -1).join('.');
return {
baseName: baseName || 'test',
variant,
isDockerTest: true,
original,
};
}
/**
* Map a Docker variant to its corresponding Dockerfile path
* "latest" -> "Dockerfile"
* Other variants -> "Dockerfile_{variant}"
*/
export function mapVariantToDockerfile(variant: string, baseDir: string): string {
if (variant === 'latest') {
return `${baseDir}/Dockerfile`;
}
return `${baseDir}/Dockerfile_${variant}`;
}