From ecf172ba5225b1a18543c64cda7da9c3c2ac0b2c Mon Sep 17 00:00:00 2001 From: Joseph Frazier <1212jtraceur@gmail.com> Date: Mon, 17 Apr 2017 18:27:17 -0400 Subject: [PATCH] `pack`: include contents of directories in `files` field This makes it so that you don't have to put '/**' after a directory in the `files` field of package.json to ensure that the contents of the directory will be published. Fixes https://github.com/yarnpkg/yarn/issues/2498 Fixes https://github.com/yarnpkg/yarn/issues/2942 Fixes https://github.com/yarnpkg/yarn/issues/2851 Includes and closes https://github.com/yarnpkg/yarn/pull/3170 --- src/cli/commands/pack.js | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/src/cli/commands/pack.js b/src/cli/commands/pack.js index cce5180c91..19c854378f 100644 --- a/src/cli/commands/pack.js +++ b/src/cli/commands/pack.js @@ -76,12 +76,27 @@ export async function pack(config: Config, dir: string): Promise // `files` field if (onlyFiles) { + // Append '**' to directories in the `files` field. + // This ensures that their contents get included. + const onlyFilesGlobs = await Promise.all(onlyFiles.map(async (filename: string): Promise => { + try { + const loc = path.join(config.cwd, filename); + const stat = await fs.lstat(loc); + + if (stat.isDirectory()) { + return path.join(filename, '**'); + } + return filename; + } catch (err) { + return filename; + } + })); let lines = [ '*', // ignore all files except those that are explicitly included with a negation filter '.*', // files with "." as first character have to be excluded explicitly ]; lines = lines.concat( - onlyFiles.map((filename: string): string => `!${filename}`), + onlyFilesGlobs.map((filename: string): string => `!${filename}`), ); const regexes = ignoreLinesToRegex(lines, '.'); filters = filters.concat(regexes); @@ -115,7 +130,17 @@ export async function pack(config: Config, dir: string): Promise sortFilter(files, filters, keepFiles, possibleKeepFiles, ignoredFiles); const packer = tar.pack(config.cwd, { - ignore: (name) => !keepFiles.has(path.relative(config.cwd, name)), + ignore: (name) => { + const relative = path.relative(config.cwd, name); + // Don't ignore directories, since we need to recurse inside them to check for unignored files. + if (fs2.lstatSync(name).isDirectory()) { + const isParentOfKeptFile = Array.from(keepFiles).some((name) => + !path.relative(relative, name).startsWith('..')); + return !isParentOfKeptFile; + } + // Otherwise, ignore a file if we're not supposed to keep it. + return !keepFiles.has(relative); + }, map: (header) => { const suffix = header.name === '.' ? '' : `/${header.name}`; header.name = `package${suffix}`;