From f7473d8ba3cb3c5f1e637bbdab49f67e6f534d6d Mon Sep 17 00:00:00 2001 From: Bunyanuch Saengnet Date: Sat, 14 Sep 2019 06:55:56 +0000 Subject: [PATCH 01/33] retrieve the files, which were added since the last release --- source/git-util.js | 6 ++++++ source/npm/util.js | 15 +++++++++++++++ source/util.js | 14 ++++++++++++++ 3 files changed, 35 insertions(+) diff --git a/source/git-util.js b/source/git-util.js index 9f9b4142..74d4d7f1 100644 --- a/source/git-util.js +++ b/source/git-util.js @@ -2,12 +2,18 @@ const execa = require('execa'); const escapeStringRegexp = require('escape-string-regexp'); const {verifyRequirementSatisfied} = require('./version'); +const {splitFileNameList} = require('util'); exports.latestTag = async () => { const {stdout} = await execa('git', ['describe', '--abbrev=0', '--tags']); return stdout; }; +exports.newFilesSinceLastRelease = async () => { + const {stdout} = await execa('git', ['diff','--stat', '--diff-filter=A', await latestTag(), 'HEAD']); + return splitFileNameList(stdout); +}; + const firstCommit = async () => { const {stdout} = await execa('git', ['rev-list', '--max-parents=0', 'HEAD']); return stdout; diff --git a/source/npm/util.js b/source/npm/util.js index 21a550ae..7b67ac23 100644 --- a/source/npm/util.js +++ b/source/npm/util.js @@ -107,3 +107,18 @@ exports.checkIgnoreStrategy = ({files}) => { `); } }; + +//new files added part of .npmignore or part of files +exports.checkNewFiles = ({files}, newFiles) => { + +} + +const isIgnoredByDotnpmIgnore = (file) => { + const roorDir = pkgDir.sync(); + fs.readFileSync(path.resolve(rootDir, '.npmignore'), +}; + +const isPartOfFileProperty = (file, fileProperty) => { + +}; + diff --git a/source/util.js b/source/util.js index 264312bd..71c3591f 100644 --- a/source/util.js +++ b/source/util.js @@ -63,3 +63,17 @@ exports.getTagVersionPrefix = pMemoize(async options => { return 'v'; } }); + +exports.splitFileNameList(stdout) => { + + if(typeof stdout !== 'string') + throw new TypeError('expected parameter stdout of type string'); + + const rows = stdout.trim().split(); + let result = new Array(rows.length); + for(let i=0;i Date: Sat, 21 Sep 2019 13:39:28 +0000 Subject: [PATCH 02/33] Checks for new files added since the last release implemented --- package.json | 2 + source/git-util.js | 5 +- source/npm/util.js | 62 +++++++++++++++--- source/util.js | 17 +++-- test/.npmignore.js.swp | Bin 0 -> 12288 bytes test/npmignore.js | 41 ++++++++++++ test/ressources/npmignore/.npmignore | 1 + test/ressources/npmignore/source/ignore.txt | 1 + .../npmignore/source/pay_attention.txt | 1 + test/ressources/package/package.json | 3 + test/ressources/package/source/ignore.txt | 1 + .../package/source/pay_attention.txt | 1 + test/ressources/readme.md | 2 + 13 files changed, 119 insertions(+), 18 deletions(-) create mode 100644 test/.npmignore.js.swp create mode 100644 test/npmignore.js create mode 100644 test/ressources/npmignore/.npmignore create mode 100644 test/ressources/npmignore/source/ignore.txt create mode 100644 test/ressources/npmignore/source/pay_attention.txt create mode 100644 test/ressources/package/package.json create mode 100644 test/ressources/package/source/ignore.txt create mode 100644 test/ressources/package/source/pay_attention.txt create mode 100644 test/ressources/readme.md diff --git a/package.json b/package.json index b522f309..948e29a4 100644 --- a/package.json +++ b/package.json @@ -40,6 +40,7 @@ "github-url-from-git": "^1.5.0", "has-yarn": "^2.1.0", "hosted-git-info": "^2.7.1", + "ignore-walk": "^3.0.2", "inquirer": "^6.4.1", "is-installed-globally": "^0.2.0", "is-scoped": "^2.1.0", @@ -66,6 +67,7 @@ "devDependencies": { "ava": "^2.1.0", "proxyquire": "^2.1.0", + "mockery": "^2.1.0", "sinon": "^7.3.2", "xo": "^0.24.0" } diff --git a/source/git-util.js b/source/git-util.js index 74d4d7f1..bc0f51d0 100644 --- a/source/git-util.js +++ b/source/git-util.js @@ -2,7 +2,6 @@ const execa = require('execa'); const escapeStringRegexp = require('escape-string-regexp'); const {verifyRequirementSatisfied} = require('./version'); -const {splitFileNameList} = require('util'); exports.latestTag = async () => { const {stdout} = await execa('git', ['describe', '--abbrev=0', '--tags']); @@ -10,8 +9,8 @@ exports.latestTag = async () => { }; exports.newFilesSinceLastRelease = async () => { - const {stdout} = await execa('git', ['diff','--stat', '--diff-filter=A', await latestTag(), 'HEAD']); - return splitFileNameList(stdout); + const {stdout} = await execa('git', ['diff', '--stat', '--diff-filter=A', await this.latestTag(), 'HEAD']); + return stdout; }; const firstCommit = async () => { diff --git a/source/npm/util.js b/source/npm/util.js index 7b67ac23..bb8f13c1 100644 --- a/source/npm/util.js +++ b/source/npm/util.js @@ -7,6 +7,7 @@ const ow = require('ow'); const npmName = require('npm-name'); const chalk = require('chalk'); const pkgDir = require('pkg-dir'); +const ignoreWalker = require('ignore-walk'); const {verifyRequirementSatisfied} = require('../version'); exports.checkConnection = () => pTimeout( @@ -108,17 +109,58 @@ exports.checkIgnoreStrategy = ({files}) => { } }; -//new files added part of .npmignore or part of files -exports.checkNewFiles = ({files}, newFiles) => { - -} +// New files added part of .npmignore or not part of files-attribute in "package.json" +exports.checkNewFiles = async ({filesFromPackageDotJson}, newFiles) => { + const rootDir = pkgDir.sync(); + const npmignoreExists = fs.existsSync(path.resolve(rootDir, '.npmignore')); -const isIgnoredByDotnpmIgnore = (file) => { - const roorDir = pkgDir.sync(); - fs.readFileSync(path.resolve(rootDir, '.npmignore'), -}; + let result = []; + + if (filesFromPackageDotJson) { + result = getFilesNotPartOfFileAttribute(filesFromPackageDotJson, newFiles); + } + + if (npmignoreExists) { + result = result.concat(await getFilesIgnoredByDotnpmignore(newFiles)); + } -const isPartOfFileProperty = (file, fileProperty) => { - + return result; }; +async function getFilesIgnoredByDotnpmignore(fileList) { + if (!Array.isArray(fileList)) { + throw new TypeError('expected array, but got {typeof fileList}'); + } + + const result = []; + await ignoreWalker({ + path: pkgDir.sync(), + ignoreFiles: ['.npmignore'] + }) + .then(CommaSeparatedList => { + const WhiteList = CommaSeparatedList.split(','); + /* Every file in fileList should be part of + the WhiteList */ + fileList.foreach(item => { + if (WhiteList.find(item) === undefined) { + result.push(item); + } + }); + }); + + return result; +} + +function getFilesNotPartOfFileAttribute(filesFromPackageDotJson, fileList) { + if (!Array.isArray(fileList)) { + throw new TypeError(`expected array, but got ${typeof fileList}`); + } + + const result = []; + fileList.foreach(item => { + if (filesFromPackageDotJson.find(item) === undefined) { + result.push(item); + } + }); + return result; +} diff --git a/source/util.js b/source/util.js index 71c3591f..3d019e79 100644 --- a/source/util.js +++ b/source/util.js @@ -5,6 +5,8 @@ const terminalLink = require('terminal-link'); const execa = require('execa'); const pMemoize = require('p-memoize'); const ow = require('ow'); +const gitUtil = require('./git-util'); +const npmUtil = require('./npm/util'); exports.readPkg = () => { const {package: pkg} = readPkgUp.sync(); @@ -64,16 +66,21 @@ exports.getTagVersionPrefix = pMemoize(async options => { } }); -exports.splitFileNameList(stdout) => { - - if(typeof stdout !== 'string') +function splitFileNameList(stdout) { + if (typeof stdout !== 'string') { throw new TypeError('expected parameter stdout of type string'); + } const rows = stdout.trim().split(); - let result = new Array(rows.length); - for(let i=0;i { + const ListNewFiles = splitFileNameList(await gitUtil.newFilesSinceLastRelease()); + return npmUtil.checkNewFiles(pkg, ListNewFiles); }; diff --git a/test/.npmignore.js.swp b/test/.npmignore.js.swp new file mode 100644 index 0000000000000000000000000000000000000000..34c759adf5abe770e303d987f50d1880f650a8d7 GIT binary patch literal 12288 zcmeI2O=}ZD7{{l2iti}mb+p26pxw0gQd%nbLPfMvU+P7wPBxQdn$7IGJKGvc+k@c2 zo1jPW(z6FWC|*73C-58S7w{qq{%5n>L@bS-M0pl|Y<6Cs`8_j%Hd`ILd2x`TMC;(Ynj-pov!7kF9IC}zS^l3W9!9$6&+QKObqUA)zD!qy`_P( z>^wHrk^wR>$iRL!acX?bwi-ThoF6&7FsK97lL0b72FL&zAOmE843Ggb@E;j4(Gc6f zdUoY&%Ki_4&qMihanB#=Mh3_L86X2>fDDiUGC&5%02v?yWPl9(g9b#6u}6FGTmN1J zkKg}`zyCiUWb8e70iJ>wd;QflY85EP@Fz z4t9ef@O>X+-@se&2DHFcFb^(+OW+td3O*vvH{dmR1zv*Z;2C%TLZE?Nj{)Wiplxl^7YH34*MK*|%gpQAd&M zmif$SzRFlO5YMk$P7R-J50XX=&{iOwBijMPSj+RK)=HXuaXcNBeMRZWfLO7lqgEzz)V8HXBS_Xk|E z{(thrXLu~{r7D)L<9U_bZ)#NF*j4oMC3TjQFj&R}Ho=Ie47N=nCyTTlv#ilPs^2TLtR(emzPCiu1V-fu)F(p6`OkwN5FNW zR%5iLVyw0oT6wz9?$6D=N<*2^ED7Bn`P?>?;!G7iaC*X(EH!=kgVM@Y4u7jh(VCU~ zP$#A@PV5kz1#CwfdUjBIE%La2Y0^E)RawW|?!B`d$X|{pz9m#U3S)y^Ynr?shi#5i hV4BW!QISoa*JPi2Rr$*D%KWKUZMR!qCzb`ue*j%C#Df3; literal 0 HcmV?d00001 diff --git a/test/npmignore.js b/test/npmignore.js new file mode 100644 index 00000000..46b4739b --- /dev/null +++ b/test/npmignore.js @@ -0,0 +1,41 @@ +import path from 'path'; +import test from 'ava'; +import mockery from 'mockery'; +import sinon from 'sinon'; + +let moduleUnderTest; + +test.before(() => { + const stubGitUtil = sinon.stub(); + const stubPkgDir = sinon.stub(); + + mockery.registerAllowable('../source/util'); + mockery.registerAllowable('../source/npm/util'); + mockery.registerMock('./git-util', stubGitUtil); + mockery.registerMock('pkg-dir', stubPkgDir); + + stubGitUtil.newFilesSinceLastRelease() + .returns(['source/ignore.txt', 'source/pay_attention.txt']); + stubPkgDir.sync() + .onCall(0).returns(path.resolve('test', 'ressources', 'package')) + .onCall(1).returns(path.resolve('test', 'ressources', 'npmignore')); + + mockery.enable({useCleanCache: true}); + + moduleUnderTest = require('../source/util'); +}); + +test('ignored files using file-attribute in package.json', async t => { + t.is(await moduleUnderTest.getFilesIgnoredByNpm({files: ['pay_attention.txt']}), + ['source/ignore.txt']); +}); + +test('ignored files using .npmignore', async t => { + t.is(await moduleUnderTest.getFilesIgnoredByNpm(undefined), + ['source/ignore.txt']); +}); + +test.after(() => { + mockery.deregisterAll(); + mockery.disable(); +}); diff --git a/test/ressources/npmignore/.npmignore b/test/ressources/npmignore/.npmignore new file mode 100644 index 00000000..8ea087a8 --- /dev/null +++ b/test/ressources/npmignore/.npmignore @@ -0,0 +1 @@ +ignore.txt diff --git a/test/ressources/npmignore/source/ignore.txt b/test/ressources/npmignore/source/ignore.txt new file mode 100644 index 00000000..26ef7633 --- /dev/null +++ b/test/ressources/npmignore/source/ignore.txt @@ -0,0 +1 @@ +Ignore this file diff --git a/test/ressources/npmignore/source/pay_attention.txt b/test/ressources/npmignore/source/pay_attention.txt new file mode 100644 index 00000000..01a573f9 --- /dev/null +++ b/test/ressources/npmignore/source/pay_attention.txt @@ -0,0 +1 @@ +File is excluded from .npmignore diff --git a/test/ressources/package/package.json b/test/ressources/package/package.json new file mode 100644 index 00000000..b2861deb --- /dev/null +++ b/test/ressources/package/package.json @@ -0,0 +1,3 @@ +{ + "files": ["pay_attention.txt"] +} diff --git a/test/ressources/package/source/ignore.txt b/test/ressources/package/source/ignore.txt new file mode 100644 index 00000000..40f91d34 --- /dev/null +++ b/test/ressources/package/source/ignore.txt @@ -0,0 +1 @@ +File is excluded from package.json diff --git a/test/ressources/package/source/pay_attention.txt b/test/ressources/package/source/pay_attention.txt new file mode 100644 index 00000000..e5f3e01f --- /dev/null +++ b/test/ressources/package/source/pay_attention.txt @@ -0,0 +1 @@ +File in included in package.json diff --git a/test/ressources/readme.md b/test/ressources/readme.md new file mode 100644 index 00000000..c0816aa2 --- /dev/null +++ b/test/ressources/readme.md @@ -0,0 +1,2 @@ +The directory is for the resources +in the script npmignore.js From 7278c44b3e623c19e94e9747954509c7b362fad1 Mon Sep 17 00:00:00 2001 From: Bunyanuch Saengnet Date: Mon, 23 Sep 2019 20:03:39 +0000 Subject: [PATCH 03/33] test-passes --- package.json | 1 + source/npm/util.js | 34 +++++++++++++++++++++++++--------- source/util.js | 8 ++++---- test/.npmignore.js.swp | Bin 12288 -> 0 bytes test/npmignore.js | 36 ++++++++++++++++++++++++------------ 5 files changed, 54 insertions(+), 25 deletions(-) delete mode 100644 test/.npmignore.js.swp diff --git a/package.json b/package.json index 948e29a4..5d3aeb5e 100644 --- a/package.json +++ b/package.json @@ -49,6 +49,7 @@ "listr-input": "^0.1.3", "log-symbols": "^3.0.0", "meow": "^5.0.0", + "minimatch": "^3.0.4", "npm-name": "^5.4.0", "onetime": "^5.1.0", "open": "^6.1.0", diff --git a/source/npm/util.js b/source/npm/util.js index bb8f13c1..37d9f701 100644 --- a/source/npm/util.js +++ b/source/npm/util.js @@ -8,6 +8,7 @@ const npmName = require('npm-name'); const chalk = require('chalk'); const pkgDir = require('pkg-dir'); const ignoreWalker = require('ignore-walk'); +const {Minimatch} = require('minimatch'); const {verifyRequirementSatisfied} = require('../version'); exports.checkConnection = () => pTimeout( @@ -110,7 +111,7 @@ exports.checkIgnoreStrategy = ({files}) => { }; // New files added part of .npmignore or not part of files-attribute in "package.json" -exports.checkNewFiles = async ({filesFromPackageDotJson}, newFiles) => { +exports.checkNewFiles = async (newFiles, filesFromPackageDotJson) => { const rootDir = pkgDir.sync(); const npmignoreExists = fs.existsSync(path.resolve(rootDir, '.npmignore')); @@ -137,12 +138,17 @@ async function getFilesIgnoredByDotnpmignore(fileList) { path: pkgDir.sync(), ignoreFiles: ['.npmignore'] }) - .then(CommaSeparatedList => { - const WhiteList = CommaSeparatedList.split(','); - /* Every file in fileList should be part of - the WhiteList */ - fileList.foreach(item => { - if (WhiteList.find(item) === undefined) { + .then(WhiteList => { + if (!Array.isArray(WhiteList)) { + throw new TypeError(`Expected array, but got ${typeof WhiteList} `); + } + + // Every file in fileList should be part of the WhiteList + fileList.forEach(item => { + const found = WhiteList.find(WhiteListItem => { + return WhiteListItem === item; + }); + if (found === undefined) { result.push(item); } }); @@ -157,10 +163,20 @@ function getFilesNotPartOfFileAttribute(filesFromPackageDotJson, fileList) { } const result = []; - fileList.foreach(item => { - if (filesFromPackageDotJson.find(item) === undefined) { + const globMatcher = new Minimatch(getGlobPattern(filesFromPackageDotJson), + {matchBase: true}); + fileList.forEach(item => { + if (!globMatcher.match(item)) { result.push(item); } }); return result; } + +function getGlobPattern(filesFromPackageDotJson) { + if (filesFromPackageDotJson.length === 1) { + return filesFromPackageDotJson[0]; + } + + return '{' + filesFromPackageDotJson.join(',') + '}'; +} diff --git a/source/util.js b/source/util.js index 3d019e79..136f4893 100644 --- a/source/util.js +++ b/source/util.js @@ -71,10 +71,10 @@ function splitFileNameList(stdout) { throw new TypeError('expected parameter stdout of type string'); } - const rows = stdout.trim().split(); - const result = new Array(rows.length); + const rows = stdout.trim().split('\n'); + const result = []; for (let i = 0; i < rows.length; i++) { - result[i] = rows[i].substring(0, rows[i].indexOf('|')).trim(); + result.push(rows[i].substring(0, rows[i].indexOf('|')).trim()); } return result; @@ -82,5 +82,5 @@ function splitFileNameList(stdout) { exports.getNewFilesIgnoredByNpm = async pkg => { const ListNewFiles = splitFileNameList(await gitUtil.newFilesSinceLastRelease()); - return npmUtil.checkNewFiles(pkg, ListNewFiles); + return npmUtil.checkNewFiles(ListNewFiles, pkg.files); }; diff --git a/test/.npmignore.js.swp b/test/.npmignore.js.swp deleted file mode 100644 index 34c759adf5abe770e303d987f50d1880f650a8d7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12288 zcmeI2O=}ZD7{{l2iti}mb+p26pxw0gQd%nbLPfMvU+P7wPBxQdn$7IGJKGvc+k@c2 zo1jPW(z6FWC|*73C-58S7w{qq{%5n>L@bS-M0pl|Y<6Cs`8_j%Hd`ILd2x`TMC;(Ynj-pov!7kF9IC}zS^l3W9!9$6&+QKObqUA)zD!qy`_P( z>^wHrk^wR>$iRL!acX?bwi-ThoF6&7FsK97lL0b72FL&zAOmE843Ggb@E;j4(Gc6f zdUoY&%Ki_4&qMihanB#=Mh3_L86X2>fDDiUGC&5%02v?yWPl9(g9b#6u}6FGTmN1J zkKg}`zyCiUWb8e70iJ>wd;QflY85EP@Fz z4t9ef@O>X+-@se&2DHFcFb^(+OW+td3O*vvH{dmR1zv*Z;2C%TLZE?Nj{)Wiplxl^7YH34*MK*|%gpQAd&M zmif$SzRFlO5YMk$P7R-J50XX=&{iOwBijMPSj+RK)=HXuaXcNBeMRZWfLO7lqgEzz)V8HXBS_Xk|E z{(thrXLu~{r7D)L<9U_bZ)#NF*j4oMC3TjQFj&R}Ho=Ie47N=nCyTTlv#ilPs^2TLtR(emzPCiu1V-fu)F(p6`OkwN5FNW zR%5iLVyw0oT6wz9?$6D=N<*2^ED7Bn`P?>?;!G7iaC*X(EH!=kgVM@Y4u7jh(VCU~ zP$#A@PV5kz1#CwfdUjBIE%La2Y0^E)RawW|?!B`d$X|{pz9m#U3S)y^Ynr?shi#5i hV4BW!QISoa*JPi2Rr$*D%KWKUZMR!qCzb`ue*j%C#Df3; diff --git a/test/npmignore.js b/test/npmignore.js index 46b4739b..bc6e24da 100644 --- a/test/npmignore.js +++ b/test/npmignore.js @@ -5,33 +5,45 @@ import sinon from 'sinon'; let moduleUnderTest; +const gitUtilApi = { + async newFilesSinceLastRelease() { + } +}; + +const pkgDirApi = { + sync() { + } +}; + test.before(() => { - const stubGitUtil = sinon.stub(); - const stubPkgDir = sinon.stub(); + const stubGitUtil = sinon.stub(gitUtilApi, 'newFilesSinceLastRelease'); + const stubPkgDir = sinon.stub(pkgDirApi, 'sync'); mockery.registerAllowable('../source/util'); mockery.registerAllowable('../source/npm/util'); - mockery.registerMock('./git-util', stubGitUtil); - mockery.registerMock('pkg-dir', stubPkgDir); + mockery.registerMock('./git-util', gitUtilApi); + mockery.registerMock('pkg-dir', pkgDirApi); - stubGitUtil.newFilesSinceLastRelease() - .returns(['source/ignore.txt', 'source/pay_attention.txt']); - stubPkgDir.sync() - .onCall(0).returns(path.resolve('test', 'ressources', 'package')) - .onCall(1).returns(path.resolve('test', 'ressources', 'npmignore')); + stubGitUtil.returns((['source/ignore.txt | ++', 'source/pay_attention.txt | --']).join('\n')); + stubPkgDir.onCall(0).returns(path.resolve('test', 'ressources', 'package')); + stubPkgDir.returns(path.resolve('test', 'ressources', 'npmignore')); - mockery.enable({useCleanCache: true}); + mockery.enable({ + useCleanCache: true, + warnOnReplace: false, + warnOnUnregistered: false + }); moduleUnderTest = require('../source/util'); }); test('ignored files using file-attribute in package.json', async t => { - t.is(await moduleUnderTest.getFilesIgnoredByNpm({files: ['pay_attention.txt']}), + t.deepEqual(await moduleUnderTest.getNewFilesIgnoredByNpm({files: ['pay_attention.txt']}), ['source/ignore.txt']); }); test('ignored files using .npmignore', async t => { - t.is(await moduleUnderTest.getFilesIgnoredByNpm(undefined), + t.deepEqual(await moduleUnderTest.getNewFilesIgnoredByNpm({name: 'without file-attribute'}), ['source/ignore.txt']); }); From 9f3a1c3af7b998b5ed473ae3db92a5f94ac80d9a Mon Sep 17 00:00:00 2001 From: Bunyanuch Saengnet Date: Mon, 23 Sep 2019 20:39:29 +0000 Subject: [PATCH 04/33] integration ignored files in ui --- source/ui.js | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/source/ui.js b/source/ui.js index b29377ad..633dd59a 100644 --- a/source/ui.js +++ b/source/ui.js @@ -49,12 +49,35 @@ const printCommitLog = async repoUrl => { }; }; +const confirmIgnoredFiles = async pkg => { + const ignoredFiles = await util.getNewFilesIgnoredByNpm(pkg); + if (ignoredFiles.length === 0) { + return {confirm: true}; + } + + const answers = await inquirer.prompt([{ + type: 'confirm', + name: 'confirm', + message: `The following new files are not part of your published package ${ignoredFiles}. Continue?`, + default: false + }]); + + return answers; +}; + module.exports = async (options, pkg) => { const oldVersion = pkg.version; const extraBaseUrls = ['gitlab.com']; const repoUrl = pkg.repository && githubUrlFromGit(pkg.repository.url, {extraBaseUrls}); checkIgnoreStrategy(pkg); + const answerIgnoredFiles = await confirmIgnoredFiles(pkg.files); + if (!answerIgnoredFiles.confirm) { + return { + ...options, + ...answerIgnoredFiles + }; + } console.log(`\nPublish a new version of ${chalk.bold.magenta(pkg.name)} ${chalk.dim(`(current: ${oldVersion})`)}\n`); From 5bb7561343824439bb0a142d738996dadf9ce959 Mon Sep 17 00:00:00 2001 From: Bunyanuch Saengnet Date: Wed, 11 Dec 2019 20:36:08 +0000 Subject: [PATCH 05/33] Refactorings for new function show files since the last release and not part of package according to pull-request comments from @fregante Pull-Request 456 --- package.json | 2 +- source/npm/util.js | 54 +++++++++++++++++----------------------------- source/ui.js | 2 +- source/util.js | 8 +------ test/npmignore.js | 8 ++++++- 5 files changed, 30 insertions(+), 44 deletions(-) diff --git a/package.json b/package.json index 17d1db05..3f5d0400 100644 --- a/package.json +++ b/package.json @@ -40,7 +40,7 @@ "github-url-from-git": "^1.5.0", "has-yarn": "^2.1.0", "hosted-git-info": "^3.0.0", - "ignore-walk": "^3.0.2", + "ignore-walk": "^3.0.2", "inquirer": "^7.0.0", "is-installed-globally": "^0.2.0", "is-scoped": "^2.1.0", diff --git a/source/npm/util.js b/source/npm/util.js index 37d9f701..197953bb 100644 --- a/source/npm/util.js +++ b/source/npm/util.js @@ -8,7 +8,7 @@ const npmName = require('npm-name'); const chalk = require('chalk'); const pkgDir = require('pkg-dir'); const ignoreWalker = require('ignore-walk'); -const {Minimatch} = require('minimatch'); +const minimatch = require('minimatch'); const {verifyRequirementSatisfied} = require('../version'); exports.checkConnection = () => pTimeout( @@ -111,14 +111,14 @@ exports.checkIgnoreStrategy = ({files}) => { }; // New files added part of .npmignore or not part of files-attribute in "package.json" -exports.checkNewFiles = async (newFiles, filesFromPackageDotJson) => { +exports.checkNewFiles = async (newFiles, filesFromFileAttribute) => { const rootDir = pkgDir.sync(); const npmignoreExists = fs.existsSync(path.resolve(rootDir, '.npmignore')); let result = []; - if (filesFromPackageDotJson) { - result = getFilesNotPartOfFileAttribute(filesFromPackageDotJson, newFiles); + if (filesFromFileAttribute) { + result = getFilesNotPartOfFileAttribute(filesFromFileAttribute, newFiles); } if (npmignoreExists) { @@ -134,49 +134,35 @@ async function getFilesIgnoredByDotnpmignore(fileList) { } const result = []; - await ignoreWalker({ + const whiteList = await ignoreWalker({ path: pkgDir.sync(), ignoreFiles: ['.npmignore'] - }) - .then(WhiteList => { - if (!Array.isArray(WhiteList)) { - throw new TypeError(`Expected array, but got ${typeof WhiteList} `); - } - - // Every file in fileList should be part of the WhiteList - fileList.forEach(item => { - const found = WhiteList.find(WhiteListItem => { - return WhiteListItem === item; - }); - if (found === undefined) { - result.push(item); - } - }); + }); + for (const file of fileList) { + const found = whiteList.find(whiteListItem => { + return whiteListItem === file; }); + if (found === undefined) { + result.push(file); + } + } return result; } -function getFilesNotPartOfFileAttribute(filesFromPackageDotJson, fileList) { +function getFilesNotPartOfFileAttribute(filesFromFileAttribute, fileList) { if (!Array.isArray(fileList)) { throw new TypeError(`expected array, but got ${typeof fileList}`); } - const result = []; - const globMatcher = new Minimatch(getGlobPattern(filesFromPackageDotJson), - {matchBase: true}); - fileList.forEach(item => { - if (!globMatcher.match(item)) { - result.push(item); - } - }); - return result; + return fileList.filter(minimatch.filter(getGlobPattern(filesFromFileAttribute), + {matchBase: true})); } -function getGlobPattern(filesFromPackageDotJson) { - if (filesFromPackageDotJson.length === 1) { - return filesFromPackageDotJson[0]; +function getGlobPattern(filesFromFileAttribute) { + if (filesFromFileAttribute.length === 1) { + return '!' + filesFromFileAttribute[0]; } - return '{' + filesFromPackageDotJson.join(',') + '}'; + return '!{' + filesFromFileAttribute.join(',') + '}'; } diff --git a/source/ui.js b/source/ui.js index 633dd59a..2e771af3 100644 --- a/source/ui.js +++ b/source/ui.js @@ -71,7 +71,7 @@ module.exports = async (options, pkg) => { const repoUrl = pkg.repository && githubUrlFromGit(pkg.repository.url, {extraBaseUrls}); checkIgnoreStrategy(pkg); - const answerIgnoredFiles = await confirmIgnoredFiles(pkg.files); + const answerIgnoredFiles = await confirmIgnoredFiles(pkg); if (!answerIgnoredFiles.confirm) { return { ...options, diff --git a/source/util.js b/source/util.js index 136f4893..802f9c46 100644 --- a/source/util.js +++ b/source/util.js @@ -71,13 +71,7 @@ function splitFileNameList(stdout) { throw new TypeError('expected parameter stdout of type string'); } - const rows = stdout.trim().split('\n'); - const result = []; - for (let i = 0; i < rows.length; i++) { - result.push(rows[i].substring(0, rows[i].indexOf('|')).trim()); - } - - return result; + return stdout.trim().split('\n').map(row => row.replace(/[|+-]/g, '').trim()); } exports.getNewFilesIgnoredByNpm = async pkg => { diff --git a/test/npmignore.js b/test/npmignore.js index bc6e24da..874d7dd4 100644 --- a/test/npmignore.js +++ b/test/npmignore.js @@ -26,6 +26,7 @@ test.before(() => { stubGitUtil.returns((['source/ignore.txt | ++', 'source/pay_attention.txt | --']).join('\n')); stubPkgDir.onCall(0).returns(path.resolve('test', 'ressources', 'package')); + stubPkgDir.onCall(1).returns(path.resolve('test', 'ressources', 'package')); stubPkgDir.returns(path.resolve('test', 'ressources', 'npmignore')); mockery.enable({ @@ -37,11 +38,16 @@ test.before(() => { moduleUnderTest = require('../source/util'); }); -test('ignored files using file-attribute in package.json', async t => { +test('ignored files using file-attribute in package.json with one item', async t => { t.deepEqual(await moduleUnderTest.getNewFilesIgnoredByNpm({files: ['pay_attention.txt']}), ['source/ignore.txt']); }); +test('ignored files using file-attribute in package.json with multiple items', async t => { + t.deepEqual(await moduleUnderTest.getNewFilesIgnoredByNpm( + {files: ['pay_attention.txt', 'ignore.txt']}), []); +}); + test('ignored files using .npmignore', async t => { t.deepEqual(await moduleUnderTest.getNewFilesIgnoredByNpm({name: 'without file-attribute'}), ['source/ignore.txt']); From c43f900e832e15dd07de4d5d9b654d8325af254f Mon Sep 17 00:00:00 2001 From: Bunyanuch Saengnet Date: Wed, 11 Dec 2019 21:04:59 +0000 Subject: [PATCH 06/33] Resolved merge-conflict in ui.js --- source/ui.js | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/source/ui.js b/source/ui.js index 2e771af3..a89ca702 100644 --- a/source/ui.js +++ b/source/ui.js @@ -70,13 +70,15 @@ module.exports = async (options, pkg) => { const extraBaseUrls = ['gitlab.com']; const repoUrl = pkg.repository && githubUrlFromGit(pkg.repository.url, {extraBaseUrls}); - checkIgnoreStrategy(pkg); - const answerIgnoredFiles = await confirmIgnoredFiles(pkg); - if (!answerIgnoredFiles.confirm) { - return { - ...options, - ...answerIgnoredFiles - }; + if (runPublish) { + checkIgnoreStrategy(pkg); + const answerIgnoredFiles = await confirmIgnoredFiles(pkg); + if (!answerIgnoredFiles.confirm) { + return { + ...options, + ...answerIgnoredFiles + }; + } } console.log(`\nPublish a new version of ${chalk.bold.magenta(pkg.name)} ${chalk.dim(`(current: ${oldVersion})`)}\n`); From 12a16f0381f00233407539ae83786ce316fd83cd Mon Sep 17 00:00:00 2001 From: Bunyanuch Saengnet Date: Fri, 27 Dec 2019 15:09:45 +0000 Subject: [PATCH 07/33] Show files added since the last release not part of the release package Iteration 3 1. Moved .npmignore exitence check into separate function 2. According to npm-docs files-attribute has a higher priority than .npmignore-file in the package-root-directory 3. Exclude the files ignored by default (http://npm.github.io/publishing-pkgs-docs/publishing/the-npmignore-file.html) from the comparison 4. Refactoring: naming of variables --- source/npm/util.js | 54 +++++++++++++++++------------------ source/ui.js | 4 +-- source/util.js | 4 +-- test/npmignore.js | 22 ++++++++------ test/ressources/npmignore/.hg | 1 + test/ressources/package/.hg | 1 + 6 files changed, 45 insertions(+), 41 deletions(-) create mode 100644 test/ressources/npmignore/.hg create mode 100644 test/ressources/package/.hg diff --git a/source/npm/util.js b/source/npm/util.js index 5e2b9608..d7b404c0 100644 --- a/source/npm/util.js +++ b/source/npm/util.js @@ -102,51 +102,41 @@ exports.verifyRecentNpmVersion = async () => { }; exports.checkIgnoreStrategy = ({files}) => { - const rootDir = pkgDir.sync(); - const npmignoreExists = fs.existsSync(path.resolve(rootDir, '.npmignore')); - - if (!files && !npmignoreExists) { + if (!files && !npmignoreExistsInPackageRootDir()) { console.log(` \n${chalk.bold.yellow('Warning:')} No ${chalk.bold.cyan('files')} field specified in ${chalk.bold.magenta('package.json')} nor is a ${chalk.bold.magenta('.npmignore')} file present. Having one of those will prevent you from accidentally publishing development-specific files along with your package's source code to npm. `); } }; -// New files added part of .npmignore or not part of files-attribute in "package.json" -exports.checkNewFiles = async (newFiles, filesFromFileAttribute) => { - const rootDir = pkgDir.sync(); - const npmignoreExists = fs.existsSync(path.resolve(rootDir, '.npmignore')); - - let result = []; - +// Get all files which will be ignored by either `.npmignore` or the `files` property in `package.json` (if defined) +exports.getNewAndUnpublishedFiles = async (newFiles, filesFromFileAttribute) => { if (filesFromFileAttribute) { - result = getFilesNotPartOfFileAttribute(filesFromFileAttribute, newFiles); + return getFilesNotPartOfFileAttribute(filesFromFileAttribute, newFiles); } - if (npmignoreExists) { - result = result.concat(await getFilesIgnoredByDotnpmignore(newFiles)); + if (npmignoreExistsInPackageRootDir()) { + return getFilesIgnoredByDotnpmignore(newFiles); } - - return result; }; +function npmignoreExistsInPackageRootDir() { + const rootDir = pkgDir.sync(); + return fs.existsSync(path.resolve(rootDir, '.npmignore')); +} + async function getFilesIgnoredByDotnpmignore(fileList) { if (!Array.isArray(fileList)) { throw new TypeError('expected array, but got {typeof fileList}'); } - const result = []; const whiteList = await ignoreWalker({ path: pkgDir.sync(), ignoreFiles: ['.npmignore'] }); - for (const file of fileList) { - if (!whiteList.includes(file)) { - result.push(file); - } - } - return result; + return fileList.filter(minimatch.filter(getGlobPattern(whiteList), + {matchBase: true})); } function getFilesNotPartOfFileAttribute(filesFromFileAttribute, fileList) { @@ -159,9 +149,17 @@ function getFilesNotPartOfFileAttribute(filesFromFileAttribute, fileList) { } function getGlobPattern(filesFromFileAttribute) { - if (filesFromFileAttribute.length === 1) { - return '!' + filesFromFileAttribute[0]; - } - - return '!{' + filesFromFileAttribute.join(',') + '}'; + const filesIgnoredByDefault = ['.*.swp', + '._*', + '.DS_Store', + '.hg', + '.npmrc', + '.lock-wscript', + '.svn', + '.wafpickle-*', + 'config.gypi', + 'CVS', + 'npm-debug.log']; + return '!{' + filesFromFileAttribute.join(',') + + ',' + filesIgnoredByDefault.join(',') + '}'; } diff --git a/source/ui.js b/source/ui.js index 9e4d1c6b..a172978c 100644 --- a/source/ui.js +++ b/source/ui.js @@ -50,8 +50,8 @@ const printCommitLog = async repoUrl => { }; const confirmIgnoredFiles = async pkg => { - const ignoredFiles = await util.getNewFilesIgnoredByNpm(pkg); - if (ignoredFiles.length === 0) { + const ignoredFiles = await util.getNewAndUnpublishedFiles(pkg); + if (ignoredFiles === undefined || ignoredFiles.length === 0) { return {confirm: true}; } diff --git a/source/util.js b/source/util.js index ffd00df8..e8a2cd37 100644 --- a/source/util.js +++ b/source/util.js @@ -74,7 +74,7 @@ function splitFileNameList(stdout) { return stdout.trim().split('\n').map(row => row.replace(/[|+-]/g, '').trim()); } -exports.getNewFilesIgnoredByNpm = async pkg => { +exports.getNewAndUnpublishedFiles = async pkg => { const ListNewFiles = splitFileNameList(await gitUtil.newFilesSinceLastRelease()); - return npmUtil.checkNewFiles(ListNewFiles, pkg.files); + return npmUtil.getNewAndUnpublishedFiles(ListNewFiles, pkg.files); }; diff --git a/test/npmignore.js b/test/npmignore.js index 388af273..6c2dd1be 100644 --- a/test/npmignore.js +++ b/test/npmignore.js @@ -15,19 +15,17 @@ const pkgDirApi = { } }; +const stubPkgDir = sinon.stub(pkgDirApi, 'sync'); + test.before(() => { const stubGitUtil = sinon.stub(gitUtilApi, 'newFilesSinceLastRelease'); - const stubPkgDir = sinon.stub(pkgDirApi, 'sync'); mockery.registerAllowable('../source/util'); mockery.registerAllowable('../source/npm/util'); mockery.registerMock('./git-util', gitUtilApi); mockery.registerMock('pkg-dir', pkgDirApi); - stubGitUtil.returns((['source/ignore.txt | ++', 'source/pay_attention.txt | --']).join('\n')); - stubPkgDir.onCall(0).returns(path.resolve('test', 'ressources', 'package')); - stubPkgDir.onCall(1).returns(path.resolve('test', 'ressources', 'package')); - stubPkgDir.returns(path.resolve('test', 'ressources', 'npmignore')); + stubGitUtil.returns((['source/ignore.txt | ++', 'source/pay_attention.txt | --', '.hg | +']).join('\n')); mockery.enable({ useCleanCache: true, @@ -44,16 +42,22 @@ test.after(() => { }); test('ignored files using file-attribute in package.json with one item', async t => { - t.deepEqual(await moduleUnderTest.getNewFilesIgnoredByNpm({files: ['pay_attention.txt']}), + t.deepEqual(await moduleUnderTest.getNewAndUnpublishedFiles({files: ['pay_attention.txt']}), ['source/ignore.txt']); }); test('ignored files using file-attribute in package.json with multiple items', async t => { - t.deepEqual(await moduleUnderTest.getNewFilesIgnoredByNpm( + t.deepEqual(await moduleUnderTest.getNewAndUnpublishedFiles( {files: ['pay_attention.txt', 'ignore.txt']}), []); }); -test('ignored files using .npmignore', async t => { - t.deepEqual(await moduleUnderTest.getNewFilesIgnoredByNpm({name: 'without file-attribute'}), +test.serial('ignored files using .npmignore', async t => { + stubPkgDir.returns(path.resolve('test', 'ressources', 'npmignore')); + t.deepEqual(await moduleUnderTest.getNewAndUnpublishedFiles({name: 'without file-attribute'}), ['source/ignore.txt']); }); + +test.serial('ignore strategy is not used', async t => { + stubPkgDir.returns(path.resolve('test', 'ressources')); + t.true(await moduleUnderTest.getNewAndUnpublishedFiles({name: 'without file-attribute'}) === undefined); +}); diff --git a/test/ressources/npmignore/.hg b/test/ressources/npmignore/.hg new file mode 100644 index 00000000..3f06d3e2 --- /dev/null +++ b/test/ressources/npmignore/.hg @@ -0,0 +1 @@ +should be ignored by default diff --git a/test/ressources/package/.hg b/test/ressources/package/.hg new file mode 100644 index 00000000..3f06d3e2 --- /dev/null +++ b/test/ressources/package/.hg @@ -0,0 +1 @@ +should be ignored by default From 73b86f7af51434cc52111e2a83f622cd85853134 Mon Sep 17 00:00:00 2001 From: Bunyanuch Saengnet Date: Fri, 27 Dec 2019 19:29:26 +0000 Subject: [PATCH 08/33] Show files added since the last release not part of the release package Iteration 3 1. Refactorings 2. UI-Improvement --- source/git-util.js | 5 +++- source/npm/util.js | 26 ++++++------------- source/ui.js | 6 ++--- source/util.js | 12 ++------- test/{ressources => fixtures}/npmignore/.hg | 0 .../npmignore/.npmignore | 0 .../npmignore/source/ignore.txt | 0 .../npmignore/source/pay_attention.txt | 0 test/{ressources => fixtures}/package/.hg | 0 .../package/package.json | 0 .../package/source/ignore.txt | 0 .../package/source/pay_attention.txt | 0 test/{ressources => fixtures}/readme.md | 0 test/npmignore.js | 6 ++--- 14 files changed, 20 insertions(+), 35 deletions(-) rename test/{ressources => fixtures}/npmignore/.hg (100%) rename test/{ressources => fixtures}/npmignore/.npmignore (100%) rename test/{ressources => fixtures}/npmignore/source/ignore.txt (100%) rename test/{ressources => fixtures}/npmignore/source/pay_attention.txt (100%) rename test/{ressources => fixtures}/package/.hg (100%) rename test/{ressources => fixtures}/package/package.json (100%) rename test/{ressources => fixtures}/package/source/ignore.txt (100%) rename test/{ressources => fixtures}/package/source/pay_attention.txt (100%) rename test/{ressources => fixtures}/readme.md (100%) diff --git a/source/git-util.js b/source/git-util.js index bc0f51d0..b32c5dfb 100644 --- a/source/git-util.js +++ b/source/git-util.js @@ -10,7 +10,10 @@ exports.latestTag = async () => { exports.newFilesSinceLastRelease = async () => { const {stdout} = await execa('git', ['diff', '--stat', '--diff-filter=A', await this.latestTag(), 'HEAD']); - return stdout; + const result = stdout.trim().split('\n').map(row => row.slice(0, row.indexOf('|')).trim()); + // Last row contains the conclusion, remove it + result.pop(); + return result; }; const firstCommit = async () => { diff --git a/source/npm/util.js b/source/npm/util.js index d7b404c0..1b03c1f0 100644 --- a/source/npm/util.js +++ b/source/npm/util.js @@ -110,9 +110,9 @@ exports.checkIgnoreStrategy = ({files}) => { }; // Get all files which will be ignored by either `.npmignore` or the `files` property in `package.json` (if defined) -exports.getNewAndUnpublishedFiles = async (newFiles, filesFromFileAttribute) => { - if (filesFromFileAttribute) { - return getFilesNotPartOfFileAttribute(filesFromFileAttribute, newFiles); +exports.getNewAndUnpublishedFiles = async (newFiles, globArrayFromFilesProperty) => { + if (globArrayFromFilesProperty) { + return getFilesNotIncludedInTheFilesProperty(globArrayFromFilesProperty, newFiles); } if (npmignoreExistsInPackageRootDir()) { @@ -126,29 +126,20 @@ function npmignoreExistsInPackageRootDir() { } async function getFilesIgnoredByDotnpmignore(fileList) { - if (!Array.isArray(fileList)) { - throw new TypeError('expected array, but got {typeof fileList}'); - } - const whiteList = await ignoreWalker({ path: pkgDir.sync(), ignoreFiles: ['.npmignore'] }); - - return fileList.filter(minimatch.filter(getGlobPattern(whiteList), + return fileList.filter(minimatch.filter(getIgnoredFilesGlob(whiteList), {matchBase: true})); } -function getFilesNotPartOfFileAttribute(filesFromFileAttribute, fileList) { - if (!Array.isArray(fileList)) { - throw new TypeError(`expected array, but got ${typeof fileList}`); - } - - return fileList.filter(minimatch.filter(getGlobPattern(filesFromFileAttribute), +function getFilesNotIncludedInTheFilesProperty(globArrayFromFilesProperty, fileList) { + return fileList.filter(minimatch.filter(getIgnoredFilesGlob(globArrayFromFilesProperty), {matchBase: true})); } -function getGlobPattern(filesFromFileAttribute) { +function getIgnoredFilesGlob(globArrayFromFilesProperty) { const filesIgnoredByDefault = ['.*.swp', '._*', '.DS_Store', @@ -160,6 +151,5 @@ function getGlobPattern(filesFromFileAttribute) { 'config.gypi', 'CVS', 'npm-debug.log']; - return '!{' + filesFromFileAttribute.join(',') + - ',' + filesIgnoredByDefault.join(',') + '}'; + return `!{${globArrayFromFilesProperty.join(',')},${filesIgnoredByDefault.join(',')}}`; } diff --git a/source/ui.js b/source/ui.js index a172978c..110bad59 100644 --- a/source/ui.js +++ b/source/ui.js @@ -52,13 +52,13 @@ const printCommitLog = async repoUrl => { const confirmIgnoredFiles = async pkg => { const ignoredFiles = await util.getNewAndUnpublishedFiles(pkg); if (ignoredFiles === undefined || ignoredFiles.length === 0) { - return {confirm: true}; + return true; } const answers = await inquirer.prompt([{ type: 'confirm', name: 'confirm', - message: `The following new files are not part of your published package ${ignoredFiles}. Continue?`, + message: `The following new files are not part of your published package:\n${ignoredFiles.join('\n')}\n Continue?`, default: false }]); @@ -74,7 +74,7 @@ module.exports = async (options, pkg) => { if (runPublish) { checkIgnoreStrategy(pkg); const answerIgnoredFiles = await confirmIgnoredFiles(pkg); - if (!answerIgnoredFiles.confirm) { + if (answerIgnoredFiles.confirm === false) { return { ...options, ...answerIgnoredFiles diff --git a/source/util.js b/source/util.js index e8a2cd37..5be78f53 100644 --- a/source/util.js +++ b/source/util.js @@ -66,15 +66,7 @@ exports.getTagVersionPrefix = pMemoize(async options => { } }); -function splitFileNameList(stdout) { - if (typeof stdout !== 'string') { - throw new TypeError('expected parameter stdout of type string'); - } - - return stdout.trim().split('\n').map(row => row.replace(/[|+-]/g, '').trim()); -} - exports.getNewAndUnpublishedFiles = async pkg => { - const ListNewFiles = splitFileNameList(await gitUtil.newFilesSinceLastRelease()); - return npmUtil.getNewAndUnpublishedFiles(ListNewFiles, pkg.files); + const listNewFiles = await gitUtil.newFilesSinceLastRelease(); + return npmUtil.getNewAndUnpublishedFiles(listNewFiles, pkg.files); }; diff --git a/test/ressources/npmignore/.hg b/test/fixtures/npmignore/.hg similarity index 100% rename from test/ressources/npmignore/.hg rename to test/fixtures/npmignore/.hg diff --git a/test/ressources/npmignore/.npmignore b/test/fixtures/npmignore/.npmignore similarity index 100% rename from test/ressources/npmignore/.npmignore rename to test/fixtures/npmignore/.npmignore diff --git a/test/ressources/npmignore/source/ignore.txt b/test/fixtures/npmignore/source/ignore.txt similarity index 100% rename from test/ressources/npmignore/source/ignore.txt rename to test/fixtures/npmignore/source/ignore.txt diff --git a/test/ressources/npmignore/source/pay_attention.txt b/test/fixtures/npmignore/source/pay_attention.txt similarity index 100% rename from test/ressources/npmignore/source/pay_attention.txt rename to test/fixtures/npmignore/source/pay_attention.txt diff --git a/test/ressources/package/.hg b/test/fixtures/package/.hg similarity index 100% rename from test/ressources/package/.hg rename to test/fixtures/package/.hg diff --git a/test/ressources/package/package.json b/test/fixtures/package/package.json similarity index 100% rename from test/ressources/package/package.json rename to test/fixtures/package/package.json diff --git a/test/ressources/package/source/ignore.txt b/test/fixtures/package/source/ignore.txt similarity index 100% rename from test/ressources/package/source/ignore.txt rename to test/fixtures/package/source/ignore.txt diff --git a/test/ressources/package/source/pay_attention.txt b/test/fixtures/package/source/pay_attention.txt similarity index 100% rename from test/ressources/package/source/pay_attention.txt rename to test/fixtures/package/source/pay_attention.txt diff --git a/test/ressources/readme.md b/test/fixtures/readme.md similarity index 100% rename from test/ressources/readme.md rename to test/fixtures/readme.md diff --git a/test/npmignore.js b/test/npmignore.js index 6c2dd1be..aa253f97 100644 --- a/test/npmignore.js +++ b/test/npmignore.js @@ -25,7 +25,7 @@ test.before(() => { mockery.registerMock('./git-util', gitUtilApi); mockery.registerMock('pkg-dir', pkgDirApi); - stubGitUtil.returns((['source/ignore.txt | ++', 'source/pay_attention.txt | --', '.hg | +']).join('\n')); + stubGitUtil.returns(['source/ignore.txt', 'source/pay_attention.txt', '.hg']); mockery.enable({ useCleanCache: true, @@ -52,12 +52,12 @@ test('ignored files using file-attribute in package.json with multiple items', a }); test.serial('ignored files using .npmignore', async t => { - stubPkgDir.returns(path.resolve('test', 'ressources', 'npmignore')); + stubPkgDir.returns(path.resolve('test', 'fixtures', 'npmignore')); t.deepEqual(await moduleUnderTest.getNewAndUnpublishedFiles({name: 'without file-attribute'}), ['source/ignore.txt']); }); test.serial('ignore strategy is not used', async t => { - stubPkgDir.returns(path.resolve('test', 'ressources')); + stubPkgDir.returns(path.resolve('test', 'fixtures')); t.true(await moduleUnderTest.getNewAndUnpublishedFiles({name: 'without file-attribute'}) === undefined); }); From 7cef7cb30cf2e1e80851bee517ecc3f67baa8316 Mon Sep 17 00:00:00 2001 From: Bunyanuch Saengnet Date: Sat, 4 Jan 2020 08:04:30 +0000 Subject: [PATCH 09/33] Show files added since the last release not part of the release package Iteration 4 Added failing unit-test for directories in file-property (package.json) --- test/npmignore.js | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/test/npmignore.js b/test/npmignore.js index aa253f97..b9bd2993 100644 --- a/test/npmignore.js +++ b/test/npmignore.js @@ -41,16 +41,21 @@ test.after(() => { mockery.disable(); }); -test('ignored files using file-attribute in package.json with one item', async t => { +test('ignored files using file-attribute in package.json with one file', async t => { t.deepEqual(await moduleUnderTest.getNewAndUnpublishedFiles({files: ['pay_attention.txt']}), ['source/ignore.txt']); }); -test('ignored files using file-attribute in package.json with multiple items', async t => { +test('ignored files using file-attribute in package.json with multiple file', async t => { t.deepEqual(await moduleUnderTest.getNewAndUnpublishedFiles( {files: ['pay_attention.txt', 'ignore.txt']}), []); }); +test('ignored file using file-attribute in package.json with directory', async t => { + t.deepEqual(await moduleUnderTest.getNewAndUnpublishedFiles( + {files: ['source']}), []); +}); + test.serial('ignored files using .npmignore', async t => { stubPkgDir.returns(path.resolve('test', 'fixtures', 'npmignore')); t.deepEqual(await moduleUnderTest.getNewAndUnpublishedFiles({name: 'without file-attribute'}), From 2827f81e534a451e797b1fd417bc655b362a5333 Mon Sep 17 00:00:00 2001 From: Bunyanuch Saengnet Date: Sat, 4 Jan 2020 09:50:26 +0000 Subject: [PATCH 10/33] Show files added since the last release not part of the release package Iteration 4 Added support for directories in files-property (package.json) --- source/npm/util.js | 13 ++++++++++++- test/fixtures/npmignore/.npmignore | 1 + test/fixtures/npmignore/test/file.txt | 1 + test/npmignore.js | 19 +++++++++++-------- 4 files changed, 25 insertions(+), 9 deletions(-) create mode 100644 test/fixtures/npmignore/test/file.txt diff --git a/source/npm/util.js b/source/npm/util.js index 1b03c1f0..651c7f64 100644 --- a/source/npm/util.js +++ b/source/npm/util.js @@ -135,12 +135,23 @@ async function getFilesIgnoredByDotnpmignore(fileList) { } function getFilesNotIncludedInTheFilesProperty(globArrayFromFilesProperty, fileList) { - return fileList.filter(minimatch.filter(getIgnoredFilesGlob(globArrayFromFilesProperty), + const globArrayForFilesAndDirs = [...globArrayFromFilesProperty]; + const rootDir = pkgDir.sync(); + for (const glob of globArrayFromFilesProperty) { + try { + if (fs.statSync(path.resolve(rootDir, glob)).isDirectory()) { + globArrayForFilesAndDirs.push(`${glob}/**/*`); + } + } catch (_) {} + } + + return fileList.filter(minimatch.filter(getIgnoredFilesGlob(globArrayForFilesAndDirs), {matchBase: true})); } function getIgnoredFilesGlob(globArrayFromFilesProperty) { const filesIgnoredByDefault = ['.*.swp', + '.npmignore', '._*', '.DS_Store', '.hg', diff --git a/test/fixtures/npmignore/.npmignore b/test/fixtures/npmignore/.npmignore index 8ea087a8..501c21cd 100644 --- a/test/fixtures/npmignore/.npmignore +++ b/test/fixtures/npmignore/.npmignore @@ -1 +1,2 @@ ignore.txt +test diff --git a/test/fixtures/npmignore/test/file.txt b/test/fixtures/npmignore/test/file.txt new file mode 100644 index 00000000..375fb8ee --- /dev/null +++ b/test/fixtures/npmignore/test/file.txt @@ -0,0 +1 @@ +ignore this file diff --git a/test/npmignore.js b/test/npmignore.js index b9bd2993..c84ef474 100644 --- a/test/npmignore.js +++ b/test/npmignore.js @@ -25,7 +25,7 @@ test.before(() => { mockery.registerMock('./git-util', gitUtilApi); mockery.registerMock('pkg-dir', pkgDirApi); - stubGitUtil.returns(['source/ignore.txt', 'source/pay_attention.txt', '.hg']); + stubGitUtil.returns(['source/ignore.txt', 'source/pay_attention.txt', '.hg', 'test/file.txt']); mockery.enable({ useCleanCache: true, @@ -41,25 +41,28 @@ test.after(() => { mockery.disable(); }); -test('ignored files using file-attribute in package.json with one file', async t => { +test.serial('ignored files using file-attribute in package.json with one file', async t => { + stubPkgDir.returns(path.resolve('test', 'fixtures', 'package')); t.deepEqual(await moduleUnderTest.getNewAndUnpublishedFiles({files: ['pay_attention.txt']}), - ['source/ignore.txt']); + ['source/ignore.txt', 'test/file.txt']); }); -test('ignored files using file-attribute in package.json with multiple file', async t => { +test.serial('ignored files using file-attribute in package.json with multiple file', async t => { + stubPkgDir.returns(path.resolve('test', 'fixtures', 'package')); t.deepEqual(await moduleUnderTest.getNewAndUnpublishedFiles( - {files: ['pay_attention.txt', 'ignore.txt']}), []); + {files: ['pay_attention.txt', 'ignore.txt']}), ['test/file.txt']); }); -test('ignored file using file-attribute in package.json with directory', async t => { +test.serial('ignored file using file-attribute in package.json with directory', async t => { + stubPkgDir.returns(path.resolve('test', 'fixtures', 'package')); t.deepEqual(await moduleUnderTest.getNewAndUnpublishedFiles( - {files: ['source']}), []); + {files: ['source']}), ['test/file.txt']); }); test.serial('ignored files using .npmignore', async t => { stubPkgDir.returns(path.resolve('test', 'fixtures', 'npmignore')); t.deepEqual(await moduleUnderTest.getNewAndUnpublishedFiles({name: 'without file-attribute'}), - ['source/ignore.txt']); + ['source/ignore.txt', 'test/file.txt']); }); test.serial('ignore strategy is not used', async t => { From da3f1874255f763180ef993f79c0b1a675c4d5da Mon Sep 17 00:00:00 2001 From: Bunyanuch Saengnet <53788417+bunysae@users.noreply.github.com> Date: Sat, 25 Jan 2020 14:39:38 +0000 Subject: [PATCH 11/33] Show files added since the last release not part of the release package Iteration 5 Apply suggestions from code review Co-Authored-By: Itai Steinherz --- source/git-util.js | 4 +--- source/npm/util.js | 39 ++++++++++++++++++++++----------------- source/ui.js | 8 +++++--- source/util.js | 2 +- test/npmignore.js | 20 +++++++++----------- 5 files changed, 38 insertions(+), 35 deletions(-) diff --git a/source/git-util.js b/source/git-util.js index 7a743e4b..d3f0db52 100644 --- a/source/git-util.js +++ b/source/git-util.js @@ -10,9 +10,7 @@ exports.latestTag = async () => { exports.newFilesSinceLastRelease = async () => { const {stdout} = await execa('git', ['diff', '--stat', '--diff-filter=A', await this.latestTag(), 'HEAD']); - const result = stdout.trim().split('\n').map(row => row.slice(0, row.indexOf('|')).trim()); - // Last row contains the conclusion, remove it - result.pop(); + const result = stdout.trim().split('\n').slice(0, -1).map(row => row.slice(0, row.indexOf('|')).trim()); return result; }; diff --git a/source/npm/util.js b/source/npm/util.js index 651c7f64..a9053760 100644 --- a/source/npm/util.js +++ b/source/npm/util.js @@ -109,17 +109,6 @@ exports.checkIgnoreStrategy = ({files}) => { } }; -// Get all files which will be ignored by either `.npmignore` or the `files` property in `package.json` (if defined) -exports.getNewAndUnpublishedFiles = async (newFiles, globArrayFromFilesProperty) => { - if (globArrayFromFilesProperty) { - return getFilesNotIncludedInTheFilesProperty(globArrayFromFilesProperty, newFiles); - } - - if (npmignoreExistsInPackageRootDir()) { - return getFilesIgnoredByDotnpmignore(newFiles); - } -}; - function npmignoreExistsInPackageRootDir() { const rootDir = pkgDir.sync(); return fs.existsSync(path.resolve(rootDir, '.npmignore')); @@ -130,8 +119,7 @@ async function getFilesIgnoredByDotnpmignore(fileList) { path: pkgDir.sync(), ignoreFiles: ['.npmignore'] }); - return fileList.filter(minimatch.filter(getIgnoredFilesGlob(whiteList), - {matchBase: true})); + return fileList.filter(minimatch.filter(getIgnoredFilesGlob(whiteList), {matchBase: true})); } function getFilesNotIncludedInTheFilesProperty(globArrayFromFilesProperty, fileList) { @@ -145,11 +133,14 @@ function getFilesNotIncludedInTheFilesProperty(globArrayFromFilesProperty, fileL } catch (_) {} } - return fileList.filter(minimatch.filter(getIgnoredFilesGlob(globArrayForFilesAndDirs), - {matchBase: true})); + return fileList.filter(minimatch.filter(getIgnoredFilesGlob(globArrayForFilesAndDirs), {matchBase: true})); } function getIgnoredFilesGlob(globArrayFromFilesProperty) { + /* According to https://docs.npmjs.com/files/package.json#files + npm's default behavior is to ignore these files. + They shouldn't be part of the result returned by function + `getNewAndUnpublishedFiles`. */ const filesIgnoredByDefault = ['.*.swp', '.npmignore', '._*', @@ -158,9 +149,23 @@ function getIgnoredFilesGlob(globArrayFromFilesProperty) { '.npmrc', '.lock-wscript', '.svn', - '.wafpickle-*', + '.wafpickle-N', + '*.orig', 'config.gypi', 'CVS', - 'npm-debug.log']; + 'node_modules/**/*', + 'npm-debug.log', + 'package-lock.json']; return `!{${globArrayFromFilesProperty.join(',')},${filesIgnoredByDefault.join(',')}}`; } + +// Get all files which will be ignored by either `.npmignore` or the `files` property in `package.json` (if defined). +exports.getNewAndUnpublishedFiles = async (globArrayFromFilesProperty, newFiles = []) => { + if (globArrayFromFilesProperty) { + return getFilesNotIncludedInTheFilesProperty(globArrayFromFilesProperty, newFiles); + } + + if (npmignoreExistsInPackageRootDir()) { + return getFilesIgnoredByDotnpmignore(newFiles); + } +}; diff --git a/source/ui.js b/source/ui.js index 110bad59..5a9b6bf3 100644 --- a/source/ui.js +++ b/source/ui.js @@ -49,16 +49,18 @@ const printCommitLog = async repoUrl => { }; }; -const confirmIgnoredFiles = async pkg => { +const checkIgnoredFiles = async pkg => { const ignoredFiles = await util.getNewAndUnpublishedFiles(pkg); if (ignoredFiles === undefined || ignoredFiles.length === 0) { return true; } + console.log(`${chalk.bold('The following new files are not part of your published package:')}`); + console.log(`${ignoredFiles.map(path => `- ${path}`).join('\n')}`); const answers = await inquirer.prompt([{ type: 'confirm', name: 'confirm', - message: `The following new files are not part of your published package:\n${ignoredFiles.join('\n')}\n Continue?`, + message: 'Continue?', default: false }]); @@ -73,7 +75,7 @@ module.exports = async (options, pkg) => { if (runPublish) { checkIgnoreStrategy(pkg); - const answerIgnoredFiles = await confirmIgnoredFiles(pkg); + const answerIgnoredFiles = await checkIgnoredFiles(pkg); if (answerIgnoredFiles.confirm === false) { return { ...options, diff --git a/source/util.js b/source/util.js index 5be78f53..b849a09f 100644 --- a/source/util.js +++ b/source/util.js @@ -68,5 +68,5 @@ exports.getTagVersionPrefix = pMemoize(async options => { exports.getNewAndUnpublishedFiles = async pkg => { const listNewFiles = await gitUtil.newFilesSinceLastRelease(); - return npmUtil.getNewAndUnpublishedFiles(listNewFiles, pkg.files); + return npmUtil.getNewAndUnpublishedFiles(pkg.files, listNewFiles); }; diff --git a/test/npmignore.js b/test/npmignore.js index c84ef474..50705430 100644 --- a/test/npmignore.js +++ b/test/npmignore.js @@ -3,16 +3,14 @@ import test from 'ava'; import mockery from 'mockery'; import sinon from 'sinon'; -let moduleUnderTest; +let testedModule; const gitUtilApi = { - async newFilesSinceLastRelease() { - } + newFilesSinceLastRelease: async () => {} }; const pkgDirApi = { - sync() { - } + sync: () => {} }; const stubPkgDir = sinon.stub(pkgDirApi, 'sync'); @@ -33,7 +31,7 @@ test.before(() => { warnOnUnregistered: false }); - moduleUnderTest = require('../source/util'); + testedModule = require('../source/util'); }); test.after(() => { @@ -43,29 +41,29 @@ test.after(() => { test.serial('ignored files using file-attribute in package.json with one file', async t => { stubPkgDir.returns(path.resolve('test', 'fixtures', 'package')); - t.deepEqual(await moduleUnderTest.getNewAndUnpublishedFiles({files: ['pay_attention.txt']}), + t.deepEqual(await testedModule.getNewAndUnpublishedFiles({files: ['pay_attention.txt']}), ['source/ignore.txt', 'test/file.txt']); }); test.serial('ignored files using file-attribute in package.json with multiple file', async t => { stubPkgDir.returns(path.resolve('test', 'fixtures', 'package')); - t.deepEqual(await moduleUnderTest.getNewAndUnpublishedFiles( + t.deepEqual(await testedModule.getNewAndUnpublishedFiles( {files: ['pay_attention.txt', 'ignore.txt']}), ['test/file.txt']); }); test.serial('ignored file using file-attribute in package.json with directory', async t => { stubPkgDir.returns(path.resolve('test', 'fixtures', 'package')); - t.deepEqual(await moduleUnderTest.getNewAndUnpublishedFiles( + t.deepEqual(await testedModule.getNewAndUnpublishedFiles( {files: ['source']}), ['test/file.txt']); }); test.serial('ignored files using .npmignore', async t => { stubPkgDir.returns(path.resolve('test', 'fixtures', 'npmignore')); - t.deepEqual(await moduleUnderTest.getNewAndUnpublishedFiles({name: 'without file-attribute'}), + t.deepEqual(await testedModule.getNewAndUnpublishedFiles({name: 'without file-attribute'}), ['source/ignore.txt', 'test/file.txt']); }); test.serial('ignore strategy is not used', async t => { stubPkgDir.returns(path.resolve('test', 'fixtures')); - t.true(await moduleUnderTest.getNewAndUnpublishedFiles({name: 'without file-attribute'}) === undefined); + t.true(await testedModule.getNewAndUnpublishedFiles({name: 'without file-attribute'}) === undefined); }); From 5db79e4344725664b12317c3d50bcc267b1fe518 Mon Sep 17 00:00:00 2001 From: Bunyanuch Saengnet Date: Tue, 28 Jan 2020 19:52:02 +0000 Subject: [PATCH 12/33] Show files added since the last release not part of the release package Iteration 6 Improve ui and code comments --- source/npm/util.js | 8 +++----- source/ui.js | 4 +--- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/source/npm/util.js b/source/npm/util.js index a9053760..68a25367 100644 --- a/source/npm/util.js +++ b/source/npm/util.js @@ -122,7 +122,7 @@ async function getFilesIgnoredByDotnpmignore(fileList) { return fileList.filter(minimatch.filter(getIgnoredFilesGlob(whiteList), {matchBase: true})); } -function getFilesNotIncludedInTheFilesProperty(globArrayFromFilesProperty, fileList) { +function getFilesNotIncludedInFilesProperty(globArrayFromFilesProperty, fileList) { const globArrayForFilesAndDirs = [...globArrayFromFilesProperty]; const rootDir = pkgDir.sync(); for (const glob of globArrayFromFilesProperty) { @@ -138,9 +138,7 @@ function getFilesNotIncludedInTheFilesProperty(globArrayFromFilesProperty, fileL function getIgnoredFilesGlob(globArrayFromFilesProperty) { /* According to https://docs.npmjs.com/files/package.json#files - npm's default behavior is to ignore these files. - They shouldn't be part of the result returned by function - `getNewAndUnpublishedFiles`. */ + npm's default behavior is to ignore these files. */ const filesIgnoredByDefault = ['.*.swp', '.npmignore', '._*', @@ -162,7 +160,7 @@ function getIgnoredFilesGlob(globArrayFromFilesProperty) { // Get all files which will be ignored by either `.npmignore` or the `files` property in `package.json` (if defined). exports.getNewAndUnpublishedFiles = async (globArrayFromFilesProperty, newFiles = []) => { if (globArrayFromFilesProperty) { - return getFilesNotIncludedInTheFilesProperty(globArrayFromFilesProperty, newFiles); + return getFilesNotIncludedInFilesProperty(globArrayFromFilesProperty, newFiles); } if (npmignoreExistsInPackageRootDir()) { diff --git a/source/ui.js b/source/ui.js index 5a9b6bf3..50cd946a 100644 --- a/source/ui.js +++ b/source/ui.js @@ -55,12 +55,10 @@ const checkIgnoredFiles = async pkg => { return true; } - console.log(`${chalk.bold('The following new files are not part of your published package:')}`); - console.log(`${ignoredFiles.map(path => `- ${path}`).join('\n')}`); const answers = await inquirer.prompt([{ type: 'confirm', name: 'confirm', - message: 'Continue?', + message: `The following new files are not part of your published package:\n${chalk.reset(ignoredFiles.map(path => `- ${path}`).join('\n'))}\nContinue?`, default: false }]); From 786187d7fd1bac17d7cee047db3dc1293921aeea Mon Sep 17 00:00:00 2001 From: Bunyanuch Saengnet Date: Thu, 27 Feb 2020 21:15:13 +0000 Subject: [PATCH 13/33] Show files added since last release refactoring testclass --- test/npmignore.js | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/test/npmignore.js b/test/npmignore.js index 50705430..d71f717a 100644 --- a/test/npmignore.js +++ b/test/npmignore.js @@ -13,8 +13,6 @@ const pkgDirApi = { sync: () => {} }; -const stubPkgDir = sinon.stub(pkgDirApi, 'sync'); - test.before(() => { const stubGitUtil = sinon.stub(gitUtilApi, 'newFilesSinceLastRelease'); @@ -31,6 +29,7 @@ test.before(() => { warnOnUnregistered: false }); + // Mockery has to setup before module is loaded testedModule = require('../source/util'); }); @@ -40,30 +39,40 @@ test.after(() => { }); test.serial('ignored files using file-attribute in package.json with one file', async t => { + const stubPkgDir = sinon.stub(); stubPkgDir.returns(path.resolve('test', 'fixtures', 'package')); + pkgDirApi.sync = stubPkgDir; t.deepEqual(await testedModule.getNewAndUnpublishedFiles({files: ['pay_attention.txt']}), ['source/ignore.txt', 'test/file.txt']); }); test.serial('ignored files using file-attribute in package.json with multiple file', async t => { + const stubPkgDir = sinon.stub(); stubPkgDir.returns(path.resolve('test', 'fixtures', 'package')); + pkgDirApi.sync = stubPkgDir; t.deepEqual(await testedModule.getNewAndUnpublishedFiles( {files: ['pay_attention.txt', 'ignore.txt']}), ['test/file.txt']); }); test.serial('ignored file using file-attribute in package.json with directory', async t => { + const stubPkgDir = sinon.stub(); stubPkgDir.returns(path.resolve('test', 'fixtures', 'package')); + pkgDirApi.sync = stubPkgDir; t.deepEqual(await testedModule.getNewAndUnpublishedFiles( {files: ['source']}), ['test/file.txt']); }); test.serial('ignored files using .npmignore', async t => { + const stubPkgDir = sinon.stub(); stubPkgDir.returns(path.resolve('test', 'fixtures', 'npmignore')); + pkgDirApi.sync = stubPkgDir; t.deepEqual(await testedModule.getNewAndUnpublishedFiles({name: 'without file-attribute'}), ['source/ignore.txt', 'test/file.txt']); }); test.serial('ignore strategy is not used', async t => { + const stubPkgDir = sinon.stub(); stubPkgDir.returns(path.resolve('test', 'fixtures')); + pkgDirApi.sync = stubPkgDir; t.true(await testedModule.getNewAndUnpublishedFiles({name: 'without file-attribute'}) === undefined); }); From 32d0d47e384b512a41825608e7d928b10760b5d6 Mon Sep 17 00:00:00 2001 From: Bunyanuch Saengnet <53788417+bunysae@users.noreply.github.com> Date: Sat, 29 Feb 2020 11:15:51 +0100 Subject: [PATCH 14/33] Refactoring ui Co-Authored-By: Itai Steinherz --- source/ui.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/ui.js b/source/ui.js index e137a80b..b4bfc07c 100644 --- a/source/ui.js +++ b/source/ui.js @@ -51,7 +51,7 @@ const printCommitLog = async (repoUrl, registryUrl) => { const checkIgnoredFiles = async pkg => { const ignoredFiles = await util.getNewAndUnpublishedFiles(pkg); - if (ignoredFiles === undefined || ignoredFiles.length === 0) { + if (!ignoredFiles || ignoredFiles.length === 0) { return true; } @@ -76,7 +76,7 @@ module.exports = async (options, pkg) => { if (runPublish) { checkIgnoreStrategy(pkg); const answerIgnoredFiles = await checkIgnoredFiles(pkg); - if (answerIgnoredFiles.confirm === false) { + if (!answerIgnoredFiles.confirm) { return { ...options, ...answerIgnoredFiles From 71d410f9be78f1d8a9a0ca683613f1e1f253adb6 Mon Sep 17 00:00:00 2001 From: Bunyanuch Saengnet Date: Wed, 8 Jul 2020 14:01:21 +0000 Subject: [PATCH 15/33] Simplify tests --- package.json | 1 - test/npmignore.js | 98 ++++++++++++++++------------------------------- 2 files changed, 33 insertions(+), 66 deletions(-) diff --git a/package.json b/package.json index a586398a..cb491ac2 100644 --- a/package.json +++ b/package.json @@ -70,7 +70,6 @@ "devDependencies": { "ava": "^2.3.0", "proxyquire": "^2.1.0", - "mockery": "^2.1.0", "sinon": "^8.0.1", "xo": "^0.25.3" } diff --git a/test/npmignore.js b/test/npmignore.js index d71f717a..cfc165c0 100644 --- a/test/npmignore.js +++ b/test/npmignore.js @@ -1,78 +1,46 @@ import path from 'path'; import test from 'ava'; -import mockery from 'mockery'; -import sinon from 'sinon'; +import proxyquire from 'proxyquire'; -let testedModule; +const newFiles = ['source/ignore.txt', 'source/pay_attention.txt', '.hg', 'test/file.txt']; -const gitUtilApi = { - newFilesSinceLastRelease: async () => {} -}; - -const pkgDirApi = { - sync: () => {} -}; - -test.before(() => { - const stubGitUtil = sinon.stub(gitUtilApi, 'newFilesSinceLastRelease'); - - mockery.registerAllowable('../source/util'); - mockery.registerAllowable('../source/npm/util'); - mockery.registerMock('./git-util', gitUtilApi); - mockery.registerMock('pkg-dir', pkgDirApi); - - stubGitUtil.returns(['source/ignore.txt', 'source/pay_attention.txt', '.hg', 'test/file.txt']); - - mockery.enable({ - useCleanCache: true, - warnOnReplace: false, - warnOnUnregistered: false +test('ignored files using file-attribute in package.json with one file', async t => { + const testedModule = proxyquire('../source/npm/util', { + 'pkg-dir': + { + sync: () => path.resolve('test', 'fixtures', 'package') + } }); - - // Mockery has to setup before module is loaded - testedModule = require('../source/util'); -}); - -test.after(() => { - mockery.deregisterAll(); - mockery.disable(); -}); - -test.serial('ignored files using file-attribute in package.json with one file', async t => { - const stubPkgDir = sinon.stub(); - stubPkgDir.returns(path.resolve('test', 'fixtures', 'package')); - pkgDirApi.sync = stubPkgDir; - t.deepEqual(await testedModule.getNewAndUnpublishedFiles({files: ['pay_attention.txt']}), + t.deepEqual(await testedModule.getNewAndUnpublishedFiles(['pay_attention.txt'], newFiles), ['source/ignore.txt', 'test/file.txt']); }); -test.serial('ignored files using file-attribute in package.json with multiple file', async t => { - const stubPkgDir = sinon.stub(); - stubPkgDir.returns(path.resolve('test', 'fixtures', 'package')); - pkgDirApi.sync = stubPkgDir; - t.deepEqual(await testedModule.getNewAndUnpublishedFiles( - {files: ['pay_attention.txt', 'ignore.txt']}), ['test/file.txt']); -}); - -test.serial('ignored file using file-attribute in package.json with directory', async t => { - const stubPkgDir = sinon.stub(); - stubPkgDir.returns(path.resolve('test', 'fixtures', 'package')); - pkgDirApi.sync = stubPkgDir; - t.deepEqual(await testedModule.getNewAndUnpublishedFiles( - {files: ['source']}), ['test/file.txt']); +test('ignored file using file-attribute in package.json with directory', async t => { + const testedModule = proxyquire('../source/npm/util', { + 'pkg-dir': + { + sync: () => path.resolve('test', 'fixtures', 'package') + } + }); + t.deepEqual(await testedModule.getNewAndUnpublishedFiles(['source'], newFiles), ['test/file.txt']); }); -test.serial('ignored files using .npmignore', async t => { - const stubPkgDir = sinon.stub(); - stubPkgDir.returns(path.resolve('test', 'fixtures', 'npmignore')); - pkgDirApi.sync = stubPkgDir; - t.deepEqual(await testedModule.getNewAndUnpublishedFiles({name: 'without file-attribute'}), - ['source/ignore.txt', 'test/file.txt']); +test('ignored files using .npmignore', async t => { + const testedModule = proxyquire('../source/npm/util', { + 'pkg-dir': + { + sync: () => path.resolve('test', 'fixtures', 'npmignore') + } + }); + t.deepEqual(await testedModule.getNewAndUnpublishedFiles(undefined, newFiles), ['source/ignore.txt', 'test/file.txt']); }); -test.serial('ignore strategy is not used', async t => { - const stubPkgDir = sinon.stub(); - stubPkgDir.returns(path.resolve('test', 'fixtures')); - pkgDirApi.sync = stubPkgDir; - t.true(await testedModule.getNewAndUnpublishedFiles({name: 'without file-attribute'}) === undefined); +test('ignore strategy is not used', async t => { + const testedModule = proxyquire('../source/npm/util', { + 'pkg-dir': + { + sync: () => path.resolve('test', 'fixtures') + } + }); + t.true(await testedModule.getNewAndUnpublishedFiles(undefined, newFiles) === undefined); }); From d86bf7df637f376239d48d0a95cb3c379ff1b9a7 Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Thu, 16 Jul 2020 00:18:15 +0800 Subject: [PATCH 16/33] Update npmignore.js --- test/npmignore.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/test/npmignore.js b/test/npmignore.js index cfc165c0..2b92b2ee 100644 --- a/test/npmignore.js +++ b/test/npmignore.js @@ -2,7 +2,12 @@ import path from 'path'; import test from 'ava'; import proxyquire from 'proxyquire'; -const newFiles = ['source/ignore.txt', 'source/pay_attention.txt', '.hg', 'test/file.txt']; +const newFiles = [ + 'source/ignore.txt', + 'source/pay_attention.txt', + '.hg', + 'test/file.txt' +]; test('ignored files using file-attribute in package.json with one file', async t => { const testedModule = proxyquire('../source/npm/util', { From c445ff60e60dd4ae4a022905c50de3fad8bf3a80 Mon Sep 17 00:00:00 2001 From: Bunyanuch Saengnet <53788417+bunysae@users.noreply.github.com> Date: Sat, 18 Jul 2020 08:54:16 +0000 Subject: [PATCH 17/33] Apply suggestions from code review Co-authored-by: Sindre Sorhus --- source/npm/util.js | 13 ++++++++----- source/ui.js | 2 +- test/npmignore.js | 2 +- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/source/npm/util.js b/source/npm/util.js index 8583fc83..b7f19c2a 100644 --- a/source/npm/util.js +++ b/source/npm/util.js @@ -140,7 +140,7 @@ async function getFilesIgnoredByDotnpmignore(fileList) { } function getFilesNotIncludedInFilesProperty(globArrayFromFilesProperty, fileList) { - const globArrayForFilesAndDirs = [...globArrayFromFilesProperty]; + const globArrayForFilesAndDirectories = [...globArrayFromFilesProperty]; const rootDir = pkgDir.sync(); for (const glob of globArrayFromFilesProperty) { try { @@ -154,9 +154,10 @@ function getFilesNotIncludedInFilesProperty(globArrayFromFilesProperty, fileList } function getIgnoredFilesGlob(globArrayFromFilesProperty) { - /* According to https://docs.npmjs.com/files/package.json#files - npm's default behavior is to ignore these files. */ - const filesIgnoredByDefault = ['.*.swp', + // According to https://docs.npmjs.com/files/package.json#files + // npm's default behavior is to ignore these files. + const filesIgnoredByDefault = [ + '.*.swp', '.npmignore', '._*', '.DS_Store', @@ -170,7 +171,9 @@ function getIgnoredFilesGlob(globArrayFromFilesProperty) { 'CVS', 'node_modules/**/*', 'npm-debug.log', - 'package-lock.json']; + 'package-lock.json' + ]; + return `!{${globArrayFromFilesProperty.join(',')},${filesIgnoredByDefault.join(',')}}`; } diff --git a/source/ui.js b/source/ui.js index a058e05e..38c5d73e 100644 --- a/source/ui.js +++ b/source/ui.js @@ -59,7 +59,7 @@ const checkIgnoredFiles = async pkg => { const answers = await inquirer.prompt([{ type: 'confirm', name: 'confirm', - message: `The following new files are not part of your published package:\n${chalk.reset(ignoredFiles.map(path => `- ${path}`).join('\n'))}\nContinue?`, + message: `The following new files are not already part of your published package:\n${chalk.reset(ignoredFiles.map(path => `- ${path}`).join('\n'))}\nContinue?`, default: false }]); diff --git a/test/npmignore.js b/test/npmignore.js index 2b92b2ee..d33b7863 100644 --- a/test/npmignore.js +++ b/test/npmignore.js @@ -47,5 +47,5 @@ test('ignore strategy is not used', async t => { sync: () => path.resolve('test', 'fixtures') } }); - t.true(await testedModule.getNewAndUnpublishedFiles(undefined, newFiles) === undefined); + t.is(await testedModule.getNewAndUnpublishedFiles(undefined, newFiles), undefined); }); From 239c61f59e470d7004ed4a29b80870bcbfaab4c4 Mon Sep 17 00:00:00 2001 From: Bunyanuch Saengnet Date: Sat, 18 Jul 2020 14:21:10 +0000 Subject: [PATCH 18/33] 1. Ingore test files 2. take always included files into account 3. add draft for integration test --- integration-test | 1 + package.json | 2 +- source/git-util.js | 16 +++++++++--- source/npm/util.js | 61 ++++++++++++++++++++++++++++++++++----------- source/util.js | 2 +- test/integration.js | 7 ++++++ test/npmignore.js | 31 +++++++++++++++++++---- 7 files changed, 96 insertions(+), 24 deletions(-) create mode 160000 integration-test create mode 100644 test/integration.js diff --git a/integration-test b/integration-test new file mode 160000 index 00000000..ce506e08 --- /dev/null +++ b/integration-test @@ -0,0 +1 @@ +Subproject commit ce506e08ee9016cfc5dd89cfa073a69c4650f290 diff --git a/package.json b/package.json index 736c1496..0ba6aa7a 100644 --- a/package.json +++ b/package.json @@ -42,7 +42,7 @@ "github-url-from-git": "^1.5.0", "has-yarn": "^2.1.0", "hosted-git-info": "^3.0.0", - "ignore-walk": "^3.0.2", + "ignore-walk": "^3.0.3", "inquirer": "^7.0.0", "is-installed-globally": "^0.3.1", "is-scoped": "^2.1.0", diff --git a/source/git-util.js b/source/git-util.js index d3f0db52..76f9d066 100644 --- a/source/git-util.js +++ b/source/git-util.js @@ -1,6 +1,8 @@ 'use strict'; const execa = require('execa'); const escapeStringRegexp = require('escape-string-regexp'); +const ignoreWalker = require('ignore-walk'); +const pkgDir = require('pkg-dir'); const {verifyRequirementSatisfied} = require('./version'); exports.latestTag = async () => { @@ -9,9 +11,17 @@ exports.latestTag = async () => { }; exports.newFilesSinceLastRelease = async () => { - const {stdout} = await execa('git', ['diff', '--stat', '--diff-filter=A', await this.latestTag(), 'HEAD']); - const result = stdout.trim().split('\n').slice(0, -1).map(row => row.slice(0, row.indexOf('|')).trim()); - return result; + try { + const {stdout} = await execa('git', ['diff', '--stat', '--diff-filter=A', await this.latestTag(), 'HEAD']); + const result = stdout.trim().split('\n').slice(0, -1).map(row => row.slice(0, row.indexOf('|')).trim()); + return result; + } catch (_) { + // Get all files under version control + return ignoreWalker({ + path: pkgDir.sync(), + ignoreFiles: ['.gitignore'] + }); + } }; const firstCommit = async () => { diff --git a/source/npm/util.js b/source/npm/util.js index b7f19c2a..9a1e6dfe 100644 --- a/source/npm/util.js +++ b/source/npm/util.js @@ -131,34 +131,55 @@ function npmignoreExistsInPackageRootDir() { return fs.existsSync(path.resolve(rootDir, '.npmignore')); } -async function getFilesIgnoredByDotnpmignore(fileList) { +async function getFilesIgnoredByDotnpmignore(pkg, fileList) { const whiteList = await ignoreWalker({ path: pkgDir.sync(), ignoreFiles: ['.npmignore'] }); - return fileList.filter(minimatch.filter(getIgnoredFilesGlob(whiteList), {matchBase: true})); + return fileList.filter(minimatch.filter(getIgnoredFilesGlob(whiteList, pkg.directories), {matchBase: true})); } -function getFilesNotIncludedInFilesProperty(globArrayFromFilesProperty, fileList) { - const globArrayForFilesAndDirectories = [...globArrayFromFilesProperty]; +function getFilesNotIncludedInFilesProperty(pkg, fileList) { + const globArrayForFilesAndDirectories = [...pkg.files]; const rootDir = pkgDir.sync(); - for (const glob of globArrayFromFilesProperty) { + for (const glob of pkg.files) { try { if (fs.statSync(path.resolve(rootDir, glob)).isDirectory()) { - globArrayForFilesAndDirs.push(`${glob}/**/*`); + globArrayForFilesAndDirectories.push(`${glob}/**/*`); } } catch (_) {} } - return fileList.filter(minimatch.filter(getIgnoredFilesGlob(globArrayForFilesAndDirs), {matchBase: true})); + let result = fileList.filter(minimatch.filter(getIgnoredFilesGlob(globArrayForFilesAndDirectories, pkg.directories), {matchBase: true})); + return result.filter(minimatch.filter(getDefaultIncludedFilesGlob(pkg.main), {nocase: true, matchBase: true})); } -function getIgnoredFilesGlob(globArrayFromFilesProperty) { +function getDefaultIncludedFilesGlob(mainFile) { + // According to https://docs.npmjs.com/files/package.json#files + // npm's default behavior is to always include these files. + const filesAlwaysIncluded = [ + 'package.json', + 'README*', + 'CHANGES*', + 'CHANGELOG*', + 'HISTORY*', + 'LICENSE*', + 'LICENCE*', + 'NOTICE*' + ]; + if (mainFile) { + filesAlwaysIncluded.push(mainFile); + } + return `!{${filesAlwaysIncluded}}`; +} + +function getIgnoredFilesGlob(globArrayFromFilesProperty, packageDirectories) { // According to https://docs.npmjs.com/files/package.json#files // npm's default behavior is to ignore these files. const filesIgnoredByDefault = [ '.*.swp', '.npmignore', + '.gitignore', '._*', '.DS_Store', '.hg', @@ -171,20 +192,32 @@ function getIgnoredFilesGlob(globArrayFromFilesProperty) { 'CVS', 'node_modules/**/*', 'npm-debug.log', - 'package-lock.json' + 'package-lock.json', + '.git/**/*' ]; - return `!{${globArrayFromFilesProperty.join(',')},${filesIgnoredByDefault.join(',')}}`; + // Test files are assumed not to be part of the package + let testDirectoriesGlob = ''; + if (packageDirectories && Array.isArray(packageDirectories.test)) { + testDirectoriesGlob = packageDirectories.test.join(','); + } else if (packageDirectories && typeof packageDirectories.test === 'string') { + testDirectoriesGlob = packageDirectories.test; + } else { + // Fallback to `test` directory + testDirectoriesGlob = 'test/**/*'; + } + + return `!{${globArrayFromFilesProperty.join(',')},${filesIgnoredByDefault.join(',')},${testDirectoriesGlob}}`; } // Get all files which will be ignored by either `.npmignore` or the `files` property in `package.json` (if defined). -exports.getNewAndUnpublishedFiles = async (globArrayFromFilesProperty, newFiles = []) => { - if (globArrayFromFilesProperty) { - return getFilesNotIncludedInFilesProperty(globArrayFromFilesProperty, newFiles); +exports.getNewAndUnpublishedFiles = async (pkg, newFiles = []) => { + if (pkg.files) { + return getFilesNotIncludedInFilesProperty(pkg, newFiles); } if (npmignoreExistsInPackageRootDir()) { - return getFilesIgnoredByDotnpmignore(newFiles); + return getFilesIgnoredByDotnpmignore(pkg, newFiles); } }; diff --git a/source/util.js b/source/util.js index a0a8b92a..12a9c988 100644 --- a/source/util.js +++ b/source/util.js @@ -73,7 +73,7 @@ exports.getTagVersionPrefix = pMemoize(async options => { exports.getNewAndUnpublishedFiles = async pkg => { const listNewFiles = await gitUtil.newFilesSinceLastRelease(); - return npmUtil.getNewAndUnpublishedFiles(pkg.files, listNewFiles); + return npmUtil.getNewAndUnpublishedFiles(pkg, listNewFiles); }; exports.getPreReleasePrefix = pMemoize(async options => { diff --git a/test/integration.js b/test/integration.js new file mode 100644 index 00000000..b1a0b1e1 --- /dev/null +++ b/test/integration.js @@ -0,0 +1,7 @@ +const test = require('ava'); +const execa = require('execa'); + +test('Integration tests', async t => { + await execa('ava', {cwd: 'integration-test'}); + t.pass(); +}); diff --git a/test/npmignore.js b/test/npmignore.js index d33b7863..8af48236 100644 --- a/test/npmignore.js +++ b/test/npmignore.js @@ -16,8 +16,7 @@ test('ignored files using file-attribute in package.json with one file', async t sync: () => path.resolve('test', 'fixtures', 'package') } }); - t.deepEqual(await testedModule.getNewAndUnpublishedFiles(['pay_attention.txt'], newFiles), - ['source/ignore.txt', 'test/file.txt']); + t.deepEqual(await testedModule.getNewAndUnpublishedFiles({files: ['pay_attention.txt']}, newFiles), ['source/ignore.txt']); }); test('ignored file using file-attribute in package.json with directory', async t => { @@ -27,7 +26,18 @@ test('ignored file using file-attribute in package.json with directory', async t sync: () => path.resolve('test', 'fixtures', 'package') } }); - t.deepEqual(await testedModule.getNewAndUnpublishedFiles(['source'], newFiles), ['test/file.txt']); + t.deepEqual(await testedModule.getNewAndUnpublishedFiles({files: ['source']}, newFiles), []); +}); + +test('ignored test files using files attribute and directory structure in package.json', async t => { + const testedModule = proxyquire('../source/npm/util', { + 'pkg-dir': + { + sync: () => path.resolve('test', 'fixtures', 'package') + } + }); + t.deepEqual(await testedModule.getNewAndUnpublishedFiles({files: ['source'], directories: {test: 'test-tap'}}, newFiles), ['test/file.txt']); + t.deepEqual(await testedModule.getNewAndUnpublishedFiles({files: ['source'], directories: {test: ['test-tap']}}, newFiles), ['test/file.txt']); }); test('ignored files using .npmignore', async t => { @@ -37,7 +47,18 @@ test('ignored files using .npmignore', async t => { sync: () => path.resolve('test', 'fixtures', 'npmignore') } }); - t.deepEqual(await testedModule.getNewAndUnpublishedFiles(undefined, newFiles), ['source/ignore.txt', 'test/file.txt']); + t.deepEqual(await testedModule.getNewAndUnpublishedFiles({name: 'npmignore'}, newFiles), ['source/ignore.txt']); +}); + +test('ignored test files using files attribute and .npmignore', async t => { + const testedModule = proxyquire('../source/npm/util', { + 'pkg-dir': + { + sync: () => path.resolve('test', 'fixtures', 'npmignore') + } + }); + t.deepEqual(await testedModule.getNewAndUnpublishedFiles({directories: {test: 'test-tap'}}, newFiles), ['source/ignore.txt', 'test/file.txt']); + t.deepEqual(await testedModule.getNewAndUnpublishedFiles({directories: {test: ['test-tap']}}, newFiles), ['source/ignore.txt', 'test/file.txt']); }); test('ignore strategy is not used', async t => { @@ -47,5 +68,5 @@ test('ignore strategy is not used', async t => { sync: () => path.resolve('test', 'fixtures') } }); - t.is(await testedModule.getNewAndUnpublishedFiles(undefined, newFiles), undefined); + t.is(await testedModule.getNewAndUnpublishedFiles({name: 'no ignore strategy'}, newFiles), undefined); }); From fba3ab4b81020bcd4e9d7f013965ce0cb306796c Mon Sep 17 00:00:00 2001 From: Bunyanuch Saengnet Date: Sat, 18 Jul 2020 14:29:46 +0000 Subject: [PATCH 19/33] Add submodule integration test --- .gitmodules | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .gitmodules diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 00000000..18f98e71 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "integration-test"] + path = integration-test + url = https://github.com/bunysae/np_integration_test From 2fa3cf52ebaf5039e87fdbb890cbea46603df770 Mon Sep 17 00:00:00 2001 From: Bunyanuch Saengnet Date: Sun, 2 Aug 2020 08:33:53 +0000 Subject: [PATCH 20/33] New files since last release: additional test cases --- integration-test | 2 +- source/npm/util.js | 6 ++++-- test/fixtures/npmignore/README.txt | 1 + test/fixtures/npmignore/readme.md | 1 + test/integration.js | 5 +++++ test/npmignore.js | 4 +++- 6 files changed, 15 insertions(+), 4 deletions(-) create mode 100644 test/fixtures/npmignore/README.txt create mode 100644 test/fixtures/npmignore/readme.md diff --git a/integration-test b/integration-test index ce506e08..273bbee5 160000 --- a/integration-test +++ b/integration-test @@ -1 +1 @@ -Subproject commit ce506e08ee9016cfc5dd89cfa073a69c4650f290 +Subproject commit 273bbee5ca55bf7f8bdd9a9c5240d61e5ac97c0b diff --git a/source/npm/util.js b/source/npm/util.js index 9a1e6dfe..c9245989 100644 --- a/source/npm/util.js +++ b/source/npm/util.js @@ -150,7 +150,7 @@ function getFilesNotIncludedInFilesProperty(pkg, fileList) { } catch (_) {} } - let result = fileList.filter(minimatch.filter(getIgnoredFilesGlob(globArrayForFilesAndDirectories, pkg.directories), {matchBase: true})); + const result = fileList.filter(minimatch.filter(getIgnoredFilesGlob(globArrayForFilesAndDirectories, pkg.directories), {matchBase: true})); return result.filter(minimatch.filter(getDefaultIncludedFilesGlob(pkg.main), {nocase: true, matchBase: true})); } @@ -170,6 +170,7 @@ function getDefaultIncludedFilesGlob(mainFile) { if (mainFile) { filesAlwaysIncluded.push(mainFile); } + return `!{${filesAlwaysIncluded}}`; } @@ -193,7 +194,8 @@ function getIgnoredFilesGlob(globArrayFromFilesProperty, packageDirectories) { 'node_modules/**/*', 'npm-debug.log', 'package-lock.json', - '.git/**/*' + '.git/**/*', + '.git' ]; // Test files are assumed not to be part of the package diff --git a/test/fixtures/npmignore/README.txt b/test/fixtures/npmignore/README.txt new file mode 100644 index 00000000..5086e7b4 --- /dev/null +++ b/test/fixtures/npmignore/README.txt @@ -0,0 +1 @@ +File is always included in package. diff --git a/test/fixtures/npmignore/readme.md b/test/fixtures/npmignore/readme.md new file mode 100644 index 00000000..5086e7b4 --- /dev/null +++ b/test/fixtures/npmignore/readme.md @@ -0,0 +1 @@ +File is always included in package. diff --git a/test/integration.js b/test/integration.js index b1a0b1e1..6be08bac 100644 --- a/test/integration.js +++ b/test/integration.js @@ -1,6 +1,11 @@ const test = require('ava'); const execa = require('execa'); +test.before(async () => { + await execa('git', ['submodule', 'update', '--remote']); + await execa('npm', ['i'], {cwd: 'integration-test'}); +}); + test('Integration tests', async t => { await execa('ava', {cwd: 'integration-test'}); t.pass(); diff --git a/test/npmignore.js b/test/npmignore.js index 8af48236..89c11513 100644 --- a/test/npmignore.js +++ b/test/npmignore.js @@ -6,7 +6,9 @@ const newFiles = [ 'source/ignore.txt', 'source/pay_attention.txt', '.hg', - 'test/file.txt' + 'test/file.txt', + 'readme.md', + 'README.txt' ]; test('ignored files using file-attribute in package.json with one file', async t => { From 22b242a016bd7ffce23576f62c270235cdf537f1 Mon Sep 17 00:00:00 2001 From: Bunyanuch Saengnet Date: Sun, 2 Aug 2020 09:08:55 +0000 Subject: [PATCH 21/33] exclude linting submodules --- integration-test | 2 +- package.json | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/integration-test b/integration-test index 273bbee5..d32a0bbd 160000 --- a/integration-test +++ b/integration-test @@ -1 +1 @@ -Subproject commit 273bbee5ca55bf7f8bdd9a9c5240d61e5ac97c0b +Subproject commit d32a0bbd5a14ed1732a3360aa079001f31ed4c1b diff --git a/package.json b/package.json index 0ba6aa7a..93f7e61e 100644 --- a/package.json +++ b/package.json @@ -76,6 +76,11 @@ "sinon": "^8.0.1", "xo": "^0.25.3" }, + "xo": { + "ignores": [ + "integration-test" + ] + }, "ava": { "files": [ "!test/fixtures" From dd5353bcfc5876b6bfb566ac0c9840cc94c553bb Mon Sep 17 00:00:00 2001 From: Bunyanuch Saengnet Date: Sun, 2 Aug 2020 09:14:26 +0000 Subject: [PATCH 22/33] Updating submodule --- integration-test | 2 +- test/integration.js | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/integration-test b/integration-test index d32a0bbd..bd327602 160000 --- a/integration-test +++ b/integration-test @@ -1 +1 @@ -Subproject commit d32a0bbd5a14ed1732a3360aa079001f31ed4c1b +Subproject commit bd327602337f5d682840611637345e8eec2584e4 diff --git a/test/integration.js b/test/integration.js index 6be08bac..34028a9b 100644 --- a/test/integration.js +++ b/test/integration.js @@ -2,7 +2,6 @@ const test = require('ava'); const execa = require('execa'); test.before(async () => { - await execa('git', ['submodule', 'update', '--remote']); await execa('npm', ['i'], {cwd: 'integration-test'}); }); From a082606e7cc71402b9a2b7bf99f9affd0af57a9b Mon Sep 17 00:00:00 2001 From: Bunyanuch Saengnet Date: Sun, 2 Aug 2020 15:48:53 +0000 Subject: [PATCH 23/33] Exclude integration-test from direct invocation --- integration-test | 2 +- package.json | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/integration-test b/integration-test index bd327602..9c824bae 160000 --- a/integration-test +++ b/integration-test @@ -1 +1 @@ -Subproject commit bd327602337f5d682840611637345e8eec2584e4 +Subproject commit 9c824baeb881870b5f2914645ccffb6944613543 diff --git a/package.json b/package.json index 93f7e61e..ebd20130 100644 --- a/package.json +++ b/package.json @@ -83,7 +83,8 @@ }, "ava": { "files": [ - "!test/fixtures" + "!test/fixtures", + "!integration-test" ] } } From f8a550718166fb437e231cf83ff6f797c3f854b0 Mon Sep 17 00:00:00 2001 From: Bunyanuch Saengnet Date: Sun, 2 Aug 2020 16:09:18 +0000 Subject: [PATCH 24/33] Adjust submodule integration-test --- integration-test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integration-test b/integration-test index 9c824bae..bd327602 160000 --- a/integration-test +++ b/integration-test @@ -1 +1 @@ -Subproject commit 9c824baeb881870b5f2914645ccffb6944613543 +Subproject commit bd327602337f5d682840611637345e8eec2584e4 From bd12ee8da9e373b31a535c5b9bfba374ff010f72 Mon Sep 17 00:00:00 2001 From: Bunyanuch Saengnet Date: Sun, 2 Aug 2020 16:34:34 +0000 Subject: [PATCH 25/33] integration-test: cleanup task --- test/integration.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/integration.js b/test/integration.js index 34028a9b..16e16f59 100644 --- a/test/integration.js +++ b/test/integration.js @@ -5,6 +5,10 @@ test.before(async () => { await execa('npm', ['i'], {cwd: 'integration-test'}); }); +test.after.always(async () => { + await execa('git', ['submodule', 'update', '--remote']); +}); + test('Integration tests', async t => { await execa('ava', {cwd: 'integration-test'}); t.pass(); From fa5c3c28097746874fc9c19005f47e73fbd9ec23 Mon Sep 17 00:00:00 2001 From: Bunyanuch Saengnet Date: Sun, 2 Aug 2020 16:46:51 +0000 Subject: [PATCH 26/33] Tweak integration-test --- integration-test | 2 +- package.json | 5 ----- test/integration.js | 4 ---- 3 files changed, 1 insertion(+), 10 deletions(-) diff --git a/integration-test b/integration-test index bd327602..ad5e6e37 160000 --- a/integration-test +++ b/integration-test @@ -1 +1 @@ -Subproject commit bd327602337f5d682840611637345e8eec2584e4 +Subproject commit ad5e6e3776cb3e2b396e7d3f5a6a7a4b5fa0b83e diff --git a/package.json b/package.json index ebd20130..62047642 100644 --- a/package.json +++ b/package.json @@ -76,11 +76,6 @@ "sinon": "^8.0.1", "xo": "^0.25.3" }, - "xo": { - "ignores": [ - "integration-test" - ] - }, "ava": { "files": [ "!test/fixtures", diff --git a/test/integration.js b/test/integration.js index 16e16f59..c486a9a3 100644 --- a/test/integration.js +++ b/test/integration.js @@ -1,10 +1,6 @@ const test = require('ava'); const execa = require('execa'); -test.before(async () => { - await execa('npm', ['i'], {cwd: 'integration-test'}); -}); - test.after.always(async () => { await execa('git', ['submodule', 'update', '--remote']); }); From aa73b47679f07996e6723499b0a8ebfcbff8ee33 Mon Sep 17 00:00:00 2001 From: Bunyanuch Saengnet Date: Tue, 11 Aug 2020 14:09:55 +0000 Subject: [PATCH 27/33] Add published file check to readme --- readme.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/readme.md b/readme.md index 0cb0d4d2..0849e01e 100644 --- a/readme.md +++ b/readme.md @@ -123,6 +123,15 @@ module.exports = { _**Note:** The global config only applies when using the global `np` binary, and is never inherited when using a local binary._ +### Select published files +You can select the published files with the `files` property in `package.json` +or you can use the `.npmignore`-file, to exclude unnecessary stuff. +The selection may exclude some necessary files or vice versa. +To avoid these mistakes, `np` reports all new files added to git, which are not published. +Test files and other [obvious stuff](https://docs.npmjs.com/files/package.json#files) is excluded by default from this report. +`np` assumes either a standard directory layout or a customized layout +depict in the `directories` property (`package.json`). + ## Tips ### npm hooks From 3bb278353cf66af29e9742e5ab4e430e5ca8c563 Mon Sep 17 00:00:00 2001 From: Bunyanuch Saengnet Date: Tue, 11 Aug 2020 14:45:36 +0000 Subject: [PATCH 28/33] fix for dot-files --- source/npm/util.js | 4 ++-- test/npmignore.js | 20 ++++++++++++++++++++ 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/source/npm/util.js b/source/npm/util.js index c9245989..93371291 100644 --- a/source/npm/util.js +++ b/source/npm/util.js @@ -136,7 +136,7 @@ async function getFilesIgnoredByDotnpmignore(pkg, fileList) { path: pkgDir.sync(), ignoreFiles: ['.npmignore'] }); - return fileList.filter(minimatch.filter(getIgnoredFilesGlob(whiteList, pkg.directories), {matchBase: true})); + return fileList.filter(minimatch.filter(getIgnoredFilesGlob(whiteList, pkg.directories), {matchBase: true, dot: true})); } function getFilesNotIncludedInFilesProperty(pkg, fileList) { @@ -150,7 +150,7 @@ function getFilesNotIncludedInFilesProperty(pkg, fileList) { } catch (_) {} } - const result = fileList.filter(minimatch.filter(getIgnoredFilesGlob(globArrayForFilesAndDirectories, pkg.directories), {matchBase: true})); + const result = fileList.filter(minimatch.filter(getIgnoredFilesGlob(globArrayForFilesAndDirectories, pkg.directories), {matchBase: true, dot: true})); return result.filter(minimatch.filter(getDefaultIncludedFilesGlob(pkg.main), {nocase: true, matchBase: true})); } diff --git a/test/npmignore.js b/test/npmignore.js index 89c11513..2769916a 100644 --- a/test/npmignore.js +++ b/test/npmignore.js @@ -63,6 +63,26 @@ test('ignored test files using files attribute and .npmignore', async t => { t.deepEqual(await testedModule.getNewAndUnpublishedFiles({directories: {test: ['test-tap']}}, newFiles), ['source/ignore.txt', 'test/file.txt']); }); +test('dot files using files attribute', async t => { + const testedModule = proxyquire('../source/npm/util', { + 'pkg-dir': + { + sync: () => path.resolve('test', 'fixtures', 'package') + } + }); + t.deepEqual(await testedModule.getNewAndUnpublishedFiles({files: ['source']}, ['test/.dotfile']), []); +}); + +test('dot files using .npmignore', async t => { + const testedModule = proxyquire('../source/npm/util', { + 'pkg-dir': + { + sync: () => path.resolve('test', 'fixtures', 'npmignore') + } + }); + t.deepEqual(await testedModule.getNewAndUnpublishedFiles({}, ['test/.dot']), []); +}); + test('ignore strategy is not used', async t => { const testedModule = proxyquire('../source/npm/util', { 'pkg-dir': From 546aebbc585336125209f953d4abfd991b8324a4 Mon Sep 17 00:00:00 2001 From: Bunyanuch Saengnet Date: Wed, 12 Aug 2020 17:47:33 +0000 Subject: [PATCH 29/33] Fix early exit --- source/ui.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/ui.js b/source/ui.js index 38c5d73e..1570c56f 100644 --- a/source/ui.js +++ b/source/ui.js @@ -63,7 +63,7 @@ const checkIgnoredFiles = async pkg => { default: false }]); - return answers; + return answers.confirm; }; module.exports = async (options, pkg) => { @@ -76,10 +76,10 @@ module.exports = async (options, pkg) => { if (options.runPublish) { checkIgnoreStrategy(pkg); const answerIgnoredFiles = await checkIgnoredFiles(pkg); - if (!answerIgnoredFiles.confirm) { + if (!answerIgnoredFiles) { return { ...options, - ...answerIgnoredFiles + confirm: answerIgnoredFiles }; } } From c0a7b4c7f26f4c87770a197f14385a235ef6f83a Mon Sep 17 00:00:00 2001 From: Bunyanuch Saengnet Date: Sun, 30 Aug 2020 18:18:12 +0000 Subject: [PATCH 30/33] Rewriting readme --- readme.md | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/readme.md b/readme.md index 0849e01e..ddefa53b 100644 --- a/readme.md +++ b/readme.md @@ -123,15 +123,6 @@ module.exports = { _**Note:** The global config only applies when using the global `np` binary, and is never inherited when using a local binary._ -### Select published files -You can select the published files with the `files` property in `package.json` -or you can use the `.npmignore`-file, to exclude unnecessary stuff. -The selection may exclude some necessary files or vice versa. -To avoid these mistakes, `np` reports all new files added to git, which are not published. -Test files and other [obvious stuff](https://docs.npmjs.com/files/package.json#files) is excluded by default from this report. -`np` assumes either a standard directory layout or a customized layout -depict in the `directories` property (`package.json`). - ## Tips ### npm hooks @@ -264,6 +255,11 @@ Host * If you're running into other issues when using SSH, please consult [GitHub's support article](https://help.github.com/articles/connecting-to-github-with-ssh/). +### Ignore strategy +The [ignore strategy](https://docs.npmjs.com/files/package.json#files) either maintained in the `files`-property (`package.json`) or in the `.npmignore`-file should minify your packages. +To ensure package consistency `np` reports all new files added to git, which are not published. Test files and other [obvious stuff](https://docs.npmjs.com/files/package.json#files) isn't considered. +`np` assumes either a standard directory layout or a customized layout depict in the `directories` property (`package.json`). + ## FAQ ### I get an error when publishing my package through Yarn From 7f383bf25d0ca9508103d2f4ee461f383f69e49b Mon Sep 17 00:00:00 2001 From: Bunyanuch Saengnet Date: Sat, 3 Oct 2020 13:57:23 +0200 Subject: [PATCH 31/33] Fix grammar and meaning in readme --- readme.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/readme.md b/readme.md index ddefa53b..de0d886f 100644 --- a/readme.md +++ b/readme.md @@ -256,9 +256,10 @@ Host * If you're running into other issues when using SSH, please consult [GitHub's support article](https://help.github.com/articles/connecting-to-github-with-ssh/). ### Ignore strategy -The [ignore strategy](https://docs.npmjs.com/files/package.json#files) either maintained in the `files`-property (`package.json`) or in the `.npmignore`-file should minify your packages. -To ensure package consistency `np` reports all new files added to git, which are not published. Test files and other [obvious stuff](https://docs.npmjs.com/files/package.json#files) isn't considered. -`np` assumes either a standard directory layout or a customized layout depict in the `directories` property (`package.json`). + +The [ignore strategy](https://docs.npmjs.com/files/package.json#files) either maintained in the `files`-property (`package.json`) or in the `.npmignore`-file should reduce the package size. +To avoid broken packages `np` reports all the new and unpublished files added to git. Test files and other [common files](https://docs.npmjs.com/files/package.json#files), that are never published, aren't considered. +`np` assumes either a standard directory layout or a customized layout represented in the `directories` property (`package.json`). ## FAQ From db59d35b75d55ce8af5f423f2bf87883ac71dee9 Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Thu, 29 Oct 2020 15:44:08 +0100 Subject: [PATCH 32/33] Update readme.md --- readme.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/readme.md b/readme.md index de0d886f..7fbf790f 100644 --- a/readme.md +++ b/readme.md @@ -257,9 +257,7 @@ If you're running into other issues when using SSH, please consult [GitHub's sup ### Ignore strategy -The [ignore strategy](https://docs.npmjs.com/files/package.json#files) either maintained in the `files`-property (`package.json`) or in the `.npmignore`-file should reduce the package size. -To avoid broken packages `np` reports all the new and unpublished files added to git. Test files and other [common files](https://docs.npmjs.com/files/package.json#files), that are never published, aren't considered. -`np` assumes either a standard directory layout or a customized layout represented in the `directories` property (`package.json`). +The [ignore strategy](https://docs.npmjs.com/files/package.json#files), either maintained in the `files`-property in `package.json` or in `.npmignore`, is meant to help reduce the package size. To avoid broken packages caused by essential files being accidentally ignored, `np` prints out all the new and unpublished files added to Git. Test files and other [common files](https://docs.npmjs.com/files/package.json#files) that are never published are not considered. `np` assumes either a standard directory layout or a customized layout represented in the `directories` property in `package.json`. ## FAQ From d7848374834a0e2e41b17e69bb58321704548c42 Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Thu, 29 Oct 2020 15:49:01 +0100 Subject: [PATCH 33/33] Update source/ui.js --- source/ui.js | 1 + 1 file changed, 1 insertion(+) diff --git a/source/ui.js b/source/ui.js index 25756c40..569be234 100644 --- a/source/ui.js +++ b/source/ui.js @@ -75,6 +75,7 @@ module.exports = async (options, pkg) => { if (options.runPublish) { checkIgnoreStrategy(pkg); + const answerIgnoredFiles = await checkIgnoredFiles(pkg); if (!answerIgnoredFiles) { return {