From 1fac4f6028b7b790cfcd978c76394dc5b39f19f7 Mon Sep 17 00:00:00 2001 From: Daniel Oakman <141111365+danoaky-tiny@users.noreply.github.com> Date: Thu, 7 Mar 2024 10:03:13 +1100 Subject: [PATCH] TINY-10688: Support using `pnpm-workspace.yaml` (#141) * TINY-10688: Call `pnpm list` if `pnpm-workspace.yaml` exists to fetch workspace roots * TINY-10688: Added `WorkspaceRoot` interface * TINY-10688: Added changelog * TINY-10688: Use a `for of` instead of iterating twice in a `map().filter()` * TINY-10688: Just print `stderr` * TINY-10688: Added missing ticket number to changelog entry --- CHANGELOG.md | 3 ++ .../main/ts/bedrock/server/RunnerRoutes.ts | 36 +++++++++++++++++-- 2 files changed, 36 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 765351ab..60c524d3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +### Improved +- Now supports using `pnpm-workspace.yaml` to fetch workspaces #TINY-10688 + ## 14.1.2 - 2024-01-31 ### Fixed diff --git a/modules/server/src/main/ts/bedrock/server/RunnerRoutes.ts b/modules/server/src/main/ts/bedrock/server/RunnerRoutes.ts index 447c5d10..0d8c47d2 100644 --- a/modules/server/src/main/ts/bedrock/server/RunnerRoutes.ts +++ b/modules/server/src/main/ts/bedrock/server/RunnerRoutes.ts @@ -1,5 +1,6 @@ import * as path from 'path'; import * as fs from 'fs'; +import * as childProcess from 'child_process'; import * as glob from 'glob'; import * as Routes from './Routes'; import * as Compiler from '../compiler/Compiler'; @@ -11,6 +12,11 @@ interface PackageJson { readonly workspaces: string[]; } +interface WorkspaceRoot { + name: string; + folder: string; +} + export const generate = async (mode: string, projectdir: string, basedir: string, configFile: string, bundler: 'webpack' | 'rollup', testfiles: string[], chunk: number, retries: number, singleTimeout: number, stopOnFailure: boolean, basePage: string, coverage: string[], polyfills: string[]): Promise => { const files = testfiles.map((filePath) => { @@ -31,7 +37,7 @@ export const generate = async (mode: string, projectdir: string, basedir: string const pkjson: PackageJson = FileUtils.readFileAsJson(`${projectdir}/package.json`); // Search for yarn workspace projects to use as resource folders - const findWorkspaceResources = (moduleFolder: string): Array<{name: string; folder: string}> => { + const findWorkspaceResources = (moduleFolder: string): Array => { const moduleJson = `${moduleFolder}/package.json`; if (fs.statSync(moduleJson)) { const workspaceJson = FileUtils.readFileAsJson(moduleJson); @@ -41,10 +47,34 @@ export const generate = async (mode: string, projectdir: string, basedir: string } }; - const workspaceRoots = ( + const findPnpmWorkspaces = async (): Promise => { + if (!fs.existsSync(path.join(projectdir, 'pnpm-workspace.yaml'))) { + return []; + } + + return new Promise((resolve, reject) => + childProcess.exec('pnpm list -r --only-projects --json', (err, stdout, stderr) => { + if (stderr) console.error(stderr); + if (err) { + reject(err); + return; + } + + const result: WorkspaceRoot[] = []; + for (const p of JSON.parse(stdout) as { name: string; path: string }[]) { + const folder = path.relative(projectdir, p.path); + if (!folder.length) continue; + result.push({ name: p.name, folder }); + } + resolve(result); + }) + ); + }; + + const workspaceRoots: WorkspaceRoot[] = ( pkjson.workspaces ? Arr.bind2(pkjson.workspaces, (w) => glob.sync(w), findWorkspaceResources) - : [] + : await findPnpmWorkspaces() ); const resourceRoots = [{name: pkjson.name, folder: '.'}].concat(workspaceRoots);