From a0432bbb5a16776385887e0ae4118b0e3f193d37 Mon Sep 17 00:00:00 2001 From: nlf Date: Wed, 18 May 2022 15:34:47 -0700 Subject: [PATCH] fix: do not pack workspaces by default --- lib/index.js | 30 ++++++++++++------- test/workspace.js | 74 +++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 89 insertions(+), 15 deletions(-) diff --git a/lib/index.js b/lib/index.js index a894655..cbbe4d0 100644 --- a/lib/index.js +++ b/lib/index.js @@ -149,16 +149,26 @@ class Walker extends IgnoreWalker { this.packageJsonCache = this.parent ? this.parent.packageJsonCache : (opt.packageJsonCache || new Map()) let rules = defaultRules.join('\n') + '\n' - // if opt.path and opt.prefix are not the same directory, and opt.workspaces has opt.path - // in it, then we know that opt.path is a workspace directory. in order to not drop ignore - // rules from directories between the workspace root (opt.prefix) and the workspace itself - // (opt.path), we need to find and read those now - if (opt.prefix && opt.path !== opt.prefix && - opt.workspaces && opt.workspaces.includes(opt.path)) { - // relpath is the relative path between the prefix and the parent of opt.path - // we use the parent because ignore-walk will read the files in opt.path already - const relpath = path.relative(opt.prefix, path.dirname(opt.path)) - rules += readOutOfTreeIgnoreFiles(opt.prefix, relpath) + + if (opt.prefix && opt.workspaces) { + const gPath = globify(opt.path) + const gPrefix = globify(opt.prefix) + const gWorkspaces = opt.workspaces.map((ws) => globify(ws)) + // if opt.path and opt.prefix are not the same directory, and opt.workspaces has opt.path + // in it, then we know that opt.path is a workspace directory. in order to not drop ignore + // rules from directories between the workspace root (opt.prefix) and the workspace itself + // (opt.path), we need to find and read those now + /* istanbul ignore else */ + if (gPath !== gPrefix && gWorkspaces.includes(opt.path)) { + // relpath is the relative path between the prefix and the parent of opt.path + // we use the parent because ignore-walk will read the files in opt.path already + const relpath = path.relative(opt.prefix, path.dirname(opt.path)) + rules += readOutOfTreeIgnoreFiles(opt.prefix, relpath) + } else if (gPath === gPrefix) { + // on the other hand, if the path and the prefix are the same, then we ignore workspaces + // so that we don't pack workspaces inside of a root project + rules += opt.workspaces.map((ws) => globify(path.relative(opt.path, ws))).join('\n') + } } super.onReadIgnoreFile(rootBuiltinRules, rules, _ => _) diff --git a/test/workspace.js b/test/workspace.js index b29c35b..d32b8b5 100644 --- a/test/workspace.js +++ b/test/workspace.js @@ -10,10 +10,10 @@ t.test('respects workspace root ignore files', async (t) => { 'package.json': JSON.stringify({ name: 'workspace-root', version: '1.0.0', - main: 'index.js', + main: 'root.js', workspaces: ['./workspaces/foo'], }), - 'index.js': `console.log('hello')`, + 'root.js': `console.log('hello')`, '.gitignore': 'ignore-me', 'ignore-me': 'should be ignored', workspaces: { @@ -24,9 +24,9 @@ t.test('respects workspace root ignore files', async (t) => { 'package.json': JSON.stringify({ name: 'workspace-child', version: '1.0.0', - main: 'index.js', + main: 'child.js', }), - 'index.js': `console.log('hello')`, + 'child.js': `console.log('hello')`, 'ignore-me': 'should be ignored', 'ignore-me-also': 'should also be ignored', }, @@ -41,7 +41,71 @@ t.test('respects workspace root ignore files', async (t) => { workspaces: [workspacePath], }) t.same(files, [ - 'index.js', + 'child.js', 'package.json', ]) + + // here we leave off workspaces to satisfy coverage + const secondFiles = await packlist({ + path: workspacePath, + prefix: root, + }) + t.same(secondFiles, [ + 'ignore-me', + 'ignore-me-also', + 'child.js', + 'package.json', + ]) +}) + +t.test('packing a workspace root does not include children', async (t) => { + const root = t.testdir({ + 'package.json': JSON.stringify({ + name: 'workspace-root', + version: '1.0.0', + main: 'root.js', + workspaces: ['./workspaces/foo'], + }), + 'root.js': `console.log('hello')`, + '.gitignore': 'ignore-me', + 'ignore-me': 'should be ignored', + workspaces: { + '.gitignore': 'ignore-me-also', + 'ignore-me': 'should be ignored', + 'ignore-me-also': 'should also be ignored', + foo: { + 'package.json': JSON.stringify({ + name: 'workspace-child', + version: '1.0.0', + main: 'child.js', + }), + 'child.js': `console.log('hello')`, + 'ignore-me': 'should be ignored', + 'ignore-me-also': 'should also be ignored', + }, + }, + }) + + const workspacePath = path.join(root, 'workspaces', 'foo') + // this simulates what it looks like when a user does i.e. npm pack from a workspace root + const files = await packlist({ + path: root, + prefix: root, + workspaces: [workspacePath], + }) + t.same(files, [ + 'root.js', + 'package.json', + ]) + + const secondFiles = await packlist({ + path: root, + prefix: root, + }) + t.same(secondFiles, [ + 'workspaces/foo/child.js', + 'root.js', + 'package.json', + 'workspaces/foo/package.json', + ]) })