@@ -11,23 +11,26 @@ const execa = require('execa');
1111const fs = require ( 'fs-extra' ) ;
1212const glob = require ( 'fast-glob' ) ;
1313const path = require ( 'path' ) ;
14- const packageJson = require ( '../../../package.json' ) ;
15-
16- const WORKSPACE_ROOT = path . resolve ( __dirname , '../../../' ) ;
17- const packagePaths = glob
18- . sync ( packageJson . workspaces . map ( ( pattern ) => `${ pattern } /package.json` ) )
19- . map ( ( match ) => {
20- const packageJsonPath = path . join ( WORKSPACE_ROOT , match ) ;
21- return {
22- packageJsonPath,
23- packageJson : fs . readJsonSync ( packageJsonPath ) ,
24- packagePath : path . dirname ( packageJsonPath ) ,
25- packageFolder : path . relative (
26- WORKSPACE_ROOT ,
27- path . dirname ( packageJsonPath )
28- ) ,
29- } ;
30- } ) ;
14+
15+ const { root : ROOT_DIR } = path . parse ( __dirname ) ;
16+ const WORKSPACE_ROOT = getProjectRoot ( __dirname ) ;
17+ const packageJson = fs . readJsonSync ( path . join ( WORKSPACE_ROOT , 'package.json' ) ) ;
18+ const packagePaths = Array . isArray ( packageJson . workspaces )
19+ ? glob
20+ . sync ( packageJson . workspaces . map ( ( pattern ) => `${ pattern } /package.json` ) )
21+ . map ( ( match ) => {
22+ const packageJsonPath = path . join ( WORKSPACE_ROOT , match ) ;
23+ return {
24+ packageJsonPath,
25+ packageJson : fs . readJsonSync ( packageJsonPath ) ,
26+ packagePath : path . dirname ( packageJsonPath ) ,
27+ packageFolder : path . relative (
28+ WORKSPACE_ROOT ,
29+ path . dirname ( packageJsonPath )
30+ ) ,
31+ } ;
32+ } )
33+ : [ ] ;
3134
3235const env = {
3336 root : {
@@ -54,6 +57,53 @@ async function getPackages() {
5457 return JSON . parse ( lernaListOutput ) . filter ( ( pkg ) => ! pkg . private ) ;
5558}
5659
60+ /**
61+ * Returns the root directory of a project, either as a workspace root with a
62+ * collection of packages or a single project with a `package.json`
63+ * @param {string } directory
64+ * @returns {string }
65+ */
66+ function getProjectRoot ( directory ) {
67+ const packageJsonPaths = ancestors ( directory ) . filter ( ( directory ) => {
68+ return fs . existsSync ( path . join ( directory , 'package.json' ) ) ;
69+ } ) ;
70+
71+ const rootDirectory =
72+ packageJsonPaths . length > 0
73+ ? packageJsonPaths [ packageJsonPaths . length - 1 ]
74+ : null ;
75+
76+ if ( ! rootDirectory ) {
77+ throw new Error (
78+ `Unable to find a \`package.json\` file from directory: ${ directory } `
79+ ) ;
80+ }
81+
82+ return rootDirectory ;
83+ }
84+
85+ /**
86+ * Returns an array of the the directory and its ancestors
87+ * @param {string } directory
88+ * @returns {Array<string> }
89+ */
90+ function ancestors ( directory ) {
91+ const result = [ directory ] ;
92+ let current = directory ;
93+
94+ while ( current !== '' ) {
95+ result . push ( current ) ;
96+
97+ if ( current !== ROOT_DIR ) {
98+ current = path . dirname ( current ) ;
99+ } else {
100+ current = '' ;
101+ }
102+ }
103+
104+ return result ;
105+ }
106+
57107module . exports = {
58108 workspace,
59109 getPackages,
0 commit comments