Skip to content

Commit

Permalink
test: support parallel tsurge unit combining in batch test infra (ang…
Browse files Browse the repository at this point in the history
…ular#58280)

This allows the batch test for the signal input migration to pass.

PR Close angular#58280
  • Loading branch information
devversion authored and AndrewKushnir committed Oct 22, 2024
1 parent 8735543 commit cb34e40
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@
import fs from 'fs';
import path from 'path';
import {executeAnalyzePhase} from '../../../../utils/tsurge/executors/analyze_exec';
import {executeCombinePhase} from '../../../../utils/tsurge/executors/combine_exec';
import {executeMigratePhase} from '../../../../utils/tsurge/executors/migrate_exec';
import {SignalInputMigration} from '../migration';
import {writeMigrationReplacements} from '../write_replacements';
import {CompilationUnitData} from './unit_data';
import {executeGlobalMetaPhase} from '../../../../utils/tsurge/executors/global_meta_exec';
import {synchronouslyCombineUnitData} from '../../../../utils/tsurge/helpers/combine_units';

main().catch((e) => {
console.error(e);
Expand All @@ -28,16 +28,16 @@ async function main() {
if (mode === 'extract') {
const analyzeResult = await executeAnalyzePhase(migration, path.resolve(args[0]));
process.stdout.write(JSON.stringify(analyzeResult));
} else if (mode === 'combine') {
const unitAPromise = readUnitMeta(path.resolve(args[0]));
const unitBPromise = readUnitMeta(path.resolve(args[1]));

const [unitA, unitB] = await Promise.all([unitAPromise, unitBPromise]);
const mergedResult = await executeCombinePhase(migration, unitA, unitB);
} else if (mode === 'combine-all') {
const unitPromises = args.map((f) => readUnitMeta(path.resolve(f)));
const units = await Promise.all(unitPromises);
const mergedResult = await synchronouslyCombineUnitData(migration, units);

process.stdout.write(JSON.stringify(mergedResult));
} else if (mode === 'globalMeta') {
await executeGlobalMetaPhase(migration, await readUnitMeta(args[0]));
} else if (mode === 'global-meta') {
const metaResult = await executeGlobalMetaPhase(migration, await readUnitMeta(args[0]));

process.stdout.write(JSON.stringify(metaResult));
} else if (mode === 'migrate') {
const {replacements, projectRoot} = await executeMigratePhase(
migration,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,8 @@ integration_test(
],
commands = [
"$(rootpath :batch_runner) analyze ./golden-test",
"$(rootpath :batch_runner) merge ./golden-test",
"$(rootpath :batch_runner) combine-all ./golden-test",
"$(rootpath :batch_runner) global-meta ./golden-test",
"$(rootpath :batch_runner) migrate ./golden-test",
"$(rootpath :golden_test_runner) ./golden-test ./golden.txt",
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,18 +53,24 @@ async function main() {
// write individual result.
await fs.promises.writeFile(extractResultFile, extractResult);
});
} else if (mode === 'merge') {
} else if (mode === 'combine-all') {
const metadataFiles = files.map((f) => path.resolve(path.join(sourceDir, `${f}.extract.json`)));
const mergeResult = await promiseExec(`migration merge ${metadataFiles.join(' ')}`);
const mergeResult = await promiseExec(`migration combine-all ${metadataFiles.join(' ')}`);

// write merge result.
await fs.promises.writeFile(path.join(sourceDir, 'merged.json'), mergeResult);
await fs.promises.writeFile(path.join(sourceDir, 'combined.json'), mergeResult);
} else if (mode === 'global-meta') {
const combinedUnitFile = path.join(sourceDir, 'combined.json');
const globalMeta = await promiseExec(`migration global-meta ${combinedUnitFile}`);

// write global meta result.
await fs.promises.writeFile(path.join(sourceDir, 'global_meta.json'), globalMeta);
} else if (mode === 'migrate') {
schedule(files, maxParallel, async (fileName) => {
const filePath = path.join(sourceDir, fileName);
// tsconfig should exist from analyze phase.
const tmpTsconfigName = path.join(sourceDir, `${fileName}.tsconfig.json`);
const mergeMetadataFile = path.join(sourceDir, 'merged.json');
const mergeMetadataFile = path.join(sourceDir, 'global_meta.json');

// migrate in parallel.
await promiseExec(
Expand Down
37 changes: 37 additions & 0 deletions packages/core/schematics/utils/tsurge/helpers/combine_units.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/

import {TsurgeMigration} from '../migration';

/**
* Synchronously combines unit data for the given migration.
*
* Note: This helper is useful for testing and execution of
* Tsurge migrations in non-batchable environments. In general,
* prefer parallel execution of combining via e.g. Beam combiners.
*/
export async function synchronouslyCombineUnitData<UnitData>(
migration: TsurgeMigration<UnitData, unknown>,
unitDatas: UnitData[],
): Promise<UnitData | null> {
if (unitDatas.length === 0) {
return null;
}
if (unitDatas.length === 1) {
return unitDatas[0];
}

let combined = unitDatas[0];

for (let i = 1; i < unitDatas.length; i++) {
const other = unitDatas[i];
combined = await migration.combine(combined, other);
}

return combined;
}

0 comments on commit cb34e40

Please sign in to comment.