@@ -33,6 +33,33 @@ const fs = require('fs')
3333const  glob  =  require ( 'glob' ) 
3434const  globify  =  pattern  =>  pattern . split ( '\\' ) . join ( '/' ) 
3535
36+ const  readOutOfTreeIgnoreFiles  =  ( root ,  rel ,  result  =  '' )  =>  { 
37+   for  ( const  file  of  [ '.gitignore' ,  '.npmignore' ] )  { 
38+     try  { 
39+       const  ignoreContent  =  fs . readFileSync ( path . join ( root ,  file ) ,  {  encoding : 'utf8'  } ) 
40+       result  +=  ignoreContent  +  '\n' 
41+     }  catch  ( err )  { 
42+       // we ignore ENOENT errors completely because we don't care if the file doesn't exist 
43+       // but we throw everything else because failing to read a file that does exist is 
44+       // something that the user likely wants to know about. we don't need to test this. 
45+       /* istanbul ignore next */ 
46+       if  ( err . code  !==  'ENOENT' )  { 
47+         throw  err 
48+       } 
49+     } 
50+   } 
51+ 
52+   if  ( ! rel )  { 
53+     return  result 
54+   } 
55+ 
56+   const  firstRel  =  rel . split ( path . sep ) [ 0 ] 
57+   const  newRoot  =  path . join ( root ,  firstRel ) 
58+   const  newRel  =  path . relative ( newRoot ,  path . join ( root ,  rel ) ) 
59+ 
60+   return  readOutOfTreeIgnoreFiles ( newRoot ,  newRel ,  result ) 
61+ } 
62+ 
3663const  pathHasPkg  =  ( input )  =>  { 
3764  if  ( ! input . startsWith ( 'node_modules/' ) )  { 
3865    return  false 
@@ -119,9 +146,31 @@ class Walker extends IgnoreWalker {
119146      this . bundledScopes  =  Array . from ( new  Set ( 
120147        this . bundled . filter ( f  =>  / ^ @ / . test ( f ) ) 
121148          . map ( f  =>  f . split ( '/' ) [ 0 ] ) ) ) 
122-       const  rules  =  defaultRules . join ( '\n' )  +  '\n' 
123149      this . packageJsonCache  =  this . parent  ? this . parent . packageJsonCache 
124150        : ( opt . packageJsonCache  ||  new  Map ( ) ) 
151+       let  rules  =  defaultRules . join ( '\n' )  +  '\n' 
152+ 
153+       if  ( opt . prefix  &&  opt . workspaces )  { 
154+         const  gPath  =  globify ( opt . path ) 
155+         const  gPrefix  =  globify ( opt . prefix ) 
156+         const  gWorkspaces  =  opt . workspaces . map ( ( ws )  =>  globify ( ws ) ) 
157+         // if opt.path and opt.prefix are not the same directory, and opt.workspaces has opt.path 
158+         // in it, then we know that opt.path is a workspace directory. in order to not drop ignore 
159+         // rules from directories between the workspace root (opt.prefix) and the workspace itself 
160+         // (opt.path), we need to find and read those now 
161+         /* istanbul ignore else */ 
162+         if  ( gPath  !==  gPrefix  &&  gWorkspaces . includes ( gPath ) )  { 
163+           // relpath is the relative path between the prefix and the parent of opt.path 
164+           // we use the parent because ignore-walk will read the files in opt.path already 
165+           const  relpath  =  path . relative ( opt . prefix ,  path . dirname ( opt . path ) ) 
166+           rules  +=  readOutOfTreeIgnoreFiles ( opt . prefix ,  relpath ) 
167+         }  else  if  ( gPath  ===  gPrefix )  { 
168+           // on the other hand, if the path and the prefix are the same, then we ignore workspaces 
169+           // so that we don't pack workspaces inside of a root project 
170+           rules  +=  opt . workspaces . map ( ( ws )  =>  globify ( path . relative ( opt . path ,  ws ) ) ) . join ( '\n' ) 
171+         } 
172+       } 
173+ 
125174      super . onReadIgnoreFile ( rootBuiltinRules ,  rules ,  _  =>  _ ) 
126175    }  else  { 
127176      this . bundled  =  [ ] 
0 commit comments