From 640124aaf7c7fe89b7f2e98d3d6b3d9299eaaa15 Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Wed, 3 Dec 2025 10:50:05 -0500 Subject: [PATCH] test: migrate tar extraction to `tar-stream` for E2E setup This commit replaces the `tar` package with `tar-stream` for file extraction in the e2e test utilities. The primary advantage of this change is a significant reduction in dependency size. The `tar` package is approximately 2MB on disk, whereas `tar-stream` is only ~235KB. This improves installation speed and reduces the overall disk footprint of the project. The implementation in `extractFile` has been updated to use the `tar-stream` event-based API and now includes `zlib.createGunzip()` to correctly handle compressed tarballs. --- package.json | 1 - pnpm-lock.yaml | 16 +++++++++-- tests/legacy-cli/e2e/utils/BUILD.bazel | 3 +- tests/legacy-cli/e2e/utils/tar.ts | 40 +++++++++++++++----------- tests/package.json | 2 ++ 5 files changed, 41 insertions(+), 21 deletions(-) diff --git a/package.json b/package.json index 2aed1d6aca99..ad9b83b0e87c 100644 --- a/package.json +++ b/package.json @@ -132,7 +132,6 @@ "rollup-plugin-sourcemaps2": "0.5.4", "semver": "7.7.3", "source-map-support": "0.5.21", - "tar": "^7.0.0", "ts-node": "^10.9.1", "tslib": "2.8.1", "typescript": "5.9.3", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c58286a7c7c3..fba93a20d9ca 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -280,9 +280,6 @@ importers: source-map-support: specifier: 0.5.21 version: 0.5.21 - tar: - specifier: ^7.0.0 - version: 7.5.2 ts-node: specifier: ^10.9.1 version: 10.9.2(@types/node@22.19.1)(typescript@5.9.3) @@ -897,9 +894,15 @@ importers: '@angular-devkit/schematics': specifier: workspace:* version: link:../packages/angular_devkit/schematics + '@types/tar-stream': + specifier: 3.1.4 + version: 3.1.4 rxjs: specifier: 7.8.2 version: 7.8.2 + tar-stream: + specifier: 3.1.7 + version: 3.1.7 tree-kill: specifier: 1.2.2 version: 1.2.2 @@ -3824,6 +3827,9 @@ packages: '@types/stack-trace@0.0.33': resolution: {integrity: sha512-O7in6531Bbvlb2KEsJ0dq0CHZvc3iWSR5ZYMtvGgnHA56VgriAN/AU2LorfmcvAl2xc9N5fbCTRyMRRl8nd74g==} + '@types/tar-stream@3.1.4': + resolution: {integrity: sha512-921gW0+g29mCJX0fRvqeHzBlE/XclDaAG0Ousy1LCghsOhvaKacDeRGEVzQP9IPfKn8Vysy7FEXAIxycpc/CMg==} + '@types/watchpack@2.4.5': resolution: {integrity: sha512-8CarnGOIYYRL342jwQyHrGwz4vCD3y5uwwYmzQVzT2Z24DqSd6wwBva6m0eNJX4S5pVmrx9xUEbOsOoqBVhWsg==} @@ -12477,6 +12483,10 @@ snapshots: '@types/stack-trace@0.0.33': {} + '@types/tar-stream@3.1.4': + dependencies: + '@types/node': 22.19.1 + '@types/watchpack@2.4.5': dependencies: '@types/graceful-fs': 4.1.9 diff --git a/tests/legacy-cli/e2e/utils/BUILD.bazel b/tests/legacy-cli/e2e/utils/BUILD.bazel index 77bd09288582..a565262640c4 100644 --- a/tests/legacy-cli/e2e/utils/BUILD.bazel +++ b/tests/legacy-cli/e2e/utils/BUILD.bazel @@ -16,10 +16,11 @@ ts_project( "//:node_modules/fast-glob", "//:node_modules/protractor", "//:node_modules/semver", - "//:node_modules/tar", "//:node_modules/verdaccio", "//:node_modules/verdaccio-auth-memory", + "//tests:node_modules/@types/tar-stream", "//tests:node_modules/rxjs", + "//tests:node_modules/tar-stream", "//tests:node_modules/tree-kill", ], ) diff --git a/tests/legacy-cli/e2e/utils/tar.ts b/tests/legacy-cli/e2e/utils/tar.ts index 77239c74eb0f..d78f47762337 100644 --- a/tests/legacy-cli/e2e/utils/tar.ts +++ b/tests/legacy-cli/e2e/utils/tar.ts @@ -8,7 +8,8 @@ import { createReadStream } from 'node:fs'; import { normalize } from 'node:path'; -import { Parser } from 'tar'; +import { createGunzip } from 'node:zlib'; +import { extract } from 'tar-stream'; /** * Extract and return the contents of a single file out of a tar file. @@ -21,20 +22,27 @@ export function extractFile(tarball: string, filePath: string): Promise const normalizedFilePath = normalize(filePath); return new Promise((resolve, reject) => { - createReadStream(tarball) - .pipe( - new Parser({ - strict: true, - filter: (p) => normalize(p) === normalizedFilePath, - onReadEntry: (entry) => { - const chunks: Buffer[] = []; - - entry.on('data', (chunk) => chunks.push(chunk)); - entry.on('error', reject); - entry.on('finish', () => resolve(Buffer.concat(chunks))); - }, - }), - ) - .on('close', () => reject(`${tarball} does not contain ${filePath}`)); + const extractor = extract(); + + extractor.on('entry', (header, stream, next) => { + if (normalize(header.name) !== normalizedFilePath) { + stream.resume(); + next(); + + return; + } + + const chunks: Buffer[] = []; + stream.on('data', (chunk) => chunks.push(chunk)); + stream.on('error', reject); + stream.on('end', () => { + resolve(Buffer.concat(chunks)); + next(); + }); + }); + + extractor.on('finish', () => reject(new Error(`'${filePath}' not found in '${tarball}'.`))); + + createReadStream(tarball).pipe(createGunzip()).pipe(extractor).on('error', reject); }); } diff --git a/tests/package.json b/tests/package.json index 4aec9553824b..9a87c1c637b8 100644 --- a/tests/package.json +++ b/tests/package.json @@ -1,7 +1,9 @@ { "devDependencies": { + "@types/tar-stream": "3.1.4", "@angular-devkit/schematics": "workspace:*", "rxjs": "7.8.2", + "tar-stream": "3.1.7", "tree-kill": "1.2.2" } }