From 211f6df8145e8b26acc20ed5ac8e0fbc06eb3bec Mon Sep 17 00:00:00 2001 From: Elizabeth Craig Date: Fri, 20 Mar 2026 12:53:16 -0700 Subject: [PATCH] Fix promise handling issues --- ...-7bd977ba-d97f-46df-be41-7378c5995273.json | 74 ++++++++++++ packages/backfill-cache/src/CacheStorage.ts | 3 +- .../src/__tests__/LocalCacheStorage.test.ts | 6 +- .../src/__tests__/cacheStorage.test.ts | 2 + .../src/__tests__/createConfig.test.ts | 16 +-- packages/backfill-hasher/src/Hasher.ts | 2 +- .../src/__tests__/Hasher.test.ts | 23 ++-- .../src/__tests__/getFileHashes.ts | 18 +-- .../src/__tests__/hashOfFiles.test.ts | 22 ++-- packages/backfill-hasher/src/hashOfFiles.ts | 4 +- packages/backfill-hasher/src/hashOfPackage.ts | 6 +- packages/backfill/src/__tests__/api.test.ts | 4 +- packages/backfill/src/__tests__/audit.test.ts | 4 +- .../backfill/src/__tests__/backfill.test.ts | 6 +- packages/backfill/src/__tests__/cli.test.ts | 2 +- packages/backfill/src/__tests__/e2e.test.ts | 4 +- .../cache/src/__tests__/chunkPromise.test.ts | 2 +- .../src/__tests__/initializeReporters.test.ts | 2 +- .../src/__tests__/simulateFileAccess.test.ts | 24 ++-- .../cli/src/commands/exec/executeRemotely.ts | 2 +- .../src/commands/exec/simulateFileAccess.ts | 2 +- .../src/commands/launchServerInBackground.ts | 2 +- .../cli/src/commands/run/createTargetGraph.ts | 4 +- packages/cli/src/commands/run/watchAction.ts | 10 +- packages/cli/src/commands/server/action.ts | 2 +- .../cli/src/commands/server/lageService.ts | 9 +- .../src/commands/server/singleTargetWorker.ts | 43 ++++--- packages/config/src/readConfigFile.ts | 2 +- packages/e2e-tests/src/basic.test.ts | 8 +- packages/e2e-tests/src/basicFailure.test.ts | 4 +- packages/e2e-tests/src/bigapp.test.ts | 2 +- packages/e2e-tests/src/cacheClear.test.ts | 2 +- packages/e2e-tests/src/customReporter.test.ts | 8 +- packages/e2e-tests/src/info.test.ts | 14 +-- packages/e2e-tests/src/lageserver.test.ts | 6 +- packages/e2e-tests/src/mock/monorepo.ts | 4 +- packages/e2e-tests/src/remoteFallback.test.ts | 8 +- .../e2e-tests/src/transitiveTaskDeps.test.ts | 10 +- packages/hasher/src/TargetHasher.ts | 2 +- .../hasher/src/__tests__/TargetHasher.test.ts | 2 +- packages/rpc/src/createServer.ts | 3 +- packages/runners/src/NoOpRunner.ts | 1 + packages/runners/src/NpmScriptRunner.ts | 1 + packages/scheduler/src/SimpleScheduler.ts | 2 +- packages/scheduler/src/WrappedTarget.ts | 11 +- .../SimpleScheduler.watchmode.test.ts | 2 + .../src/__tests__/WrappedTarget.test.ts | 43 +++---- .../src/cache/createCacheProvider.ts | 4 +- .../scheduler/src/workers/targetWorker.ts | 106 +++++++++--------- .../src/WorkspaceTargetGraphBuilder.ts | 2 +- .../WorkspaceTargetGraphBuilder.test.ts | 54 ++++----- .../worker-threads-pool/src/ThreadWorker.ts | 2 +- .../worker-threads-pool/src/registerWorker.ts | 4 +- scripts/config/eslintrc.js | 5 + scripts/config/getDtsBundleConfig.js | 1 + scripts/worker/types.js | 1 + 56 files changed, 340 insertions(+), 272 deletions(-) create mode 100644 change/change-7bd977ba-d97f-46df-be41-7378c5995273.json diff --git a/change/change-7bd977ba-d97f-46df-be41-7378c5995273.json b/change/change-7bd977ba-d97f-46df-be41-7378c5995273.json new file mode 100644 index 000000000..f212e85d0 --- /dev/null +++ b/change/change-7bd977ba-d97f-46df-be41-7378c5995273.json @@ -0,0 +1,74 @@ +{ + "changes": [ + { + "type": "patch", + "comment": "Address promise lint issues", + "packageName": "backfill-cache", + "email": "elcraig@microsoft.com", + "dependentChangeType": "patch" + }, + { + "type": "patch", + "comment": "Address promise lint issues", + "packageName": "backfill-hasher", + "email": "elcraig@microsoft.com", + "dependentChangeType": "patch" + }, + { + "type": "patch", + "comment": "Address promise lint issues", + "packageName": "@lage-run/cli", + "email": "elcraig@microsoft.com", + "dependentChangeType": "patch" + }, + { + "type": "patch", + "comment": "Address promise lint issues", + "packageName": "@lage-run/config", + "email": "elcraig@microsoft.com", + "dependentChangeType": "patch" + }, + { + "type": "patch", + "comment": "Address promise lint issues", + "packageName": "@lage-run/hasher", + "email": "elcraig@microsoft.com", + "dependentChangeType": "patch" + }, + { + "type": "patch", + "comment": "Address promise lint issues", + "packageName": "@lage-run/rpc", + "email": "elcraig@microsoft.com", + "dependentChangeType": "patch" + }, + { + "type": "patch", + "comment": "Address promise lint issues", + "packageName": "@lage-run/runners", + "email": "elcraig@microsoft.com", + "dependentChangeType": "patch" + }, + { + "type": "patch", + "comment": "Address promise lint issues", + "packageName": "@lage-run/scheduler", + "email": "elcraig@microsoft.com", + "dependentChangeType": "patch" + }, + { + "type": "patch", + "comment": "Address promise lint issues", + "packageName": "@lage-run/target-graph", + "email": "elcraig@microsoft.com", + "dependentChangeType": "patch" + }, + { + "type": "patch", + "comment": "Address promise lint issues", + "packageName": "@lage-run/worker-threads-pool", + "email": "elcraig@microsoft.com", + "dependentChangeType": "patch" + } + ] +} \ No newline at end of file diff --git a/packages/backfill-cache/src/CacheStorage.ts b/packages/backfill-cache/src/CacheStorage.ts index f615bb2e7..4e1468404 100644 --- a/packages/backfill-cache/src/CacheStorage.ts +++ b/packages/backfill-cache/src/CacheStorage.ts @@ -59,8 +59,7 @@ export abstract class CacheStorage implements ICacheStorage { if (this.incrementalCaching) { // Get the list of files that have not changed so we don't need to cache them. const hashesNow = await getHashesFor(this.cwd); - const hashesThen = - (await savedHashes.get(hash)) || new Map(); + const hashesThen = savedHashes.get(hash) || new Map(); const unchangedFiles = [...hashesThen.keys()].filter( (s) => hashesThen.get(s) === hashesNow.get(s) ); diff --git a/packages/backfill-cache/src/__tests__/LocalCacheStorage.test.ts b/packages/backfill-cache/src/__tests__/LocalCacheStorage.test.ts index 917d38305..b1f25f347 100644 --- a/packages/backfill-cache/src/__tests__/LocalCacheStorage.test.ts +++ b/packages/backfill-cache/src/__tests__/LocalCacheStorage.test.ts @@ -7,7 +7,7 @@ import type { CacheStorageConfig } from "backfill-config"; import { getCacheStorageProvider } from "../getCacheStorageProvider.js"; -const setupCacheStorage = async (fixtureName: FixtureName) => { +const setupCacheStorage = (fixtureName: FixtureName) => { const fixtureLocation = setupFixture(fixtureName); const cacheStorageConfig: CacheStorageConfig = { @@ -49,7 +49,7 @@ async function fetchFromCache({ expectSuccess = true, }: CacheHelper) { const { cacheStorage, internalCacheFolder, fixtureLocation } = - await setupCacheStorage(fixtureName); + setupCacheStorage(fixtureName); const secretFile = "qwerty"; @@ -75,7 +75,7 @@ async function putInCache({ errorMessage, }: CacheHelper) { const { cacheStorage, internalCacheFolder, fixtureLocation } = - await setupCacheStorage(fixtureName); + setupCacheStorage(fixtureName); if (!outputGlob) { throw new Error("outputGlob should be provided to the putInCache function"); diff --git a/packages/backfill-cache/src/__tests__/cacheStorage.test.ts b/packages/backfill-cache/src/__tests__/cacheStorage.test.ts index 7554cd8e8..b04d60363 100644 --- a/packages/backfill-cache/src/__tests__/cacheStorage.test.ts +++ b/packages/backfill-cache/src/__tests__/cacheStorage.test.ts @@ -10,9 +10,11 @@ class MockLocalCacheStorage extends CacheStorage { super(logger, cwd, true); } + // eslint-disable-next-line @typescript-eslint/require-await -- match signature protected async _fetch(): Promise { return false; } + // eslint-disable-next-line @typescript-eslint/require-await -- match signature protected async _put(_hash: string, filesToCache: string[]): Promise { this.filesToCache = filesToCache; } diff --git a/packages/backfill-config/src/__tests__/createConfig.test.ts b/packages/backfill-config/src/__tests__/createConfig.test.ts index 5459c2edb..36a40bb2a 100644 --- a/packages/backfill-config/src/__tests__/createConfig.test.ts +++ b/packages/backfill-config/src/__tests__/createConfig.test.ts @@ -17,7 +17,7 @@ describe("getName()", () => { packageRoot = ""; }); - it("get the name of the package", async () => { + it("get the name of the package", () => { packageRoot = setupFixture("basic"); const packageName = getName(packageRoot); @@ -33,7 +33,7 @@ describe("getSearchPaths()", () => { packageRoot = ""; }); - it("finds all instances of backfill.config.js", async () => { + it("finds all instances of backfill.config.js", () => { packageRoot = setupFixture("config"); const pathPackage1 = path.join(packageRoot, "packages/package-1"); @@ -51,7 +51,7 @@ describe("getSearchPaths()", () => { ]); }); - it("returns empty list when no backfill.config.js can be found", async () => { + it("returns empty list when no backfill.config.js can be found", () => { packageRoot = setupFixture("basic"); const searchPaths = getSearchPaths(packageRoot); @@ -77,7 +77,7 @@ describe("createConfig()", () => { process.env = originalEnv; }); - it("returns default config values when no config file and no env override is provided", async () => { + it("returns default config values when no config file and no env override is provided", () => { packageRoot = setupFixture("basic"); const config = createConfig(logger, packageRoot); @@ -86,7 +86,7 @@ describe("createConfig()", () => { expect(config.internalCacheFolder).toStrictEqual(defaultLocalCacheFolder); }); - it("returns config file value when config file is provided, and no env override", async () => { + it("returns config file value when config file is provided, and no env override", () => { packageRoot = setupFixture("config"); const config = createConfig(logger, packageRoot); @@ -95,7 +95,7 @@ describe("createConfig()", () => { expect(config.logLevel).toStrictEqual("info"); }); - it("returns env override value when env override is provided", async () => { + it("returns env override value when env override is provided", () => { process.env["BACKFILL_INTERNAL_CACHE_FOLDER"] = "bar"; packageRoot = setupFixture("config"); @@ -107,7 +107,7 @@ describe("createConfig()", () => { }); // For some reason, "mode" is the only option that throws if invalid as of writing - it("throws on an invalid mode", async () => { + it("throws on an invalid mode", () => { packageRoot = setupFixture("config"); fs.writeFileSync( path.join(packageRoot, "backfill.config.js"), @@ -118,7 +118,7 @@ describe("createConfig()", () => { }); // This should be removed once more config validation is added in a major version - it("does not throw on other invalid options", async () => { + it("does not throw on other invalid options", () => { packageRoot = setupFixture("config"); fs.writeFileSync( path.join(packageRoot, "backfill.config.js"), diff --git a/packages/backfill-hasher/src/Hasher.ts b/packages/backfill-hasher/src/Hasher.ts index b8048b2df..3846cde93 100644 --- a/packages/backfill-hasher/src/Hasher.ts +++ b/packages/backfill-hasher/src/Hasher.ts @@ -83,7 +83,7 @@ export class Hasher implements IHasher { while (queue.length > 0) { const nextPackageRoot = queue.shift()!; - const packageHash = await getPackageHash( + const packageHash = getPackageHash( nextPackageRoot, repoInfo, this.logger diff --git a/packages/backfill-hasher/src/__tests__/Hasher.test.ts b/packages/backfill-hasher/src/__tests__/Hasher.test.ts index f621558e8..c9a8ad2ce 100644 --- a/packages/backfill-hasher/src/__tests__/Hasher.test.ts +++ b/packages/backfill-hasher/src/__tests__/Hasher.test.ts @@ -45,7 +45,7 @@ describe("_addToQueue", () => { }; }; - it("adds internal dependencies to the queue", async () => { + it("adds internal dependencies to the queue", () => { const { queueParams, packagePath } = initFixture(); _addToQueue(queueParams); @@ -53,7 +53,7 @@ describe("_addToQueue", () => { expect(queueParams.queue).toEqual([packagePath]); }); - it("doesn't add to the queue if the package has been evaluated", async () => { + it("doesn't add to the queue if the package has been evaluated", () => { const { queueParams, packageToAdd } = initFixture(); // Override @@ -71,7 +71,7 @@ describe("_addToQueue", () => { expect(queueParams.queue).toEqual([]); }); - it("doesn't add to the queue if the package is already in the queue", async () => { + it("doesn't add to the queue if the package is already in the queue", () => { const { queueParams, packagePath } = initFixture(); // Override @@ -93,20 +93,15 @@ describe("Hasher", () => { roots = []; }); - const setupFixtureAndReturnHash = async ( - fixture: FixtureName = "monorepo" - ) => { - const packageRoot = setupFixture(fixture); - roots.push(packageRoot); + async function setupFixtureAndReturnHash(fixture: FixtureName = "monorepo") { + const root = setupFixture(fixture); + roots.push(root); - const options = { packageRoot, outputGlob: ["lib/**"] }; - const buildSignature = "yarn build"; - - const hasher = new Hasher(options, logger); - const hash = await hasher.createPackageHash(buildSignature); + const hasher = new Hasher({ packageRoot: root }, logger); + const hash = await hasher.createPackageHash("yarn build"); return hash; - }; + } it("creates different hashes given different fixtures", async () => { const hash = await setupFixtureAndReturnHash(); diff --git a/packages/backfill-hasher/src/__tests__/getFileHashes.ts b/packages/backfill-hasher/src/__tests__/getFileHashes.ts index 04812a529..0d1b95b9c 100644 --- a/packages/backfill-hasher/src/__tests__/getFileHashes.ts +++ b/packages/backfill-hasher/src/__tests__/getFileHashes.ts @@ -89,7 +89,7 @@ describe(getFileHashes.name, () => { root = ""; }); - it("can parse committed file", async () => { + it("can parse committed file", () => { root = setupFixture("hasher-test-project"); const results = getFileHashes(root); @@ -101,7 +101,7 @@ describe(getFileHashes.name, () => { }); }); - it("can handle files in subfolders", async () => { + it("can handle files in subfolders", () => { root = setupFixture("hasher-nested-test-project"); const results = getFileHashes(root); @@ -112,7 +112,7 @@ describe(getFileHashes.name, () => { }); }); - it("can handle adding one file", async () => { + it("can handle adding one file", () => { root = setupFixture("hasher-test-project"); const tempFilePath = path.join(root, "a.txt"); @@ -129,7 +129,7 @@ describe(getFileHashes.name, () => { }); }); - it("can handle adding two files", async () => { + it("can handle adding two files", () => { root = setupFixture("hasher-test-project"); const tempFilePath1 = path.join(root, "a.txt"); @@ -149,7 +149,7 @@ describe(getFileHashes.name, () => { }); }); - it("can handle removing one file", async () => { + it("can handle removing one file", () => { root = setupFixture("hasher-test-project"); const testFilePath = path.join(root, "file1.txt"); @@ -164,7 +164,7 @@ describe(getFileHashes.name, () => { }); }); - it("can handle changing one file", async () => { + it("can handle changing one file", () => { root = setupFixture("hasher-test-project"); const testFilePath = path.join(root, "file1.txt"); @@ -180,7 +180,7 @@ describe(getFileHashes.name, () => { }); }); - it("can handle a filename with spaces", async () => { + it("can handle a filename with spaces", () => { root = setupFixture("hasher-test-project"); const tempFilePath = path.join(root, "a file.txt"); @@ -197,7 +197,7 @@ describe(getFileHashes.name, () => { }); }); - it("can handle a filename with multiple spaces", async () => { + it("can handle a filename with multiple spaces", () => { root = setupFixture("hasher-test-project"); const tempFilePath = path.join(root, "a file name.txt"); @@ -214,7 +214,7 @@ describe(getFileHashes.name, () => { }); }); - it("can handle a filename with non-standard characters", async () => { + it("can handle a filename with non-standard characters", () => { root = setupFixture("hasher-test-project"); const tempFilePath = path.join(root, "newFile批把.txt"); diff --git a/packages/backfill-hasher/src/__tests__/hashOfFiles.test.ts b/packages/backfill-hasher/src/__tests__/hashOfFiles.test.ts index dc00c351a..f32895af5 100644 --- a/packages/backfill-hasher/src/__tests__/hashOfFiles.test.ts +++ b/packages/backfill-hasher/src/__tests__/hashOfFiles.test.ts @@ -18,22 +18,22 @@ describe("generateHashOfFiles()", () => { root = setupFixture("monorepo"); let repoInfo = await getRepoInfoNoCache(root); - const hashOfPackage = await generateHashOfFiles(root, repoInfo); + const hashOfPackage = generateHashOfFiles(root, repoInfo); fs.writeFileSync(path.join(root, "foo.txt"), "bar"); repoInfo = await getRepoInfoNoCache(root); - const hashOfPackageWithFoo = await generateHashOfFiles(root, repoInfo); + const hashOfPackageWithFoo = generateHashOfFiles(root, repoInfo); expect(hashOfPackage).not.toEqual(hashOfPackageWithFoo); fs.writeFileSync(path.join(root, "foo.txt"), "foo"); repoInfo = await getRepoInfoNoCache(root); - const hashOfPackageWithFoo2 = await generateHashOfFiles(root, repoInfo); + const hashOfPackageWithFoo2 = generateHashOfFiles(root, repoInfo); expect(hashOfPackageWithFoo).not.toEqual(hashOfPackageWithFoo2); fs.unlinkSync(path.join(root, "foo.txt")); repoInfo = await getRepoInfoNoCache(root); - const hashOfPackageWithoutFoo = await generateHashOfFiles(root, repoInfo); + const hashOfPackageWithoutFoo = generateHashOfFiles(root, repoInfo); expect(hashOfPackage).toEqual(hashOfPackageWithoutFoo); }); @@ -42,7 +42,7 @@ describe("generateHashOfFiles()", () => { let repoInfo = await getRepoInfoNoCache(root); - const hashOfPackageA = await generateHashOfFiles( + const hashOfPackageA = generateHashOfFiles( path.join(root, "packages", "package-a"), repoInfo ); @@ -51,7 +51,7 @@ describe("generateHashOfFiles()", () => { fs.writeFileSync(path.join(root, "packages", "package-abc", "foo"), "bar"); repoInfo = await getRepoInfoNoCache(root); - const newHashOfPackageA = await generateHashOfFiles( + const newHashOfPackageA = generateHashOfFiles( path.join(root, "packages", "package-a"), repoInfo ); @@ -65,13 +65,13 @@ describe("generateHashOfFiles()", () => { fs.writeFileSync(path.join(root, "foo.txt"), "bar"); let repoInfo = await getRepoInfoNoCache(root); - const hashOfPackageWithFoo = await generateHashOfFiles(root, repoInfo); + const hashOfPackageWithFoo = generateHashOfFiles(root, repoInfo); fs.unlinkSync(path.join(root, "foo.txt")); fs.writeFileSync(path.join(root, "bar.txt"), "bar"); repoInfo = await getRepoInfoNoCache(root); - const hashOfPackageWithBar = await generateHashOfFiles(root, repoInfo); + const hashOfPackageWithBar = generateHashOfFiles(root, repoInfo); expect(hashOfPackageWithFoo).not.toEqual(hashOfPackageWithBar); }); @@ -88,7 +88,7 @@ describe("generateHashOfFiles()", () => { fs.writeFileSync(path.join(folder, "foo.txt"), "bar"); const repoInfo = await getRepoInfoNoCache(root); - const hashOfPackage = await generateHashOfFiles(root, repoInfo); + const hashOfPackage = generateHashOfFiles(root, repoInfo); expect(hashOfPackage).toEqual("4d4ca2ecc436e1198554f5d03236ea8f956ac0c4"); }); @@ -105,7 +105,7 @@ describe("generateHashOfFiles()", () => { fs.writeFileSync(path.join(folder, "foo.txt"), "bar"); const repoInfo = await getRepoInfoNoCache(root); - const hashOfPackage = await generateHashOfFiles(folder, repoInfo); + const hashOfPackage = generateHashOfFiles(folder, repoInfo); expect(hashOfPackage).toEqual("438b5f734e6de1ef0eb9114a28ef230a9ff83f54"); }); @@ -118,7 +118,7 @@ describe("generateHashOfFiles()", () => { const repoInfo = await getRepoInfoNoCache(root); - const hashOfPackage = await generateHashOfFiles(folder, repoInfo); + const hashOfPackage = generateHashOfFiles(folder, repoInfo); expect(hashOfPackage).toEqual("b91634233c6a3768136391c804967bf0e0a6578d"); }); diff --git a/packages/backfill-hasher/src/hashOfFiles.ts b/packages/backfill-hasher/src/hashOfFiles.ts index 956a255c1..afcabead2 100644 --- a/packages/backfill-hasher/src/hashOfFiles.ts +++ b/packages/backfill-hasher/src/hashOfFiles.ts @@ -12,10 +12,10 @@ import type { RepoInfo } from "./types.js"; * @param packageRoot The root of the package * @param repoInfo The repoInfo that carries information about repo-wide hashes */ -export async function generateHashOfFiles( +export function generateHashOfFiles( packageRoot: string, repoInfo: RepoInfo -): Promise { +): string { const { repoHashes, root, packageHashes } = repoInfo; const hashes: string[] = []; diff --git a/packages/backfill-hasher/src/hashOfPackage.ts b/packages/backfill-hasher/src/hashOfPackage.ts index 59067aadc..1f6028078 100644 --- a/packages/backfill-hasher/src/hashOfPackage.ts +++ b/packages/backfill-hasher/src/hashOfPackage.ts @@ -34,11 +34,11 @@ export function generateHashOfInternalPackages( const memoization: { [key: string]: PackageHashInfo } = {}; -export async function getPackageHash( +export function getPackageHash( packageRoot: string, repoInfo: RepoInfo, logger: Logger -): Promise { +): PackageHashInfo { const { packageInfos, parsedLock } = repoInfo; const memoizationKey = path.resolve(packageRoot); @@ -72,7 +72,7 @@ export async function getPackageHash( ...externalDependencies, ]; - const filesHash = await generateHashOfFiles(packageRoot, repoInfo); + const filesHash = generateHashOfFiles(packageRoot, repoInfo); const dependenciesHash = hashStrings(resolvedDependencies); logger.silly(name); diff --git a/packages/backfill/src/__tests__/api.test.ts b/packages/backfill/src/__tests__/api.test.ts index ff9723ffd..5f4cca0f8 100644 --- a/packages/backfill/src/__tests__/api.test.ts +++ b/packages/backfill/src/__tests__/api.test.ts @@ -5,7 +5,7 @@ import { fetch, put, makeLogger } from "../api.js"; describe("api", () => { it("fetch works with custom providers", async () => { - const packageRoot = await setupFixture("basic"); + const packageRoot = setupFixture("basic"); const logger = makeLogger("silly", process.stdout, process.stderr); const config = createDefaultConfig(packageRoot); @@ -31,7 +31,7 @@ describe("api", () => { }); it("put works with custom providers", async () => { - const packageRoot = await setupFixture("basic"); + const packageRoot = setupFixture("basic"); const logger = makeLogger("silly", process.stdout, process.stderr); const config = createDefaultConfig(packageRoot); diff --git a/packages/backfill/src/__tests__/audit.test.ts b/packages/backfill/src/__tests__/audit.test.ts index ebc2d5140..e1bf03b31 100644 --- a/packages/backfill/src/__tests__/audit.test.ts +++ b/packages/backfill/src/__tests__/audit.test.ts @@ -16,10 +16,10 @@ describe("Audit", () => { pathToBackfill = await findPathToBackfill(); }); - beforeEach(async () => { + beforeEach(() => { backfillOutput = undefined; - const monorepoPath = await setupFixture("monorepo"); + const monorepoPath = setupFixture("monorepo"); // Create a .git folder to help `--audit` identify the boundaries of the repo fs.mkdirpSync(path.join(monorepoPath, ".git")); diff --git a/packages/backfill/src/__tests__/backfill.test.ts b/packages/backfill/src/__tests__/backfill.test.ts index 218a8fb69..a717a8987 100644 --- a/packages/backfill/src/__tests__/backfill.test.ts +++ b/packages/backfill/src/__tests__/backfill.test.ts @@ -12,7 +12,7 @@ const logger = makeLogger("mute"); describe("backfill", () => { it("with modified source files", async () => { // Set up - const fixtureLocation = await setupFixture("basic"); + const fixtureLocation = setupFixture("basic"); const config = createConfig(logger, fixtureLocation); config.outputGlob = ["src/*"]; @@ -60,7 +60,7 @@ describe("backfill", () => { }); it("with cache miss and then cache hit", async () => { // Set up - const fixtureLocation = await setupFixture("basic"); + const fixtureLocation = setupFixture("basic"); const config = createConfig(logger, fixtureLocation); @@ -104,7 +104,7 @@ describe("backfill", () => { it("should set the proper custom cache provider name", async () => { // Set up - const fixtureLocation = await setupFixture("custom-cache-provider"); + const fixtureLocation = setupFixture("custom-cache-provider"); const spyLogger = jest.spyOn(logger, "setCacheProvider"); diff --git a/packages/backfill/src/__tests__/cli.test.ts b/packages/backfill/src/__tests__/cli.test.ts index 55919b82e..5a0052fc4 100644 --- a/packages/backfill/src/__tests__/cli.test.ts +++ b/packages/backfill/src/__tests__/cli.test.ts @@ -65,7 +65,7 @@ describe("createBuildCommand", () => { }); it("clears the output folder", async () => { - const fixtureLocation = await setupFixture("pre-built"); + const fixtureLocation = setupFixture("pre-built"); const buildCommand = createBuildCommand( ["echo foo"], true, diff --git a/packages/backfill/src/__tests__/e2e.test.ts b/packages/backfill/src/__tests__/e2e.test.ts index cc4974752..29211554d 100644 --- a/packages/backfill/src/__tests__/e2e.test.ts +++ b/packages/backfill/src/__tests__/e2e.test.ts @@ -16,7 +16,7 @@ describe("End to end", () => { }); it("works", async () => { - const packageRoot = await setupFixture("basic"); + const packageRoot = setupFixture("basic"); await execa("node", [pathToBackfill, "--", "npm run compile"], { cwd: packageRoot, @@ -32,7 +32,7 @@ describe("End to end", () => { }); it("fails on error with error code 1", async () => { - const packageRoot = await setupFixture("basic"); + const packageRoot = setupFixture("basic"); const execProcess = execa("node", [pathToBackfill, "--", "somecommand"], { cwd: packageRoot, diff --git a/packages/cache/src/__tests__/chunkPromise.test.ts b/packages/cache/src/__tests__/chunkPromise.test.ts index 8ee32693d..d82390721 100644 --- a/packages/cache/src/__tests__/chunkPromise.test.ts +++ b/packages/cache/src/__tests__/chunkPromise.test.ts @@ -17,7 +17,7 @@ describe("chunking promises", () => { } }); - it("should throw, if one promise was rejected", async () => { + it("should throw, if one promise was rejected", () => { const mockedPromiseFns = [ jest.fn().mockResolvedValue(1).mockName("1"), jest.fn().mockResolvedValue(2).mockName("2"), diff --git a/packages/cli/src/__tests__/initializeReporters.test.ts b/packages/cli/src/__tests__/initializeReporters.test.ts index 81c81f546..bb86ba207 100644 --- a/packages/cli/src/__tests__/initializeReporters.test.ts +++ b/packages/cli/src/__tests__/initializeReporters.test.ts @@ -32,7 +32,7 @@ describe("initializeReporters", () => { delete process.env.TF_BUILD; }); - afterEach(async () => { + afterEach(() => { for (const reporter of reporters || []) { reporter.cleanup?.(); } diff --git a/packages/cli/src/__tests__/simulateFileAccess.test.ts b/packages/cli/src/__tests__/simulateFileAccess.test.ts index bc831381f..363faadf2 100644 --- a/packages/cli/src/__tests__/simulateFileAccess.test.ts +++ b/packages/cli/src/__tests__/simulateFileAccess.test.ts @@ -46,12 +46,12 @@ describe("simulateFileAccess", () => { jest.resetAllMocks(); }); - test("should probe files and their parent directories for inputs", async () => { + it("should probe files and their parent directories for inputs", () => { // Nested directory structure with a file at the deepest level const inputs = ["packages/a/src/components/Button.tsx", "packages/b/dist/index.js"]; const outputs: string[] = []; - await simulateFileAccess(mockLogger, mockRoot, inputs, outputs); + simulateFileAccess(mockLogger, mockRoot, inputs, outputs); // Verify the files were probed expect(mockOpenSync).toHaveBeenCalledWith(path.join(mockRoot, "packages/a/src/components/Button.tsx"), "r"); @@ -68,12 +68,12 @@ describe("simulateFileAccess", () => { expect(mockReaddirSync).toHaveBeenCalledWith(path.join(mockRoot, "packages/b")); }); - test("should handle deeply nested directories", async () => { + it("should handle deeply nested directories", () => { // Very deep nesting with a single file at the deepest level const inputs = ["level1/level2/level3/level4/level5/file.txt"]; const outputs: string[] = []; - await simulateFileAccess(mockLogger, mockRoot, inputs, outputs); + simulateFileAccess(mockLogger, mockRoot, inputs, outputs); // Verify the file was probed expect(mockOpenSync).toHaveBeenCalledWith(path.join(mockRoot, "level1/level2/level3/level4/level5/file.txt"), "r"); @@ -86,11 +86,11 @@ describe("simulateFileAccess", () => { expect(mockReaddirSync).toHaveBeenCalledWith(path.join(mockRoot, "level1")); }); - test("should update timestamps for output files and their directories", async () => { + it("should update timestamps for output files and their directories", () => { const inputs: string[] = []; const outputs = ["dist/bundles/main.js", "dist/types/index.d.ts"]; - await simulateFileAccess(mockLogger, mockRoot, inputs, outputs); + simulateFileAccess(mockLogger, mockRoot, inputs, outputs); // Verify timestamps were updated for output files expect(mockUtimesSync).toHaveBeenCalledWith(path.join(mockRoot, "dist/bundles/main.js"), expect.any(Date), expect.any(Date)); @@ -102,11 +102,11 @@ describe("simulateFileAccess", () => { expect(mockUtimesSync).toHaveBeenCalledWith(path.join(mockRoot, "dist"), expect.any(Date), expect.any(Date)); }); - test("should handle mixed inputs and outputs with overlapping directories", async () => { + it("should handle mixed inputs and outputs with overlapping directories", () => { const inputs = ["src/components/Button.tsx", "src/utils/helpers.ts"]; const outputs = ["dist/components/Button.js", "dist/utils/helpers.js"]; - await simulateFileAccess(mockLogger, mockRoot, inputs, outputs); + simulateFileAccess(mockLogger, mockRoot, inputs, outputs); // Verify both input and output files were handled correctly // Input files should be opened and closed @@ -128,7 +128,7 @@ describe("simulateFileAccess", () => { expect(mockUtimesSync).toHaveBeenCalledWith(path.join(mockRoot, "dist"), expect.any(Date), expect.any(Date)); }); - test("should handle errors during file operations", async () => { + it("should handle errors during file operations", () => { // Restore original mocks to allow error simulation mockOpenSync.mockRestore(); mockReadSync.mockRestore(); @@ -151,19 +151,19 @@ describe("simulateFileAccess", () => { const outputs: string[] = []; // Function should not throw even when file operations fail - await expect(simulateFileAccess(mockLogger, mockRoot, inputs, outputs)).resolves.not.toThrow(); + simulateFileAccess(mockLogger, mockRoot, inputs, outputs); // Verify that other operations still proceed despite errors expect(fs.openSync).toHaveBeenCalledWith(path.join(mockRoot, "src/components/Button.tsx"), "r"); expect(fs.openSync).toHaveBeenCalledWith(failingPath, "r"); }); - test("should handle empty directories with only a single file", async () => { + it("should handle empty directories with only a single file", () => { // Create a test case where the input list contains only directories and a single file const inputs = ["empty-dir-1/", "empty-dir-2/", "empty-dir-3/single-file.txt"]; const outputs: string[] = []; - await simulateFileAccess(mockLogger, mockRoot, inputs, outputs); + simulateFileAccess(mockLogger, mockRoot, inputs, outputs); // Verify all directories were enumerated using readdirSync expect(mockReaddirSync).toHaveBeenCalledWith(path.join(mockRoot, "empty-dir-1/")); diff --git a/packages/cli/src/commands/exec/executeRemotely.ts b/packages/cli/src/commands/exec/executeRemotely.ts index 0e1319067..b03987d21 100644 --- a/packages/cli/src/commands/exec/executeRemotely.ts +++ b/packages/cli/src/commands/exec/executeRemotely.ts @@ -144,7 +144,7 @@ export async function executeRemotely(options: ExecRemotelyOptions, command: Com // we will simulate file access even if exit code may be non-zero const relativeGlobalInputsForTarget = path.relative(root, path.join(response.cwd, response.globalInputHashFile)); - await simulateFileAccess(logger, root, [...response.inputs, relativeGlobalInputsForTarget], response.outputs); + simulateFileAccess(logger, root, [...response.inputs, relativeGlobalInputsForTarget], response.outputs); } else { process.exitCode = 1; } diff --git a/packages/cli/src/commands/exec/simulateFileAccess.ts b/packages/cli/src/commands/exec/simulateFileAccess.ts index 07e86cb00..7399f49bc 100644 --- a/packages/cli/src/commands/exec/simulateFileAccess.ts +++ b/packages/cli/src/commands/exec/simulateFileAccess.ts @@ -2,7 +2,7 @@ import type { Logger } from "@lage-run/logger"; import path from "path"; import fs from "fs"; -export async function simulateFileAccess(logger: Logger, root: string, inputs: string[], outputs: string[]): Promise { +export function simulateFileAccess(logger: Logger, root: string, inputs: string[], outputs: string[]): void { logger.silly("Now probing and touching inputs and outputs"); // Helper to get all directory parts up to root diff --git a/packages/cli/src/commands/launchServerInBackground.ts b/packages/cli/src/commands/launchServerInBackground.ts index cf013c4b5..04d2b6053 100644 --- a/packages/cli/src/commands/launchServerInBackground.ts +++ b/packages/cli/src/commands/launchServerInBackground.ts @@ -73,7 +73,7 @@ export async function launchServerInBackground({ maxBuffer: 1024 * 1024 * 100, }); - if (child && child.pid) { + if (child.pid) { fs.writeFileSync(lockfilePath, child.pid.toString()); } diff --git a/packages/cli/src/commands/run/createTargetGraph.ts b/packages/cli/src/commands/run/createTargetGraph.ts index 9f8e6799d..736b442b1 100644 --- a/packages/cli/src/commands/run/createTargetGraph.ts +++ b/packages/cli/src/commands/run/createTargetGraph.ts @@ -102,7 +102,7 @@ export async function createTargetGraph(options: CreateTargetGraphOptions): Prom for (const [id, definition] of pipelineEntries) { if (Array.isArray(definition)) { - await builder.addTargetConfig( + builder.addTargetConfig( id, { cache: true, @@ -113,7 +113,7 @@ export async function createTargetGraph(options: CreateTargetGraphOptions): Prom changedFiles ); } else { - await builder.addTargetConfig(id, definition, changedFiles); + builder.addTargetConfig(id, definition, changedFiles); } } diff --git a/packages/cli/src/commands/run/watchAction.ts b/packages/cli/src/commands/run/watchAction.ts index 66808cc5d..70144df4d 100644 --- a/packages/cli/src/commands/run/watchAction.ts +++ b/packages/cli/src/commands/run/watchAction.ts @@ -115,8 +115,8 @@ export async function watchAction(options: RunOptions, command: Command): Promis } // When initial run is done, disable fetching of caches on all targets, keep writing to the cache - const watcher = await watch(root, packageInfos); - watcher.on("change", async (packageName) => { + const watcher = watch(root, packageInfos); + watcher.on("change", (packageName) => { reporter.resetLogEntries(); const targets = new Map(); for (const target of targetGraph.targets.values()) { @@ -127,8 +127,10 @@ export async function watchAction(options: RunOptions, command: Command): Promis const deltaGraph = { targets }; - const deltaSummary = await scheduler.run(root, deltaGraph, true); - displaySummary(deltaSummary, logger.reporters); + void (async () => { + const deltaSummary = await scheduler.run(root, deltaGraph, true); + displaySummary(deltaSummary, logger.reporters); + })().catch(() => {}); }); } diff --git a/packages/cli/src/commands/server/action.ts b/packages/cli/src/commands/server/action.ts index e2ea31197..1448adad1 100644 --- a/packages/cli/src/commands/server/action.ts +++ b/packages/cli/src/commands/server/action.ts @@ -33,7 +33,7 @@ export async function serverAction(options: WorkerOptions): Promise { const abortController = new AbortController(); - const lageService = await createLageService({ + const lageService = createLageService({ cwd, serverControls: { abortController, diff --git a/packages/cli/src/commands/server/lageService.ts b/packages/cli/src/commands/server/lageService.ts index a06363c1d..e69383c2b 100644 --- a/packages/cli/src/commands/server/lageService.ts +++ b/packages/cli/src/commands/server/lageService.ts @@ -157,14 +157,9 @@ interface CreateLageServiceOptions { tasks: string[]; } -export async function createLageService({ - cwd, - serverControls, - logger, - concurrency, - tasks, -}: CreateLageServiceOptions): Promise { +export function createLageService({ cwd, serverControls, logger, concurrency, tasks }: CreateLageServiceOptions): ILageService { return { + // eslint-disable-next-line @typescript-eslint/require-await async ping() { return { pong: true }; }, diff --git a/packages/cli/src/commands/server/singleTargetWorker.ts b/packages/cli/src/commands/server/singleTargetWorker.ts index 3478cb8d7..1446fe988 100644 --- a/packages/cli/src/commands/server/singleTargetWorker.ts +++ b/packages/cli/src/commands/server/singleTargetWorker.ts @@ -8,7 +8,7 @@ interface SimpleTargetWorkerDataOptions { runners: TargetRunnerPickerOptions; } -async function setup(options: SimpleTargetWorkerDataOptions) { +function setup(options: SimpleTargetWorkerDataOptions) { const { runners } = options; const runnerPicker = new TargetRunnerPicker(runners); @@ -18,24 +18,23 @@ async function setup(options: SimpleTargetWorkerDataOptions) { }; } -void (async () => { - const { runnerPicker } = await setup(workerData); - async function run(data: { target: Target }, abortSignal?: AbortSignal) { - let value: unknown = undefined; - const runner = await runnerPicker.pick(data.target); - - value = await runner.run({ - target: data.target, - weight: 0, - abortSignal, - }); - - return { - skipped: false, - hash: undefined, - value, - }; - } - - registerWorker(run); -})(); +const { runnerPicker } = setup(workerData); + +async function run(data: { target: Target }, abortSignal?: AbortSignal) { + let value: unknown = undefined; + const runner = await runnerPicker.pick(data.target); + + value = await runner.run({ + target: data.target, + weight: 0, + abortSignal, + }); + + return { + skipped: false, + hash: undefined, + value, + }; +} + +registerWorker(run); diff --git a/packages/config/src/readConfigFile.ts b/packages/config/src/readConfigFile.ts index 94842a5cf..4945e35d2 100644 --- a/packages/config/src/readConfigFile.ts +++ b/packages/config/src/readConfigFile.ts @@ -14,7 +14,7 @@ export async function readConfigFile(cwd: string): Promise { packages: { a: { internalDeps: ["b"] }, b: {} }, }); - await repo.install(); + repo.install(); const results = await repo.run("test"); const jsonOutput = parseNdJson(results.stdout, results.stderr); @@ -46,7 +46,7 @@ describe("basics", () => { }, }); - await repo.install(); + repo.install(); const results = await repo.run("extra"); const jsonOutput = parseNdJson(results.stdout, results.stderr); @@ -66,7 +66,7 @@ describe("basics", () => { packages: { a: { internalDeps: ["b"] }, b: {} }, }); - await repo.install(); + repo.install(); // run once without params await repo.run("test"); @@ -123,7 +123,7 @@ describe("basics", () => { packages: { a: { internalDeps: ["b"] }, b: {} }, }); - await repo.install(); + repo.install(); const results = await repo.run("test"); const jsonOutput = parseNdJson(results.stdout, results.stderr); diff --git a/packages/e2e-tests/src/basicFailure.test.ts b/packages/e2e-tests/src/basicFailure.test.ts index 3c35f094d..225ff7b9d 100644 --- a/packages/e2e-tests/src/basicFailure.test.ts +++ b/packages/e2e-tests/src/basicFailure.test.ts @@ -19,7 +19,7 @@ describe("basic failure case where a dependent target has failed", () => { c: {}, }, }); - await repo.install(); + repo.install(); let results: execa.ExecaError | undefined; @@ -53,7 +53,7 @@ describe("basic failure case where a dependent target has failed", () => { c: {}, }, }); - await repo.install(); + repo.install(); let results: execa.ExecaError | undefined; diff --git a/packages/e2e-tests/src/bigapp.test.ts b/packages/e2e-tests/src/bigapp.test.ts index 0e2d86e47..352b17e44 100644 --- a/packages/e2e-tests/src/bigapp.test.ts +++ b/packages/e2e-tests/src/bigapp.test.ts @@ -26,7 +26,7 @@ describe("bigapp test", () => { }, }); - await repo.install(); + repo.install(); const results = await repo.run("test"); const jsonOutput = parseNdJson(results.stdout, results.stderr); diff --git a/packages/e2e-tests/src/cacheClear.test.ts b/packages/e2e-tests/src/cacheClear.test.ts index 371bccf0d..40c574644 100644 --- a/packages/e2e-tests/src/cacheClear.test.ts +++ b/packages/e2e-tests/src/cacheClear.test.ts @@ -25,7 +25,7 @@ describe("Cache clear", () => { b: { scripts: { build: "echo b:build" } }, }, }); - await repo.install(); + repo.install(); // Run build so we get a cache folder await repo.run("build"); diff --git a/packages/e2e-tests/src/customReporter.test.ts b/packages/e2e-tests/src/customReporter.test.ts index 1fc547f43..d98c2b195 100644 --- a/packages/e2e-tests/src/customReporter.test.ts +++ b/packages/e2e-tests/src/customReporter.test.ts @@ -80,7 +80,7 @@ describe("custom reporters", () => { }, }); - await repo.install(); + repo.install(); const results = await repo.run("build", ["--reporter", "customTest", "--reporter", "cjs"]); const output = results.stdout + "\n" + results.stderr; @@ -110,7 +110,7 @@ describe("custom reporters", () => { }, }); - await repo.install(); + repo.install(); // Use a default reporter here too const results = await repo.run("build", [ @@ -150,7 +150,7 @@ describe("custom reporters", () => { }, }); - await repo.install(); + repo.install(); // Should throw an error when trying to use a reporter that exports a string await expect(repo!.run("build", ["--reporter", "bad"])).rejects.toThrow(/does not export a valid reporter class or instance/); @@ -189,7 +189,7 @@ export default objectReporter; }, }); - await repo.install(); + repo.install(); const results = await repo.run("build", ["--reporter", "objectReporter"]); const output = results.stdout + "\n" + results.stderr; diff --git a/packages/e2e-tests/src/info.test.ts b/packages/e2e-tests/src/info.test.ts index 329787ea9..0215c3400 100644 --- a/packages/e2e-tests/src/info.test.ts +++ b/packages/e2e-tests/src/info.test.ts @@ -17,7 +17,7 @@ describe("info command", () => { packages: { a: { internalDeps: ["b"] }, b: {} }, }); - await repo.install(); + repo.install(); const results = await repo.run("writeInfo", ["test"]); const jsonOutput = parseNdJson(results.stdout, results.stderr); @@ -32,7 +32,7 @@ describe("info command", () => { packages: { a: { internalDeps: ["b"] }, b: {} }, }); - await repo.install(); + repo.install(); const results = await repo.run("writeInfo", ["test", "--to", "b"]); const jsonOutput = parseNdJson(results.stdout, results.stderr); @@ -49,7 +49,7 @@ describe("info command", () => { c: { scripts: { build: "echo 'building c'" } }, }, }); - await repo.install(); + repo.install(); const results = await repo.run("writeInfo", ["build", "prepare"]); @@ -79,7 +79,7 @@ describe("info command", () => { d: { scripts: { nobuild: "echo 'no build'" } }, }, }); - await repo.install(); + repo.install(); const results = await repo.run("writeInfo", ["build"]); @@ -105,7 +105,7 @@ describe("info command", () => { d: { scripts: { nobuild: "echo 'no build'" } }, }, }); - await repo.install(); + repo.install(); const backCompatEnvVars = { DOMINO: "1" }; const results = await repo.run("writeInfo", ["build"], false, { env: backCompatEnvVars }); @@ -146,7 +146,7 @@ describe("info command", () => { b: {}, }, }); - await repo.install(); + repo.install(); const results = await repo.run("writeInfo", ["test", "build"]); const jsonOutput = parseNdJson(results.stdout, results.stderr); @@ -178,7 +178,7 @@ describe("info command", () => { b: {}, }, }); - await repo.install(); + repo.install(); const results = await repo.run("writeInfo", ["test", "build"]); const jsonOutput = parseNdJson(results.stdout, results.stderr); diff --git a/packages/e2e-tests/src/lageserver.test.ts b/packages/e2e-tests/src/lageserver.test.ts index 30e5c7e68..ae2509950 100644 --- a/packages/e2e-tests/src/lageserver.test.ts +++ b/packages/e2e-tests/src/lageserver.test.ts @@ -59,7 +59,7 @@ describe("lageserver", () => { await repo.init({ packages: { a: { internalDeps: ["b"] }, b: {} }, }); - await repo.install(); + repo.install(); serverProcess = repo.runServer(["build"], port); await new Promise((resolve) => setTimeout(resolve, 2000)); @@ -82,7 +82,7 @@ describe("lageserver", () => { await repo.init({ packages: { a: { internalDeps: ["b"] }, b: {} }, }); - await repo.install(); + repo.install(); const results = await execOnServer("--tasks", "build", "--", "b", "build"); @@ -117,7 +117,7 @@ describe("lageserver", () => { }, extraFiles: {}, }); - await repo.install(); + repo.install(); const results = await execOnServer("c", "build", "--tasks", "build", "--timeout", "60", "--reporter", "json"); diff --git a/packages/e2e-tests/src/mock/monorepo.ts b/packages/e2e-tests/src/mock/monorepo.ts index 9a5b2f9c8..15dd97b43 100644 --- a/packages/e2e-tests/src/mock/monorepo.ts +++ b/packages/e2e-tests/src/mock/monorepo.ts @@ -130,7 +130,7 @@ export class Monorepo extends BaseMonorepo { /** * Run `yarn install` for the fixture */ - public async install(): Promise { + public install(): void { execa.sync(`"${process.execPath}"`, [`"${this.yarnPath}"`, "install", "--no-immutable"], { cwd: this.root, shell: true }); } @@ -142,7 +142,7 @@ export class Monorepo extends BaseMonorepo { stdio: "ignore", }); - if (cp && !cp.pid) { + if (!cp.pid) { throw new Error("Failed to start server"); } diff --git a/packages/e2e-tests/src/remoteFallback.test.ts b/packages/e2e-tests/src/remoteFallback.test.ts index 1aae7eae0..c00ad1f16 100644 --- a/packages/e2e-tests/src/remoteFallback.test.ts +++ b/packages/e2e-tests/src/remoteFallback.test.ts @@ -44,7 +44,7 @@ describe("RemoteFallbackCacheProvider", () => { b: { scripts: { build: "echo b:build" } }, }, }); - await repo.install(); + repo.install(); const results = await repo.run("test", ["--skip-local-cache"]); @@ -69,7 +69,7 @@ describe("RemoteFallbackCacheProvider", () => { b: { scripts: { build: "echo b:build" } }, }, }); - await repo.install(); + repo.install(); const results = await repo.run("test"); @@ -99,7 +99,7 @@ describe("RemoteFallbackCacheProvider", () => { b: { scripts: { build: "echo b:build" } }, }, }); - await repo.install(); + repo.install(); const results = await repo.run("test", ["--log-level", "silly"]); @@ -130,7 +130,7 @@ describe("RemoteFallbackCacheProvider", () => { b: { scripts: { build: "echo b:build" } }, }, }); - await repo.install(); + repo.install(); const results = await repo.run("test", ["--log-level", "silly"]); diff --git a/packages/e2e-tests/src/transitiveTaskDeps.test.ts b/packages/e2e-tests/src/transitiveTaskDeps.test.ts index f5e001a3c..faadd7bb3 100644 --- a/packages/e2e-tests/src/transitiveTaskDeps.test.ts +++ b/packages/e2e-tests/src/transitiveTaskDeps.test.ts @@ -29,7 +29,7 @@ describe("transitive task deps test", () => { b: { scripts: { build: "echo b:build" } }, }, }); - await repo.install(); + repo.install(); const results = await repo.run("test"); @@ -62,7 +62,7 @@ describe("transitive task deps test", () => { c: { scripts: { transpile: "echo c:transpile" } }, }, }); - await repo.install(); + repo.install(); const results = await repo.run("bundle", ["--scope", "a"]); @@ -97,7 +97,7 @@ describe("transitive task deps test", () => { c: { scripts: { transpile: "echo c:transpile" } }, }, }); - await repo.install(); + repo.install(); const results = await repo.run("bundle", ["--scope", "a"]); @@ -146,7 +146,7 @@ describe("transitive task deps test", () => { c: { scripts: { transpile: "echo c:transpile" } }, }, }); - await repo.install(); + repo.install(); const results = await repo.run("bundle", ["--scope", "a"]); @@ -195,7 +195,7 @@ describe("transitive task deps test", () => { }, }); - await repo.install(); + repo.install(); const results = await repo.run("writeInfo", ["typecheck", "--scope", "app"]); diff --git a/packages/hasher/src/TargetHasher.ts b/packages/hasher/src/TargetHasher.ts index 002077640..425db2a02 100644 --- a/packages/hasher/src/TargetHasher.ts +++ b/packages/hasher/src/TargetHasher.ts @@ -218,7 +218,7 @@ export class TargetHasher { return globalFileHashes; } - public async cleanup(): Promise { + public cleanup(): void { this.writeTargetHashesManifest(); this.fileHasher.writeManifest(); } diff --git a/packages/hasher/src/__tests__/TargetHasher.test.ts b/packages/hasher/src/__tests__/TargetHasher.test.ts index 3b2f57810..1991ab3bc 100644 --- a/packages/hasher/src/__tests__/TargetHasher.test.ts +++ b/packages/hasher/src/__tests__/TargetHasher.test.ts @@ -27,7 +27,7 @@ describe("The main Hasher class", () => { async function getHash(hasher: TargetHasher, target: Target) { await hasher.initialize(); const hash = await hasher.hash(target); - await hasher.cleanup(); + hasher.cleanup(); return hash; } diff --git a/packages/rpc/src/createServer.ts b/packages/rpc/src/createServer.ts index c97c9ea07..6b3728930 100644 --- a/packages/rpc/src/createServer.ts +++ b/packages/rpc/src/createServer.ts @@ -22,8 +22,7 @@ export async function createServer( }); server.get("/", (_, reply) => { - void reply.type("text/plain"); - void reply.send("lage service"); + void reply.type("text/plain").send("lage service"); }); return server; diff --git a/packages/runners/src/NoOpRunner.ts b/packages/runners/src/NoOpRunner.ts index f20740963..4bd770c13 100644 --- a/packages/runners/src/NoOpRunner.ts +++ b/packages/runners/src/NoOpRunner.ts @@ -1,6 +1,7 @@ import type { TargetRunner } from "./types/TargetRunner.js"; export class NoOpRunner implements TargetRunner { + // eslint-disable-next-line @typescript-eslint/require-await public async shouldRun(): Promise { return true; } diff --git a/packages/runners/src/NpmScriptRunner.ts b/packages/runners/src/NpmScriptRunner.ts index db8d0c0c9..fdadaa276 100644 --- a/packages/runners/src/NpmScriptRunner.ts +++ b/packages/runners/src/NpmScriptRunner.ts @@ -47,6 +47,7 @@ export class NpmScriptRunner implements TargetRunner { return targetOptions?.script ?? target.task; } + // eslint-disable-next-line @typescript-eslint/require-await -- match signature public async shouldRun(target: Target): Promise { // By convention, do not run anything if there is no script for this task defined in package.json (counts as "success") // diff --git a/packages/scheduler/src/SimpleScheduler.ts b/packages/scheduler/src/SimpleScheduler.ts index 1bd71b7ab..bef457fba 100644 --- a/packages/scheduler/src/SimpleScheduler.ts +++ b/packages/scheduler/src/SimpleScheduler.ts @@ -158,7 +158,7 @@ export class SimpleScheduler implements TargetScheduler { const poolStats = pool.stats(); - await this.options.hasher.cleanup(); + this.options.hasher.cleanup(); return { targetRunByStatus, diff --git a/packages/scheduler/src/WrappedTarget.ts b/packages/scheduler/src/WrappedTarget.ts index fef6e20be..b67da0f3c 100644 --- a/packages/scheduler/src/WrappedTarget.ts +++ b/packages/scheduler/src/WrappedTarget.ts @@ -215,9 +215,14 @@ export class WrappedTarget implements TargetRun { if (data.type === "log") { logger.log(data.level, data.msg, { target, threadId: worker.threadId }); } else if (data.type === "hash") { - void this.options.hasher.hash(target).then((hash) => { - worker.postMessage({ type: "hash", hash }); - }); + void this.options.hasher + .hash(target) + .then((hash) => { + worker.postMessage({ type: "hash", hash }); + }) + .catch((e) => { + logger.warn(`Failed to hash target ${target.id}: ${e instanceof Error ? e.message : String(e)}`); + }); } else if (this.options.onMessage) { this.options.onMessage(data, postMessage); } diff --git a/packages/scheduler/src/__tests__/SimpleScheduler.watchmode.test.ts b/packages/scheduler/src/__tests__/SimpleScheduler.watchmode.test.ts index 5f7bdcad5..51f43416d 100644 --- a/packages/scheduler/src/__tests__/SimpleScheduler.watchmode.test.ts +++ b/packages/scheduler/src/__tests__/SimpleScheduler.watchmode.test.ts @@ -28,6 +28,7 @@ describe("SimpleScheduler watch mode", () => { const hasher = new TargetHasher({ root, environmentGlob: [] }); const runner: TargetRunner = { + // eslint-disable-next-line @typescript-eslint/require-await async shouldRun() { return true; }, @@ -74,6 +75,7 @@ describe("SimpleScheduler watch mode", () => { const hasher = new TargetHasher({ root, environmentGlob: [] }); const runner: TargetRunner = { + // eslint-disable-next-line @typescript-eslint/require-await async shouldRun() { return true; }, diff --git a/packages/scheduler/src/__tests__/WrappedTarget.test.ts b/packages/scheduler/src/__tests__/WrappedTarget.test.ts index 12310e08a..d8009af72 100644 --- a/packages/scheduler/src/__tests__/WrappedTarget.test.ts +++ b/packages/scheduler/src/__tests__/WrappedTarget.test.ts @@ -72,14 +72,10 @@ describe("WrappedTarget", () => { it("should be able to run a target to completion", async () => { const logger = new Logger(); - const runner = { - async shouldRun() { - return true; - }, - async run() { - // nothing - }, - } as TargetRunner; + const runner: TargetRunner = { + shouldRun: () => Promise.resolve(true), + async run() {}, + }; const wrappedTarget = new WrappedTarget({ abortController: new AbortController(), @@ -105,14 +101,10 @@ describe("WrappedTarget", () => { const fakePackages = ["a", "b", "c", "d", "e", "f", "g", "h"]; const wrappedTargets: WrappedTarget[] = []; - const runner = { - async shouldRun() { - return true; - }, - async run() { - // nothing - }, - } as TargetRunner; + const runner: TargetRunner = { + shouldRun: () => Promise.resolve(true), + async run() {}, + }; for (const packageName of fakePackages) { const wrappedTarget = new WrappedTarget({ @@ -146,14 +138,15 @@ describe("WrappedTarget", () => { const fakePackages = ["a", "b", "c", "d", "e", "f", "g", "h"]; const wrappedTargets: WrappedTarget[] = []; - const runner = { + const runner: TargetRunner = { + shouldRun: () => Promise.resolve(true), + // eslint-disable-next-line @typescript-eslint/require-await async run({ target }) { - // nothing if (target.packageName === "a") { throw oops; } }, - } as TargetRunner; + }; for (const packageName of fakePackages) { const wrappedTarget = new WrappedTarget({ @@ -235,14 +228,10 @@ describe("WrappedTarget", () => { it("should skip the work if cache is hit", async () => { const logger = new Logger(); - const runner = { - async shouldRun() { - return true; - }, - async run() { - // nothing - }, - } as TargetRunner; + const runner: TargetRunner = { + shouldRun: () => Promise.resolve(true), + async run() {}, + }; const wrappedTarget = new WrappedTarget({ abortController: new AbortController(), diff --git a/packages/scheduler/src/cache/createCacheProvider.ts b/packages/scheduler/src/cache/createCacheProvider.ts index d0a9cb9b5..59b028c0d 100644 --- a/packages/scheduler/src/cache/createCacheProvider.ts +++ b/packages/scheduler/src/cache/createCacheProvider.ts @@ -11,9 +11,9 @@ interface CreateCacheOptions { cliArgs: string[]; } -export async function createCache(options: CreateCacheOptions): Promise<{ +export function createCache(options: CreateCacheOptions): { cacheProvider: RemoteFallbackCacheProvider; -}> { +} { const { cacheOptions, logger, root, skipLocalCache } = options; const hasRemoteCacheConfig = diff --git a/packages/scheduler/src/workers/targetWorker.ts b/packages/scheduler/src/workers/targetWorker.ts index 97ebc44fb..ae533da8e 100644 --- a/packages/scheduler/src/workers/targetWorker.ts +++ b/packages/scheduler/src/workers/targetWorker.ts @@ -18,7 +18,7 @@ interface TargetWorkerDataOptions { cacheOptions?: CacheOptions; } -async function setup(options: TargetWorkerDataOptions) { +function setup(options: TargetWorkerDataOptions) { const { runners, root, cacheOptions } = options; const logger = createLogger(); @@ -29,7 +29,7 @@ async function setup(options: TargetWorkerDataOptions) { summarize() {}, }); - const { cacheProvider } = await createCache({ + const { cacheProvider } = createCache({ root, logger, cacheOptions, @@ -46,70 +46,68 @@ async function setup(options: TargetWorkerDataOptions) { }; } -void (async () => { - const { cacheProvider, runnerPicker, options } = await setup(workerData); +const { cacheProvider, runnerPicker, options } = setup(workerData); - let hashPromiseResolve = (_hash: string) => {}; +let hashPromiseResolve = (_hash: string) => {}; - // main thread sends hash to worker because it keeps a global memory cache of the hashes - parentPort!.on("message", (data: any) => { - if (data.type === "hash") { - hashPromiseResolve(data.hash); - } - }); - - async function getCache(target: Target) { - const { shouldCache, shouldResetCache } = options; - let hash: string | undefined = undefined; - let cacheHit = false; - - if (!shouldCache || !target.cache || !cacheProvider) { - return { hash, cacheHit }; - } - - // using a special pattern in communicating with the main thread to get the hash for the target - hash = await new Promise((resolve) => { - hashPromiseResolve = resolve; - parentPort!.postMessage({ type: "hash" }); - }); +// main thread sends hash to worker because it keeps a global memory cache of the hashes +parentPort!.on("message", (data: any) => { + if (data.type === "hash") { + hashPromiseResolve(data.hash); + } +}); - if (hash && !shouldResetCache) { - cacheHit = await cacheProvider.fetch(hash, target); - } +async function getCache(target: Target) { + const { shouldCache, shouldResetCache } = options; + let hash: string | undefined = undefined; + let cacheHit = false; + if (!shouldCache || !target.cache || !cacheProvider) { return { hash, cacheHit }; } - async function saveCache(target: Target, hash: string | undefined) { - if (!hash || !cacheProvider) { - return; - } - await cacheProvider.put(hash, target); + // using a special pattern in communicating with the main thread to get the hash for the target + hash = await new Promise((resolve) => { + hashPromiseResolve = resolve; + parentPort!.postMessage({ type: "hash" }); + }); + + if (hash && !shouldResetCache) { + cacheHit = await cacheProvider.fetch(hash, target); } - async function run(data: any, abortSignal?: AbortSignal) { - const { hash, cacheHit } = await getCache(data.target); + return { hash, cacheHit }; +} - const cacheEnabled = data.target.cache && options.shouldCache && hash; +async function saveCache(target: Target, hash: string | undefined) { + if (!hash || !cacheProvider) { + return; + } + await cacheProvider.put(hash, target); +} - let value: unknown = undefined; - if (!cacheHit || !cacheEnabled) { - const runner = await runnerPicker.pick(data.target); - value = await runner.run({ - ...data, - abortSignal, - }); +async function run(data: any, abortSignal?: AbortSignal) { + const { hash, cacheHit } = await getCache(data.target); - await saveCache(data.target, hash); - } + const cacheEnabled = data.target.cache && options.shouldCache && hash; + + let value: unknown = undefined; + if (!cacheHit || !cacheEnabled) { + const runner = await runnerPicker.pick(data.target); + value = await runner.run({ + ...data, + abortSignal, + }); - return { - skipped: cacheHit, - id: data.target.id, - hash, - value, - }; + await saveCache(data.target, hash); } - registerWorker(run); -})(); + return { + skipped: cacheHit, + id: data.target.id, + hash, + value, + }; +} + +registerWorker(run); diff --git a/packages/target-graph/src/WorkspaceTargetGraphBuilder.ts b/packages/target-graph/src/WorkspaceTargetGraphBuilder.ts index 7acd2cccf..731ada7f6 100644 --- a/packages/target-graph/src/WorkspaceTargetGraphBuilder.ts +++ b/packages/target-graph/src/WorkspaceTargetGraphBuilder.ts @@ -82,7 +82,7 @@ export class WorkspaceTargetGraphBuilder { /** * Generates new `Target`, indexed by the id based on a new target configuration. */ - public async addTargetConfig(id: string, config: TargetConfig = {}, changedFiles?: string[]): Promise { + public addTargetConfig(id: string, config: TargetConfig = {}, changedFiles?: string[]): void { // Generates a target definition from the target config if (id.startsWith("//") || id.startsWith("#")) { const targetConfig = this.determineFinalTargetConfig(id, config); diff --git a/packages/target-graph/src/__tests__/WorkspaceTargetGraphBuilder.test.ts b/packages/target-graph/src/__tests__/WorkspaceTargetGraphBuilder.test.ts index ef67abe13..2cb895638 100644 --- a/packages/target-graph/src/__tests__/WorkspaceTargetGraphBuilder.test.ts +++ b/packages/target-graph/src/__tests__/WorkspaceTargetGraphBuilder.test.ts @@ -60,7 +60,7 @@ describe("workspace target graph builder", () => { enableTargetConfigMerging: false, enablePhantomTargetOptimization: false, }); - await builder.addTargetConfig("build", { + builder.addTargetConfig("build", { dependsOn: ["^build"], }); @@ -95,8 +95,8 @@ describe("workspace target graph builder", () => { enableTargetConfigMerging: false, enablePhantomTargetOptimization: false, }); - await builder.addTargetConfig("test"); - await builder.addTargetConfig("lint"); + builder.addTargetConfig("test"); + builder.addTargetConfig("lint"); const targetGraph = await builder.build(["test", "lint"]); @@ -124,11 +124,11 @@ describe("workspace target graph builder", () => { enablePhantomTargetOptimization: false, }); - await builder.addTargetConfig("build", { + builder.addTargetConfig("build", { dependsOn: ["^build"], }); - await builder.addTargetConfig("a#build", { + builder.addTargetConfig("a#build", { dependsOn: [], }); @@ -155,11 +155,11 @@ describe("workspace target graph builder", () => { enablePhantomTargetOptimization: false, }); - await builder.addTargetConfig("build", { + builder.addTargetConfig("build", { dependsOn: ["^build"], }); - await builder.addTargetConfig("a#build", { + builder.addTargetConfig("a#build", { dependsOn: [], }); @@ -184,11 +184,11 @@ describe("workspace target graph builder", () => { enablePhantomTargetOptimization: false, }); - await builder.addTargetConfig("bundle", { + builder.addTargetConfig("bundle", { dependsOn: ["^^transpile"], }); - await builder.addTargetConfig("transpile"); + builder.addTargetConfig("transpile"); const targetGraph = await builder.build(["bundle"], ["a"]); expect(getGraphFromTargets(targetGraph)).toEqual([ @@ -215,12 +215,12 @@ describe("workspace target graph builder", () => { enablePhantomTargetOptimization: false, }); - await builder.addTargetConfig("build", { + builder.addTargetConfig("build", { dependsOn: ["common#copy", "^build"], }); - await builder.addTargetConfig("common#copy"); - await builder.addTargetConfig("common#build"); + builder.addTargetConfig("common#copy"); + builder.addTargetConfig("common#build"); const targetGraph = await builder.build(["build"]); expect(getGraphFromTargets(targetGraph)).toEqual([ @@ -247,11 +247,11 @@ describe("workspace target graph builder", () => { enableTargetConfigMerging: false, enablePhantomTargetOptimization: false, }); - await builder.addTargetConfig("build", { + builder.addTargetConfig("build", { dependsOn: ["^build", "#global:task"], }); - await builder.addTargetConfig("#global:task", { + builder.addTargetConfig("#global:task", { dependsOn: [], }); @@ -279,11 +279,11 @@ describe("workspace target graph builder", () => { enableTargetConfigMerging: false, enablePhantomTargetOptimization: false, }); - await builder.addTargetConfig("build", { + builder.addTargetConfig("build", { dependsOn: ["^build", "#global:task"], }); - await builder.addTargetConfig("#global:task", { + builder.addTargetConfig("#global:task", { dependsOn: [], }); @@ -304,11 +304,11 @@ describe("workspace target graph builder", () => { enableTargetConfigMerging: false, enablePhantomTargetOptimization: false, }); - await builder.addTargetConfig("build", { + builder.addTargetConfig("build", { dependsOn: ["^build"], }); - await builder.addTargetConfig("#global:task", { + builder.addTargetConfig("#global:task", { dependsOn: [], }); @@ -334,11 +334,11 @@ describe("workspace target graph builder", () => { enableTargetConfigMerging: false, enablePhantomTargetOptimization: false, }); - await builder.addTargetConfig("transpile"); - await builder.addTargetConfig("emitDeclarations", { + builder.addTargetConfig("transpile"); + builder.addTargetConfig("emitDeclarations", { dependsOn: ["typecheck"], }); - await builder.addTargetConfig("typecheck", { + builder.addTargetConfig("typecheck", { dependsOn: ["^^emitDeclarations", "transpile", "^^transpile"], }); @@ -376,11 +376,11 @@ describe("workspace target graph builder", () => { enableTargetConfigMerging: false, enablePhantomTargetOptimization: true, }); - await builder.addTargetConfig("transpile"); - await builder.addTargetConfig("emitDeclarations", { + builder.addTargetConfig("transpile"); + builder.addTargetConfig("emitDeclarations", { dependsOn: ["typecheck"], }); - await builder.addTargetConfig("typecheck", { + builder.addTargetConfig("typecheck", { dependsOn: ["^^emitDeclarations", "transpile", "^^transpile"], }); @@ -414,7 +414,7 @@ describe("workspace target graph builder", () => { enableTargetConfigMerging: false, enablePhantomTargetOptimization: false, }); - await builder.addTargetConfig("build", { + builder.addTargetConfig("build", { dependsOn: ["^build"], }); @@ -444,10 +444,10 @@ describe("workspace target graph builder", () => { enableTargetConfigMerging: false, enablePhantomTargetOptimization: false, }); - await builder.addTargetConfig("customTask", { + builder.addTargetConfig("customTask", { type: "worker", }); - await builder.addTargetConfig("build", { + builder.addTargetConfig("build", { dependsOn: ["^^customTask"], }); diff --git a/packages/worker-threads-pool/src/ThreadWorker.ts b/packages/worker-threads-pool/src/ThreadWorker.ts index 8e6bc468a..cceb162af 100644 --- a/packages/worker-threads-pool/src/ThreadWorker.ts +++ b/packages/worker-threads-pool/src/ThreadWorker.ts @@ -112,7 +112,7 @@ export class ThreadWorker extends EventEmitter implements IWorker { 100; if (limit && data.memoryUsage > limit) { - void this.restart(); + this.restart(); } else { this.#ready(); } diff --git a/packages/worker-threads-pool/src/registerWorker.ts b/packages/worker-threads-pool/src/registerWorker.ts index 4a3dfc60c..2cd44f003 100644 --- a/packages/worker-threads-pool/src/registerWorker.ts +++ b/packages/worker-threads-pool/src/registerWorker.ts @@ -4,13 +4,13 @@ import { endMarker, startMarker } from "./stdioStreamMarkers.js"; import type { MessagePort } from "worker_threads"; export function registerWorker(fn: (data: any, abortSignal?: AbortSignal) => Promise | any): void { - parentPort?.on("message", async (message) => { + parentPort?.on("message", (message) => { let abortController: AbortController | undefined; switch (message.type) { case "start": abortController = new AbortController(); - return message.task && (await start(message.id, message.task, abortController.signal)); + return message.task && void start(message.id, message.task, abortController.signal); case "abort": return abortController?.abort(); diff --git a/scripts/config/eslintrc.js b/scripts/config/eslintrc.js index cdc2de2b4..f7a3b4164 100644 --- a/scripts/config/eslintrc.js +++ b/scripts/config/eslintrc.js @@ -41,7 +41,12 @@ const config = { "@typescript-eslint/no-require-imports": "error", "no-console": "error", "file-extension-in-import-ts/file-extension-in-import-ts": "error", + "@typescript-eslint/await-thenable": "error", "@typescript-eslint/no-floating-promises": "error", + "@typescript-eslint/no-misused-promises": "error", + "@typescript-eslint/require-await": "error", + // enable after eslint upgrade: + // "@typescript-eslint/return-await": ["error", "error-handling-correctness-only"], "@typescript-eslint/explicit-module-boundary-types": "error", "@typescript-eslint/no-unused-vars": [ "error", diff --git a/scripts/config/getDtsBundleConfig.js b/scripts/config/getDtsBundleConfig.js index 0b6254171..2f7d28fb6 100644 --- a/scripts/config/getDtsBundleConfig.js +++ b/scripts/config/getDtsBundleConfig.js @@ -34,6 +34,7 @@ function getDtsBundleConfig(params) { const outFile = path.resolve(packageRoot, params.outFile); // Use "once" because otherwise it will run again after the first run completes + // eslint-disable-next-line @typescript-eslint/no-misused-promises -- appears to allow async despite types process.once("beforeExit", async (code) => { if (!code) { console.log("Verifying no unexpected imports in bundled types"); diff --git a/scripts/worker/types.js b/scripts/worker/types.js index de4ca932f..9c39faac0 100644 --- a/scripts/worker/types.js +++ b/scripts/worker/types.js @@ -15,6 +15,7 @@ let oldProgram; * * @type {WorkerRunnerFunction} */ +// eslint-disable-next-line @typescript-eslint/require-await -- match type async function run(data) { const { target, taskArgs } = data;