mirror of
https://github.com/LukeHagar/vercel.git
synced 2025-12-09 12:57:46 +00:00
[build-utils] Add getNodeBinPaths() function (#10150)
The `getNodeBinPath()` function is problematic because it assumes that commands are installed in the `node_modules` directory alongside the detected lockfile. This works fine the majority of the time, but ends up not being the case when using a monorepo that uses a package manager in "linked" mode (i.e. pnpm by default). Consider the following: ``` . ├── pnpm-lock.yaml ├── node_modules ├── blog │ ├── node_modules │ │ ├── hexo -> .pnpm/hexo@3.9.0/node_modules/hexo ``` In this setup, adding the root-level `node_modules/.bin` would not make the `hexo` command be visible in the `$PATH`. To solve this issue, the new `getNodeBinPaths()` function returns an array of all directories up to the specified `root`, which can then be placed into the `$PATH`. It's also more efficient (synchronous) since it does not need to scan for a lockfile anymore (the `root` needs to be specified explicitly). The new function is being used in `@vercel/next` and `@vercel/static-build`. The `traverseUpDirectories()` function from CLI was moved to `build-utils` to implement this function. Consequently, that makes the implementations of `walkParentDirs()` and `walkParentDirsMulti()` simpler, since it's using this generator now.
This commit is contained in:
@@ -2,7 +2,7 @@ import chalk from 'chalk';
|
||||
import pluralize from 'pluralize';
|
||||
import { homedir } from 'os';
|
||||
import { join, normalize } from 'path';
|
||||
import { normalizePath } from '@vercel/build-utils';
|
||||
import { normalizePath, traverseUpDirectories } from '@vercel/build-utils';
|
||||
import { lstat, readJSON, outputJSON } from 'fs-extra';
|
||||
import confirm from '../input/confirm';
|
||||
import toHumanPath from '../humanize-path';
|
||||
@@ -229,7 +229,7 @@ export async function findRepoRoot(
|
||||
const REPO_JSON_PATH = join(VERCEL_DIR, VERCEL_DIR_REPO);
|
||||
const GIT_CONFIG_PATH = normalize('.git/config');
|
||||
|
||||
for (const current of traverseUpDirectories(start)) {
|
||||
for (const current of traverseUpDirectories({ start })) {
|
||||
if (current === home) {
|
||||
// Sometimes the $HOME directory is set up as a Git repo
|
||||
// (for dotfiles, etc.). In this case it's safe to say that
|
||||
@@ -264,16 +264,6 @@ export async function findRepoRoot(
|
||||
debug('Aborting search for repo root');
|
||||
}
|
||||
|
||||
export function* traverseUpDirectories(start: string) {
|
||||
let current: string | undefined = normalize(start);
|
||||
while (current) {
|
||||
yield current;
|
||||
// Go up one directory
|
||||
const next = join(current, '..');
|
||||
current = next === current ? undefined : next;
|
||||
}
|
||||
}
|
||||
|
||||
function sortByDirectory(a: RepoProjectConfig, b: RepoProjectConfig): number {
|
||||
const aParts = a.directory.split('/');
|
||||
const bParts = b.directory.split('/');
|
||||
|
||||
@@ -4,12 +4,9 @@ import {
|
||||
findProjectsFromPath,
|
||||
findRepoRoot,
|
||||
RepoProjectConfig,
|
||||
traverseUpDirectories,
|
||||
} from '../../../../src/util/link/repo';
|
||||
import { client } from '../../../mocks/client';
|
||||
|
||||
const isWindows = process.platform === 'win32';
|
||||
|
||||
// Root of `vercel/vercel` repo
|
||||
const vercelRepoRoot = join(__dirname, '../../../../../..');
|
||||
|
||||
@@ -30,34 +27,6 @@ describe('findRepoRoot()', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('traverseUpDirectories()', () => {
|
||||
test.each(
|
||||
isWindows
|
||||
? [
|
||||
{
|
||||
input: 'C:\\foo\\bar\\baz',
|
||||
expected: ['C:\\foo\\bar\\baz', 'C:\\foo\\bar', 'C:\\foo', 'C:\\'],
|
||||
},
|
||||
{
|
||||
input: 'C:\\foo\\..\\bar\\.\\baz',
|
||||
expected: ['C:\\bar\\baz', 'C:\\bar', 'C:\\'],
|
||||
},
|
||||
]
|
||||
: [
|
||||
{
|
||||
input: '/foo/bar/baz',
|
||||
expected: ['/foo/bar/baz', '/foo/bar', '/foo', '/'],
|
||||
},
|
||||
{
|
||||
input: '/foo/../bar/./baz',
|
||||
expected: ['/bar/baz', '/bar', '/'],
|
||||
},
|
||||
]
|
||||
)('should traverse "$input"', ({ input, expected }) => {
|
||||
expect(Array.from(traverseUpDirectories(input))).toEqual(expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('findProjectsFromPath()', () => {
|
||||
const projects: RepoProjectConfig[] = [
|
||||
{ id: 'root', name: 'r', directory: '.' },
|
||||
|
||||
Reference in New Issue
Block a user