diff --git a/packages/cli/package.json b/packages/cli/package.json index 250aa5f796..f6fdaf8e5d 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -29,6 +29,7 @@ "backstage-cli": "bin/backstage-cli" }, "dependencies": { + "@backstage/cli-common": "^0.1.1-alpha.16", "@backstage/config": "^0.1.1-alpha.16", "@backstage/config-loader": "^0.1.1-alpha.16", "@hot-loader/react-dom": "^16.13.0", diff --git a/packages/cli/src/lib/paths.ts b/packages/cli/src/lib/paths.ts index ab3578ca1c..06c8f2ab38 100644 --- a/packages/cli/src/lib/paths.ts +++ b/packages/cli/src/lib/paths.ts @@ -14,135 +14,6 @@ * limitations under the License. */ -import fs from 'fs-extra'; -import { dirname, resolve as resolvePath } from 'path'; +import { findPaths } from '@backstage/cli-common'; -export type ResolveFunc = (...paths: string[]) => string; - -// Common paths and resolve functions used by the cli. -// Currently assumes it is being executed within a monorepo. -export type Paths = { - // Root dir of the cli itself, containing package.json - ownDir: string; - - // Monorepo root dir of the cli itself. Only accessible when running inside Backstage repo. - ownRoot: string; - - // The location of the app that the cli is being executed in - targetDir: string; - - // The monorepo root package of the app that the cli is being executed in. - targetRoot: string; - - // Resolve a path relative to own repo - resolveOwn: ResolveFunc; - - // Resolve a path relative to own monorepo root. Only accessible when running inside Backstage repo. - resolveOwnRoot: ResolveFunc; - - // Resolve a path relative to the app - resolveTarget: ResolveFunc; - - // Resolve a path relative to the app repo root - resolveTargetRoot: ResolveFunc; -}; - -// Looks for a package.json with a workspace config to identify the root of the monorepo -export function findRootPath(topPath: string): string { - let path = topPath; - - // Some sanity check to avoid infinite loop - for (let i = 0; i < 1000; i++) { - const packagePath = resolvePath(path, 'package.json'); - const exists = fs.pathExistsSync(packagePath); - if (exists) { - try { - const data = fs.readJsonSync(packagePath); - if (data.workspaces?.packages) { - return path; - } - } catch (error) { - throw new Error( - `Failed to parse package.json file while searching for root, ${error}`, - ); - } - } - - const newPath = dirname(path); - if (newPath === path) { - return topPath; // We didn't find any root package.json, assume we're not in a monorepo - } - path = newPath; - } - - throw new Error( - `Iteration limit reached when searching for root package.json at ${topPath}`, - ); -} - -// Finds the root of the cli package itself -export function findOwnDir() { - // Known relative locations of package in dist/dev - const pathDist = '..'; - const pathDev = '../..'; - - // Check the closest dir first - const pkgInDist = resolvePath(__dirname, pathDist, 'package.json'); - const isDist = fs.pathExistsSync(pkgInDist); - - const path = isDist ? pathDist : pathDev; - return resolvePath(__dirname, path); -} - -// Finds the root of the monorepo that the cli exists in. Only accessible when running inside Backstage repo. -export function findOwnRootPath(ownDir: string) { - const isLocal = fs.pathExistsSync(resolvePath(ownDir, 'src')); - if (!isLocal) { - throw new Error( - 'Tried to access monorepo package root dir outside of Backstage repository', - ); - } - - return resolvePath(ownDir, '../..'); -} - -export function findPaths(): Paths { - const ownDir = findOwnDir(); - const targetDir = fs.realpathSync(process.cwd()); - - // Lazy load this as it will throw an error if we're not inside the Backstage repo. - let ownRoot = ''; - const getOwnRoot = () => { - if (!ownRoot) { - ownRoot = findOwnRootPath(ownDir); - } - return ownRoot; - }; - - // We're not always running in a monorepo, so we lazy init this to only crash commands - // that require a monorepo when we're not in one. - let targetRoot = ''; - const getTargetRoot = () => { - if (!targetRoot) { - targetRoot = findRootPath(targetDir); - } - return targetRoot; - }; - - return { - ownDir, - get ownRoot() { - return getOwnRoot(); - }, - targetDir, - get targetRoot() { - return getTargetRoot(); - }, - resolveOwn: (...paths) => resolvePath(ownDir, ...paths), - resolveOwnRoot: (...paths) => resolvePath(getOwnRoot(), ...paths), - resolveTarget: (...paths) => resolvePath(targetDir, ...paths), - resolveTargetRoot: (...paths) => resolvePath(getTargetRoot(), ...paths), - }; -} - -export const paths = findPaths(); +export const paths = findPaths(__dirname);