1*09bb6093SEvan Baconimport path from 'path'; 2*09bb6093SEvan Baconimport resolveFrom from 'resolve-from'; 3*09bb6093SEvan Bacon 4*09bb6093SEvan Baconimport { CommandError } from '../utils/errors'; 5*09bb6093SEvan Bacon 6*09bb6093SEvan Bacon/** Look up directories until one with a `package.json` can be found, assert if none can be found. */ 7*09bb6093SEvan Baconexport function findUpProjectRootOrAssert(cwd: string): string { 8*09bb6093SEvan Bacon const projectRoot = findUpProjectRoot(cwd); 9*09bb6093SEvan Bacon if (!projectRoot) { 10*09bb6093SEvan Bacon throw new CommandError(`Project root directory not found (working directory: ${cwd})`); 11*09bb6093SEvan Bacon } 12*09bb6093SEvan Bacon return projectRoot; 13*09bb6093SEvan Bacon} 14*09bb6093SEvan Bacon 15*09bb6093SEvan Baconfunction findUpProjectRoot(cwd: string): string | null { 16*09bb6093SEvan Bacon if (['.', path.sep].includes(cwd)) return null; 17*09bb6093SEvan Bacon 18*09bb6093SEvan Bacon const found = resolveFrom.silent(cwd, './package.json'); 19*09bb6093SEvan Bacon if (found) { 20*09bb6093SEvan Bacon return path.dirname(found); 21*09bb6093SEvan Bacon } 22*09bb6093SEvan Bacon return findUpProjectRoot(path.dirname(cwd)); 23*09bb6093SEvan Bacon} 24