diff options
| author | 2023-04-28 01:36:44 +0800 | |
|---|---|---|
| committer | 2023-04-28 01:36:44 +0800 | |
| commit | dd84b9d64fb98746a230cd24233ff50a562c39c9 (patch) | |
| tree | b583261ef00b3afe72ec4d6dacb31e57779a6faf /packages/turbo-utils/src/getTurboConfigs.ts | |
| parent | 0b46fcd72ac34382387b2bcf9095233efbcc52f4 (diff) | |
| download | HydroRoll-dd84b9d64fb98746a230cd24233ff50a562c39c9.tar.gz HydroRoll-dd84b9d64fb98746a230cd24233ff50a562c39c9.zip | |
Diffstat (limited to 'packages/turbo-utils/src/getTurboConfigs.ts')
| -rw-r--r-- | packages/turbo-utils/src/getTurboConfigs.ts | 106 |
1 files changed, 106 insertions, 0 deletions
diff --git a/packages/turbo-utils/src/getTurboConfigs.ts b/packages/turbo-utils/src/getTurboConfigs.ts new file mode 100644 index 0000000..df15a56 --- /dev/null +++ b/packages/turbo-utils/src/getTurboConfigs.ts @@ -0,0 +1,106 @@ +import fs from "fs"; +import path from "path"; +import getTurboRoot from "./getTurboRoot"; +import yaml from "js-yaml"; +import { sync } from "fast-glob"; +import { Schema } from "@turbo/types"; +import JSON5 from "json5"; + +const ROOT_GLOB = "turbo.json"; + +export type TurboConfigs = Array<{ + config: Schema; + turboConfigPath: string; + workspacePath: string; + isRootConfig: boolean; +}>; + +interface Options { + cache?: boolean; +} + +const configsCache: Record<string, TurboConfigs> = {}; + +// A quick and dirty workspace parser +// TODO: after @turbo/workspace-convert is merged, we can leverage those utils here +function getWorkspaceGlobs(root: string): Array<string> { + try { + if (fs.existsSync(path.join(root, "pnpm-workspace.yaml"))) { + const workspaceConfig = yaml.load( + fs.readFileSync(path.join(root, "pnpm-workspace.yaml"), "utf8") + ) as Record<"packages", Array<string>>; + + return workspaceConfig?.packages || []; + } else { + const packageJson = JSON.parse( + fs.readFileSync(path.join(root, "package.json"), "utf8") + ); + return packageJson?.workspaces || []; + } + } catch (e) { + return []; + } +} + +function getTurboConfigs(cwd?: string, opts?: Options): TurboConfigs { + const turboRoot = getTurboRoot(cwd, opts); + const configs: TurboConfigs = []; + + const cacheEnabled = opts?.cache ?? true; + if (cacheEnabled && cwd && configsCache[cwd]) { + return configsCache[cwd]; + } + + // parse workspaces + if (turboRoot) { + const workspaceGlobs = getWorkspaceGlobs(turboRoot); + const workspaceConfigGlobs = workspaceGlobs.map( + (glob) => `${glob}/turbo.json` + ); + + const configPaths = sync([ROOT_GLOB, ...workspaceConfigGlobs], { + cwd: turboRoot, + onlyFiles: true, + followSymbolicLinks: false, + // avoid throwing when encountering permission errors or unreadable paths + suppressErrors: true, + }).map((configPath) => path.join(turboRoot, configPath)); + + configPaths.forEach((configPath) => { + try { + const raw = fs.readFileSync(configPath, "utf8"); + const turboJsonContent: Schema = JSON5.parse(raw); + // basic config validation + let isRootConfig = path.dirname(configPath) === turboRoot; + if (isRootConfig) { + // invalid - root config with extends + if ("extends" in turboJsonContent) { + return; + } + } else { + // invalid - workspace config with no extends + if (!("extends" in turboJsonContent)) { + return; + } + } + configs.push({ + config: turboJsonContent, + turboConfigPath: configPath, + workspacePath: path.dirname(configPath), + isRootConfig, + }); + } catch (e) { + // if we can't read or parse the config, just ignore it with a warning + console.warn(e); + } + }); + } + + if (cacheEnabled && cwd) { + configsCache[cwd] = configs; + } + + return configs; +} + +export default getTurboConfigs; |
