From a6ce792079deec63305810766247d90d34106f2b Mon Sep 17 00:00:00 2001 From: Tommy Date: Wed, 5 Apr 2023 10:56:08 -0500 Subject: [PATCH] Get files to be packed via `npm pack --dry-run --json` (#682) --- package.json | 10 +- source/git-util.js | 4 +- source/npm/util.js | 164 ++-------------- source/ui.js | 10 +- source/util.js | 9 +- test/_utils.js | 6 + .../.github/pull_request_template.md | 9 + test/fixtures/files/dot-github/index.js | 1 + test/fixtures/files/dot-github/package.json | 5 + .../files/files-and-npmignore/package.json | 5 + .../files/files-and-npmignore/readme.md | 1 + .../files-and-npmignore/source/.npmignore | 1 + .../files/files-and-npmignore/source/bar.js | 1 + .../files/files-and-npmignore/source/foo.js | 1 + .../files-and-npmignore/source/index.d.ts | 2 + .../source/index.test-d.ts | 5 + test/fixtures/files/files-slash/index.js | 1 + test/fixtures/files/files-slash/package.json | 5 + test/fixtures/files/gitignore/dist/index.js | 2 + test/fixtures/files/gitignore/gitignore | 3 + test/fixtures/files/gitignore/index.d.ts | 1 + test/fixtures/files/gitignore/index.js | 3 + test/fixtures/files/gitignore/index.test-d.ts | 4 + test/fixtures/files/gitignore/package.json | 5 + test/fixtures/files/gitignore/readme.md | 1 + .../files/has-readme-and-license/index.js | 1 + .../files/has-readme-and-license/license.md | 1 + .../files/has-readme-and-license/package.json | 5 + .../files/has-readme-and-license/readme.md | 1 + test/fixtures/files/main/bar.js | 1 + test/fixtures/files/main/foo.js | 1 + test/fixtures/files/main/package.json | 6 + .../files/npmignore-and-gitignore/.npmignore | 2 + .../npmignore-and-gitignore/dist/index.js | 2 + .../files/npmignore-and-gitignore/gitignore | 3 + .../npmignore-and-gitignore/package.json | 4 + .../files/npmignore-and-gitignore/readme.md | 1 + .../npmignore-and-gitignore/script/build.js | 2 + .../npmignore-and-gitignore/source/index.ts | 3 + test/fixtures/files/npmignore/.npmignore | 1 + test/fixtures/files/npmignore/index.d.ts | 1 + test/fixtures/files/npmignore/index.js | 3 + test/fixtures/files/npmignore/index.test-d.ts | 4 + test/fixtures/files/npmignore/package.json | 4 + test/fixtures/files/npmignore/readme.md | 1 + test/fixtures/files/one-file/index.js | 1 + test/fixtures/files/one-file/package.json | 5 + .../files/source-and-dist-dir/dist/index.js | 2 + .../files/source-and-dist-dir/package.json | 5 + .../files/source-and-dist-dir/source/bar.js | 1 + .../files/source-and-dist-dir/source/foo.js | 1 + test/fixtures/files/source-dir/package.json | 5 + test/fixtures/files/source-dir/source/bar.js | 1 + test/fixtures/files/source-dir/source/foo.js | 1 + test/fixtures/npmignore/.hg | 1 - test/fixtures/npmignore/.npmignore | 2 - test/fixtures/npmignore/README.txt | 1 - test/fixtures/npmignore/readme.md | 1 - test/fixtures/npmignore/source/.dotfile | 0 test/fixtures/npmignore/source/ignore.txt | 1 - .../npmignore/source/pay_attention.txt | 1 - test/fixtures/npmignore/test/file.txt | 1 - test/fixtures/package/.hg | 1 - test/fixtures/package/package.json | 3 - test/fixtures/package/source/ignore.txt | 1 - .../fixtures/package/source/pay_attention.txt | 1 - test/integration.js | 184 +++++++++--------- test/new-files.js | 87 +++++++++ test/npmignore.js | 118 ----------- 69 files changed, 343 insertions(+), 388 deletions(-) create mode 100644 test/fixtures/files/dot-github/.github/pull_request_template.md create mode 100644 test/fixtures/files/dot-github/index.js create mode 100644 test/fixtures/files/dot-github/package.json create mode 100644 test/fixtures/files/files-and-npmignore/package.json create mode 100644 test/fixtures/files/files-and-npmignore/readme.md create mode 100644 test/fixtures/files/files-and-npmignore/source/.npmignore create mode 100644 test/fixtures/files/files-and-npmignore/source/bar.js create mode 100644 test/fixtures/files/files-and-npmignore/source/foo.js create mode 100644 test/fixtures/files/files-and-npmignore/source/index.d.ts create mode 100644 test/fixtures/files/files-and-npmignore/source/index.test-d.ts create mode 100644 test/fixtures/files/files-slash/index.js create mode 100644 test/fixtures/files/files-slash/package.json create mode 100644 test/fixtures/files/gitignore/dist/index.js create mode 100644 test/fixtures/files/gitignore/gitignore create mode 100644 test/fixtures/files/gitignore/index.d.ts create mode 100644 test/fixtures/files/gitignore/index.js create mode 100644 test/fixtures/files/gitignore/index.test-d.ts create mode 100644 test/fixtures/files/gitignore/package.json create mode 100644 test/fixtures/files/gitignore/readme.md create mode 100644 test/fixtures/files/has-readme-and-license/index.js create mode 100644 test/fixtures/files/has-readme-and-license/license.md create mode 100644 test/fixtures/files/has-readme-and-license/package.json create mode 100644 test/fixtures/files/has-readme-and-license/readme.md create mode 100644 test/fixtures/files/main/bar.js create mode 100644 test/fixtures/files/main/foo.js create mode 100644 test/fixtures/files/main/package.json create mode 100644 test/fixtures/files/npmignore-and-gitignore/.npmignore create mode 100644 test/fixtures/files/npmignore-and-gitignore/dist/index.js create mode 100644 test/fixtures/files/npmignore-and-gitignore/gitignore create mode 100644 test/fixtures/files/npmignore-and-gitignore/package.json create mode 100644 test/fixtures/files/npmignore-and-gitignore/readme.md create mode 100644 test/fixtures/files/npmignore-and-gitignore/script/build.js create mode 100644 test/fixtures/files/npmignore-and-gitignore/source/index.ts create mode 100644 test/fixtures/files/npmignore/.npmignore create mode 100644 test/fixtures/files/npmignore/index.d.ts create mode 100644 test/fixtures/files/npmignore/index.js create mode 100644 test/fixtures/files/npmignore/index.test-d.ts create mode 100644 test/fixtures/files/npmignore/package.json create mode 100644 test/fixtures/files/npmignore/readme.md create mode 100644 test/fixtures/files/one-file/index.js create mode 100644 test/fixtures/files/one-file/package.json create mode 100644 test/fixtures/files/source-and-dist-dir/dist/index.js create mode 100644 test/fixtures/files/source-and-dist-dir/package.json create mode 100644 test/fixtures/files/source-and-dist-dir/source/bar.js create mode 100644 test/fixtures/files/source-and-dist-dir/source/foo.js create mode 100644 test/fixtures/files/source-dir/package.json create mode 100644 test/fixtures/files/source-dir/source/bar.js create mode 100644 test/fixtures/files/source-dir/source/foo.js delete mode 100644 test/fixtures/npmignore/.hg delete mode 100644 test/fixtures/npmignore/.npmignore delete mode 100644 test/fixtures/npmignore/README.txt delete mode 100644 test/fixtures/npmignore/readme.md delete mode 100644 test/fixtures/npmignore/source/.dotfile delete mode 100644 test/fixtures/npmignore/source/ignore.txt delete mode 100644 test/fixtures/npmignore/source/pay_attention.txt delete mode 100644 test/fixtures/npmignore/test/file.txt delete mode 100644 test/fixtures/package/.hg delete mode 100644 test/fixtures/package/package.json delete mode 100644 test/fixtures/package/source/ignore.txt delete mode 100644 test/fixtures/package/source/pay_attention.txt create mode 100644 test/new-files.js delete mode 100644 test/npmignore.js diff --git a/package.json b/package.json index 219d79d7..920aa6ee 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,7 @@ "yarn": ">=1.7.0" }, "scripts": { - "test": "xo && ava && ava test/integration.js --no-worker-threads" + "test": "xo && ava" }, "files": [ "source" @@ -60,6 +60,7 @@ "ow": "^1.1.1", "p-memoize": "^7.1.1", "p-timeout": "^6.1.1", + "path-exists": "^5.0.0", "pkg-dir": "^7.0.0", "read-pkg-up": "^9.1.0", "rxjs": "^7.8.0", @@ -71,18 +72,17 @@ "devDependencies": { "ava": "^5.2.0", "common-tags": "^1.8.2", - "esmock": "^2.2.0", + "esmock": "^2.2.1", "fs-extra": "^11.1.1", "sinon": "^15.0.3", + "tempy": "^3.0.0", + "write-pkg": "^5.1.0", "xo": "^0.53.1" }, "ava": { "environmentVariables": { "FORCE_HYPERLINK": "1" }, - "files": [ - "!test/integration.js" - ], "nodeArguments": [ "--loader=esmock" ] diff --git a/source/git-util.js b/source/git-util.js index 917655ea..2f76d561 100644 --- a/source/git-util.js +++ b/source/git-util.js @@ -2,7 +2,7 @@ import path from 'node:path'; import {execa} from 'execa'; import escapeStringRegexp from 'escape-string-regexp'; import ignoreWalker from 'ignore-walk'; -import {packageDirectorySync} from 'pkg-dir'; +import {packageDirectory} from 'pkg-dir'; import Version from './version.js'; export const latestTag = async () => { @@ -27,7 +27,7 @@ export const newFilesSinceLastRelease = async () => { } catch { // Get all files under version control return ignoreWalker({ - path: packageDirectorySync(), + path: await packageDirectory(), ignoreFiles: ['.gitignore'], }); } diff --git a/source/npm/util.js b/source/npm/util.js index 0d6582a5..7cf46998 100644 --- a/source/npm/util.js +++ b/source/npm/util.js @@ -1,39 +1,14 @@ -import fs from 'node:fs'; import path from 'node:path'; +import {pathExists} from 'path-exists'; import {execa} from 'execa'; import pTimeout from 'p-timeout'; import ow from 'ow'; import npmName from 'npm-name'; import chalk from 'chalk'; -import {packageDirectorySync} from 'pkg-dir'; -import ignoreWalker from 'ignore-walk'; -import minimatch from 'minimatch'; +import {packageDirectory} from 'pkg-dir'; import semver from 'semver'; import Version from '../version.js'; -// 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', - '.npmrc', - '.lock-wscript', - '.svn', - '.wafpickle-N', - '*.orig', - 'config.gypi', - 'CVS', - 'node_modules/**/*', - 'npm-debug.log', - 'package-lock.json', - '.git/**/*', - '.git', -]; - export const checkConnection = () => pTimeout( (async () => { try { @@ -154,137 +129,24 @@ export const verifyRecentNpmVersion = async () => { Version.verifyRequirementSatisfied('npm', npmVersion); }; -export const checkIgnoreStrategy = ({files}) => { - if (!files && !npmignoreExistsInPackageRootDir()) { +const npmignoreExistsInPackageRootDir = async () => { + const rootDir = await packageDirectory(); + return pathExists(path.resolve(rootDir, '.npmignore')); +}; + +export const checkIgnoreStrategy = async ({files}) => { + if (!files && !(await 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. `); } }; -function npmignoreExistsInPackageRootDir() { - const rootDir = packageDirectorySync(); - return fs.existsSync(path.resolve(rootDir, '.npmignore')); -} - -function excludeGitAndNodeModulesPaths(singlePath) { - return !singlePath.startsWith('.git/') && !singlePath.startsWith('node_modules/'); -} - -async function getFilesIgnoredByDotnpmignore(pkg, fileList) { - let allowList = await ignoreWalker({ - path: packageDirectorySync(), - ignoreFiles: ['.npmignore'], - }); - allowList = allowList.filter(singlePath => excludeGitAndNodeModulesPaths(singlePath)); - return fileList.filter(minimatch.filter(getIgnoredFilesGlob(allowList, pkg.directories), {matchBase: true, dot: true})); -} - -function filterFileList(globArray, fileList) { - if (globArray.length === 0) { - return []; - } - - const globString = globArray.length > 1 ? `{${globArray.filter(singlePath => excludeGitAndNodeModulesPaths(singlePath))}}` : globArray[0]; - return fileList.filter(minimatch.filter(globString, {matchBase: true, dot: true})); // eslint-disable-line unicorn/no-array-callback-reference, unicorn/no-array-method-this-argument -} - -async function getFilesIncludedByDotnpmignore(pkg, fileList) { - const allowList = await ignoreWalker({ - path: packageDirectorySync(), - ignoreFiles: ['.npmignore'], - }); - return filterFileList(allowList, fileList); -} - -function getFilesNotIncludedInFilesProperty(pkg, fileList) { - const globArrayForFilesAndDirectories = [...pkg.files]; - const rootDir = packageDirectorySync(); - for (const glob of pkg.files) { - try { - if (fs.statSync(path.resolve(rootDir, glob)).isDirectory()) { - globArrayForFilesAndDirectories.push(`${glob}/**/*`); - } - } catch {} - } - - 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})); -} - -function getFilesIncludedInFilesProperty(pkg, fileList) { - const globArrayForFilesAndDirectories = [...pkg.files]; - const rootDir = packageDirectorySync(); - for (const glob of pkg.files) { - try { - if (fs.statSync(path.resolve(rootDir, glob)).isDirectory()) { - globArrayForFilesAndDirectories.push(`${glob}/**/*`); - } - } catch {} - } - - return filterFileList(globArrayForFilesAndDirectories, fileList); -} - -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) { - // 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). -export const getNewAndUnpublishedFiles = async (pkg, newFiles = []) => { - if (pkg.files) { - return getFilesNotIncludedInFilesProperty(pkg, newFiles); - } - - if (npmignoreExistsInPackageRootDir()) { - return getFilesIgnoredByDotnpmignore(pkg, newFiles); - } - - return []; -}; - -export const getFirstTimePublishedFiles = async (pkg, newFiles = []) => { - let result; - if (pkg.files) { - result = getFilesIncludedInFilesProperty(pkg, newFiles); - } else if (npmignoreExistsInPackageRootDir()) { - result = await getFilesIncludedByDotnpmignore(pkg, newFiles); - } else { - result = newFiles; - } +export const getFilesToBePacked = async () => { + const {stdout} = await execa('npm', ['pack', '--dry-run', '--json'], {cwd: await packageDirectory()}); - return result.filter(minimatch.filter(`!{${filesIgnoredByDefault}}`, {matchBase: true, dot: true})).filter(minimatch.filter(getDefaultIncludedFilesGlob(pkg.main), {nocase: true, matchBase: true})); + const {files} = JSON.parse(stdout).at(0); + return files.map(file => file.path); }; export const getRegistryUrl = async (pkgManager, pkg) => { diff --git a/source/ui.js b/source/ui.js index 3cbfb213..389cf53e 100644 --- a/source/ui.js +++ b/source/ui.js @@ -6,7 +6,7 @@ import isScoped from 'is-scoped'; import isInteractive from 'is-interactive'; import * as util from './util.js'; import * as git from './git-util.js'; -import {prereleaseTags, checkIgnoreStrategy, getRegistryUrl, isExternalRegistry} from './npm/util.js'; +import * as npmUtil from './npm/util.js'; import Version from './version.js'; import prettyVersionDiff from './pretty-version-diff.js'; @@ -126,11 +126,11 @@ const ui = async (options, {pkg, pkgPath}) => { const extraBaseUrls = ['gitlab.com']; const repoUrl = pkg.repository && githubUrlFromGit(pkg.repository.url, {extraBaseUrls}); const pkgManager = options.yarn ? 'yarn' : 'npm'; - const registryUrl = await getRegistryUrl(pkgManager, pkg); + const registryUrl = await npmUtil.getRegistryUrl(pkgManager, pkg); const releaseBranch = options.branch; if (options.runPublish) { - checkIgnoreStrategy(pkg); + await npmUtil.checkIgnoreStrategy(pkg); const answerIgnoredFiles = await checkNewFilesAndDependencies(pkg, pkgPath); if (!answerIgnoredFiles) { @@ -253,7 +253,7 @@ const ui = async (options, {pkg, pkgPath}) => { message: 'How should this pre-release version be tagged in npm?', when: answers => options.runPublish && (Version.isPrereleaseOrIncrement(answers.customVersion) || Version.isPrereleaseOrIncrement(answers.version)) && !options.tag, async choices() { - const existingPrereleaseTags = await prereleaseTags(pkg.name); + const existingPrereleaseTags = await npmUtil.prereleaseTags(pkg.name); return [ ...existingPrereleaseTags, @@ -283,7 +283,7 @@ const ui = async (options, {pkg, pkgPath}) => { }, publishScoped: { type: 'confirm', - when: isScoped(pkg.name) && options.availability.isAvailable && !options.availability.isUnknown && options.runPublish && (pkg.publishConfig && pkg.publishConfig.access !== 'restricted') && !isExternalRegistry(pkg), + when: isScoped(pkg.name) && options.availability.isAvailable && !options.availability.isUnknown && options.runPublish && (pkg.publishConfig && pkg.publishConfig.access !== 'restricted') && !npmUtil.isExternalRegistry(pkg), message: `This scoped repo ${chalk.bold.magenta(pkg.name)} hasn't been published. Do you want to publish it publicly?`, default: false, }, diff --git a/source/util.js b/source/util.js index b76a4080..88960b55 100644 --- a/source/util.js +++ b/source/util.js @@ -72,9 +72,14 @@ export const getTagVersionPrefix = pMemoize(async options => { export const joinList = list => chalk.reset(list.map(item => `- ${item}`).join('\n')); -export const getNewFiles = async pkg => { +export const getNewFiles = async () => { const listNewFiles = await gitUtil.newFilesSinceLastRelease(); - return {unpublished: await npmUtil.getNewAndUnpublishedFiles(pkg, listNewFiles), firstTime: await npmUtil.getFirstTimePublishedFiles(pkg, listNewFiles)}; + const listPkgFiles = await npmUtil.getFilesToBePacked(); + + return { + unpublished: listNewFiles.filter(file => !listPkgFiles.includes(file) && !file.startsWith('.git')), + firstTime: listNewFiles.filter(file => listPkgFiles.includes(file)), + }; }; export const getNewDependencies = async (newPkg, pkgPath) => { diff --git a/test/_utils.js b/test/_utils.js index 1f9a47f3..f91da530 100644 --- a/test/_utils.js +++ b/test/_utils.js @@ -48,3 +48,9 @@ export const assertTaskDisabled = (t, taskTitle) => { export const assertTaskDoesntExist = (t, taskTitle) => { t.true(SilentRenderer.tasks.every(task => task.title !== taskTitle), `'${taskTitle}' exists!`); }; + +export const runIfExists = async (func, ...args) => { + if (typeof func === 'function') { + await func(...args); + } +}; diff --git a/test/fixtures/files/dot-github/.github/pull_request_template.md b/test/fixtures/files/dot-github/.github/pull_request_template.md new file mode 100644 index 00000000..5c30d3f2 --- /dev/null +++ b/test/fixtures/files/dot-github/.github/pull_request_template.md @@ -0,0 +1,9 @@ + diff --git a/test/fixtures/files/dot-github/index.js b/test/fixtures/files/dot-github/index.js new file mode 100644 index 00000000..81afa315 --- /dev/null +++ b/test/fixtures/files/dot-github/index.js @@ -0,0 +1 @@ +console.log('foo'); diff --git a/test/fixtures/files/dot-github/package.json b/test/fixtures/files/dot-github/package.json new file mode 100644 index 00000000..d08c2333 --- /dev/null +++ b/test/fixtures/files/dot-github/package.json @@ -0,0 +1,5 @@ +{ + "name": "foo", + "version": "0.0.0", + "files": ["index.js"] +} diff --git a/test/fixtures/files/files-and-npmignore/package.json b/test/fixtures/files/files-and-npmignore/package.json new file mode 100644 index 00000000..aa65336d --- /dev/null +++ b/test/fixtures/files/files-and-npmignore/package.json @@ -0,0 +1,5 @@ +{ + "name": "foo", + "version": "0.0.0", + "files": ["source"] +} diff --git a/test/fixtures/files/files-and-npmignore/readme.md b/test/fixtures/files/files-and-npmignore/readme.md new file mode 100644 index 00000000..7635c78e --- /dev/null +++ b/test/fixtures/files/files-and-npmignore/readme.md @@ -0,0 +1 @@ +# Foo diff --git a/test/fixtures/files/files-and-npmignore/source/.npmignore b/test/fixtures/files/files-and-npmignore/source/.npmignore new file mode 100644 index 00000000..b0b0549d --- /dev/null +++ b/test/fixtures/files/files-and-npmignore/source/.npmignore @@ -0,0 +1 @@ +index.test-d.ts diff --git a/test/fixtures/files/files-and-npmignore/source/bar.js b/test/fixtures/files/files-and-npmignore/source/bar.js new file mode 100644 index 00000000..8cc7aa3e --- /dev/null +++ b/test/fixtures/files/files-and-npmignore/source/bar.js @@ -0,0 +1 @@ +console.log('bar'); diff --git a/test/fixtures/files/files-and-npmignore/source/foo.js b/test/fixtures/files/files-and-npmignore/source/foo.js new file mode 100644 index 00000000..81afa315 --- /dev/null +++ b/test/fixtures/files/files-and-npmignore/source/foo.js @@ -0,0 +1 @@ +console.log('foo'); diff --git a/test/fixtures/files/files-and-npmignore/source/index.d.ts b/test/fixtures/files/files-and-npmignore/source/index.d.ts new file mode 100644 index 00000000..ce96e9a6 --- /dev/null +++ b/test/fixtures/files/files-and-npmignore/source/index.d.ts @@ -0,0 +1,2 @@ +export function foo(): string; +export function bar(): string; diff --git a/test/fixtures/files/files-and-npmignore/source/index.test-d.ts b/test/fixtures/files/files-and-npmignore/source/index.test-d.ts new file mode 100644 index 00000000..448777bb --- /dev/null +++ b/test/fixtures/files/files-and-npmignore/source/index.test-d.ts @@ -0,0 +1,5 @@ +import {expectType} from 'tsd'; +import {foo, bar} from '.'; + +expectType(foo()); +expectType(bar()); diff --git a/test/fixtures/files/files-slash/index.js b/test/fixtures/files/files-slash/index.js new file mode 100644 index 00000000..81afa315 --- /dev/null +++ b/test/fixtures/files/files-slash/index.js @@ -0,0 +1 @@ +console.log('foo'); diff --git a/test/fixtures/files/files-slash/package.json b/test/fixtures/files/files-slash/package.json new file mode 100644 index 00000000..850e9c9f --- /dev/null +++ b/test/fixtures/files/files-slash/package.json @@ -0,0 +1,5 @@ +{ + "name": "foo", + "version": "0.0.0", + "files": ["/index.js"] +} diff --git a/test/fixtures/files/gitignore/dist/index.js b/test/fixtures/files/gitignore/dist/index.js new file mode 100644 index 00000000..714c3081 --- /dev/null +++ b/test/fixtures/files/gitignore/dist/index.js @@ -0,0 +1,2 @@ +console.log('foo'); +console.log('bar'); diff --git a/test/fixtures/files/gitignore/gitignore b/test/fixtures/files/gitignore/gitignore new file mode 100644 index 00000000..a01644f5 --- /dev/null +++ b/test/fixtures/files/gitignore/gitignore @@ -0,0 +1,3 @@ +# This file is renamed to `.gitignore` in the test +# This is not named `.gitignore` to allow `dist/` to be committed +dist diff --git a/test/fixtures/files/gitignore/index.d.ts b/test/fixtures/files/gitignore/index.d.ts new file mode 100644 index 00000000..07134df8 --- /dev/null +++ b/test/fixtures/files/gitignore/index.d.ts @@ -0,0 +1 @@ +export default function foo(): string; diff --git a/test/fixtures/files/gitignore/index.js b/test/fixtures/files/gitignore/index.js new file mode 100644 index 00000000..50862df2 --- /dev/null +++ b/test/fixtures/files/gitignore/index.js @@ -0,0 +1,3 @@ +export default function foo() { + return 'bar'; +} diff --git a/test/fixtures/files/gitignore/index.test-d.ts b/test/fixtures/files/gitignore/index.test-d.ts new file mode 100644 index 00000000..650c167e --- /dev/null +++ b/test/fixtures/files/gitignore/index.test-d.ts @@ -0,0 +1,4 @@ +import {expectType} from 'tsd'; +import foo from '.'; + +expectType(foo()); diff --git a/test/fixtures/files/gitignore/package.json b/test/fixtures/files/gitignore/package.json new file mode 100644 index 00000000..745fec5b --- /dev/null +++ b/test/fixtures/files/gitignore/package.json @@ -0,0 +1,5 @@ +{ + "name": "foo", + "version": "0.0.0", + "files": ["dist"] +} diff --git a/test/fixtures/files/gitignore/readme.md b/test/fixtures/files/gitignore/readme.md new file mode 100644 index 00000000..7635c78e --- /dev/null +++ b/test/fixtures/files/gitignore/readme.md @@ -0,0 +1 @@ +# Foo diff --git a/test/fixtures/files/has-readme-and-license/index.js b/test/fixtures/files/has-readme-and-license/index.js new file mode 100644 index 00000000..81afa315 --- /dev/null +++ b/test/fixtures/files/has-readme-and-license/index.js @@ -0,0 +1 @@ +console.log('foo'); diff --git a/test/fixtures/files/has-readme-and-license/license.md b/test/fixtures/files/has-readme-and-license/license.md new file mode 100644 index 00000000..a22a2da2 --- /dev/null +++ b/test/fixtures/files/has-readme-and-license/license.md @@ -0,0 +1 @@ +MIT diff --git a/test/fixtures/files/has-readme-and-license/package.json b/test/fixtures/files/has-readme-and-license/package.json new file mode 100644 index 00000000..d08c2333 --- /dev/null +++ b/test/fixtures/files/has-readme-and-license/package.json @@ -0,0 +1,5 @@ +{ + "name": "foo", + "version": "0.0.0", + "files": ["index.js"] +} diff --git a/test/fixtures/files/has-readme-and-license/readme.md b/test/fixtures/files/has-readme-and-license/readme.md new file mode 100644 index 00000000..7635c78e --- /dev/null +++ b/test/fixtures/files/has-readme-and-license/readme.md @@ -0,0 +1 @@ +# Foo diff --git a/test/fixtures/files/main/bar.js b/test/fixtures/files/main/bar.js new file mode 100644 index 00000000..8cc7aa3e --- /dev/null +++ b/test/fixtures/files/main/bar.js @@ -0,0 +1 @@ +console.log('bar'); diff --git a/test/fixtures/files/main/foo.js b/test/fixtures/files/main/foo.js new file mode 100644 index 00000000..81afa315 --- /dev/null +++ b/test/fixtures/files/main/foo.js @@ -0,0 +1 @@ +console.log('foo'); diff --git a/test/fixtures/files/main/package.json b/test/fixtures/files/main/package.json new file mode 100644 index 00000000..10a4cbd9 --- /dev/null +++ b/test/fixtures/files/main/package.json @@ -0,0 +1,6 @@ +{ + "name": "foo", + "version": "0.0.0", + "main": "foo.js", + "files": ["bar.js"] +} diff --git a/test/fixtures/files/npmignore-and-gitignore/.npmignore b/test/fixtures/files/npmignore-and-gitignore/.npmignore new file mode 100644 index 00000000..7dbdd130 --- /dev/null +++ b/test/fixtures/files/npmignore-and-gitignore/.npmignore @@ -0,0 +1,2 @@ +script/ +source/ diff --git a/test/fixtures/files/npmignore-and-gitignore/dist/index.js b/test/fixtures/files/npmignore-and-gitignore/dist/index.js new file mode 100644 index 00000000..714c3081 --- /dev/null +++ b/test/fixtures/files/npmignore-and-gitignore/dist/index.js @@ -0,0 +1,2 @@ +console.log('foo'); +console.log('bar'); diff --git a/test/fixtures/files/npmignore-and-gitignore/gitignore b/test/fixtures/files/npmignore-and-gitignore/gitignore new file mode 100644 index 00000000..a01644f5 --- /dev/null +++ b/test/fixtures/files/npmignore-and-gitignore/gitignore @@ -0,0 +1,3 @@ +# This file is renamed to `.gitignore` in the test +# This is not named `.gitignore` to allow `dist/` to be committed +dist diff --git a/test/fixtures/files/npmignore-and-gitignore/package.json b/test/fixtures/files/npmignore-and-gitignore/package.json new file mode 100644 index 00000000..3538ae77 --- /dev/null +++ b/test/fixtures/files/npmignore-and-gitignore/package.json @@ -0,0 +1,4 @@ +{ + "name": "foo", + "version": "0.0.0" +} diff --git a/test/fixtures/files/npmignore-and-gitignore/readme.md b/test/fixtures/files/npmignore-and-gitignore/readme.md new file mode 100644 index 00000000..7635c78e --- /dev/null +++ b/test/fixtures/files/npmignore-and-gitignore/readme.md @@ -0,0 +1 @@ +# Foo diff --git a/test/fixtures/files/npmignore-and-gitignore/script/build.js b/test/fixtures/files/npmignore-and-gitignore/script/build.js new file mode 100644 index 00000000..8a2c0921 --- /dev/null +++ b/test/fixtures/files/npmignore-and-gitignore/script/build.js @@ -0,0 +1,2 @@ +/* eslint-disable unicorn/no-empty-file */ +// ... yada yada yada diff --git a/test/fixtures/files/npmignore-and-gitignore/source/index.ts b/test/fixtures/files/npmignore-and-gitignore/source/index.ts new file mode 100644 index 00000000..50862df2 --- /dev/null +++ b/test/fixtures/files/npmignore-and-gitignore/source/index.ts @@ -0,0 +1,3 @@ +export default function foo() { + return 'bar'; +} diff --git a/test/fixtures/files/npmignore/.npmignore b/test/fixtures/files/npmignore/.npmignore new file mode 100644 index 00000000..b0b0549d --- /dev/null +++ b/test/fixtures/files/npmignore/.npmignore @@ -0,0 +1 @@ +index.test-d.ts diff --git a/test/fixtures/files/npmignore/index.d.ts b/test/fixtures/files/npmignore/index.d.ts new file mode 100644 index 00000000..07134df8 --- /dev/null +++ b/test/fixtures/files/npmignore/index.d.ts @@ -0,0 +1 @@ +export default function foo(): string; diff --git a/test/fixtures/files/npmignore/index.js b/test/fixtures/files/npmignore/index.js new file mode 100644 index 00000000..50862df2 --- /dev/null +++ b/test/fixtures/files/npmignore/index.js @@ -0,0 +1,3 @@ +export default function foo() { + return 'bar'; +} diff --git a/test/fixtures/files/npmignore/index.test-d.ts b/test/fixtures/files/npmignore/index.test-d.ts new file mode 100644 index 00000000..650c167e --- /dev/null +++ b/test/fixtures/files/npmignore/index.test-d.ts @@ -0,0 +1,4 @@ +import {expectType} from 'tsd'; +import foo from '.'; + +expectType(foo()); diff --git a/test/fixtures/files/npmignore/package.json b/test/fixtures/files/npmignore/package.json new file mode 100644 index 00000000..3538ae77 --- /dev/null +++ b/test/fixtures/files/npmignore/package.json @@ -0,0 +1,4 @@ +{ + "name": "foo", + "version": "0.0.0" +} diff --git a/test/fixtures/files/npmignore/readme.md b/test/fixtures/files/npmignore/readme.md new file mode 100644 index 00000000..7635c78e --- /dev/null +++ b/test/fixtures/files/npmignore/readme.md @@ -0,0 +1 @@ +# Foo diff --git a/test/fixtures/files/one-file/index.js b/test/fixtures/files/one-file/index.js new file mode 100644 index 00000000..81afa315 --- /dev/null +++ b/test/fixtures/files/one-file/index.js @@ -0,0 +1 @@ +console.log('foo'); diff --git a/test/fixtures/files/one-file/package.json b/test/fixtures/files/one-file/package.json new file mode 100644 index 00000000..d08c2333 --- /dev/null +++ b/test/fixtures/files/one-file/package.json @@ -0,0 +1,5 @@ +{ + "name": "foo", + "version": "0.0.0", + "files": ["index.js"] +} diff --git a/test/fixtures/files/source-and-dist-dir/dist/index.js b/test/fixtures/files/source-and-dist-dir/dist/index.js new file mode 100644 index 00000000..714c3081 --- /dev/null +++ b/test/fixtures/files/source-and-dist-dir/dist/index.js @@ -0,0 +1,2 @@ +console.log('foo'); +console.log('bar'); diff --git a/test/fixtures/files/source-and-dist-dir/package.json b/test/fixtures/files/source-and-dist-dir/package.json new file mode 100644 index 00000000..aa65336d --- /dev/null +++ b/test/fixtures/files/source-and-dist-dir/package.json @@ -0,0 +1,5 @@ +{ + "name": "foo", + "version": "0.0.0", + "files": ["source"] +} diff --git a/test/fixtures/files/source-and-dist-dir/source/bar.js b/test/fixtures/files/source-and-dist-dir/source/bar.js new file mode 100644 index 00000000..8cc7aa3e --- /dev/null +++ b/test/fixtures/files/source-and-dist-dir/source/bar.js @@ -0,0 +1 @@ +console.log('bar'); diff --git a/test/fixtures/files/source-and-dist-dir/source/foo.js b/test/fixtures/files/source-and-dist-dir/source/foo.js new file mode 100644 index 00000000..81afa315 --- /dev/null +++ b/test/fixtures/files/source-and-dist-dir/source/foo.js @@ -0,0 +1 @@ +console.log('foo'); diff --git a/test/fixtures/files/source-dir/package.json b/test/fixtures/files/source-dir/package.json new file mode 100644 index 00000000..aa65336d --- /dev/null +++ b/test/fixtures/files/source-dir/package.json @@ -0,0 +1,5 @@ +{ + "name": "foo", + "version": "0.0.0", + "files": ["source"] +} diff --git a/test/fixtures/files/source-dir/source/bar.js b/test/fixtures/files/source-dir/source/bar.js new file mode 100644 index 00000000..8cc7aa3e --- /dev/null +++ b/test/fixtures/files/source-dir/source/bar.js @@ -0,0 +1 @@ +console.log('bar'); diff --git a/test/fixtures/files/source-dir/source/foo.js b/test/fixtures/files/source-dir/source/foo.js new file mode 100644 index 00000000..81afa315 --- /dev/null +++ b/test/fixtures/files/source-dir/source/foo.js @@ -0,0 +1 @@ +console.log('foo'); diff --git a/test/fixtures/npmignore/.hg b/test/fixtures/npmignore/.hg deleted file mode 100644 index 3f06d3e2..00000000 --- a/test/fixtures/npmignore/.hg +++ /dev/null @@ -1 +0,0 @@ -should be ignored by default diff --git a/test/fixtures/npmignore/.npmignore b/test/fixtures/npmignore/.npmignore deleted file mode 100644 index 501c21cd..00000000 --- a/test/fixtures/npmignore/.npmignore +++ /dev/null @@ -1,2 +0,0 @@ -ignore.txt -test diff --git a/test/fixtures/npmignore/README.txt b/test/fixtures/npmignore/README.txt deleted file mode 100644 index 5086e7b4..00000000 --- a/test/fixtures/npmignore/README.txt +++ /dev/null @@ -1 +0,0 @@ -File is always included in package. diff --git a/test/fixtures/npmignore/readme.md b/test/fixtures/npmignore/readme.md deleted file mode 100644 index 5086e7b4..00000000 --- a/test/fixtures/npmignore/readme.md +++ /dev/null @@ -1 +0,0 @@ -File is always included in package. diff --git a/test/fixtures/npmignore/source/.dotfile b/test/fixtures/npmignore/source/.dotfile deleted file mode 100644 index e69de29b..00000000 diff --git a/test/fixtures/npmignore/source/ignore.txt b/test/fixtures/npmignore/source/ignore.txt deleted file mode 100644 index 26ef7633..00000000 --- a/test/fixtures/npmignore/source/ignore.txt +++ /dev/null @@ -1 +0,0 @@ -Ignore this file diff --git a/test/fixtures/npmignore/source/pay_attention.txt b/test/fixtures/npmignore/source/pay_attention.txt deleted file mode 100644 index 01a573f9..00000000 --- a/test/fixtures/npmignore/source/pay_attention.txt +++ /dev/null @@ -1 +0,0 @@ -File is excluded from .npmignore diff --git a/test/fixtures/npmignore/test/file.txt b/test/fixtures/npmignore/test/file.txt deleted file mode 100644 index 375fb8ee..00000000 --- a/test/fixtures/npmignore/test/file.txt +++ /dev/null @@ -1 +0,0 @@ -ignore this file diff --git a/test/fixtures/package/.hg b/test/fixtures/package/.hg deleted file mode 100644 index 3f06d3e2..00000000 --- a/test/fixtures/package/.hg +++ /dev/null @@ -1 +0,0 @@ -should be ignored by default diff --git a/test/fixtures/package/package.json b/test/fixtures/package/package.json deleted file mode 100644 index b2861deb..00000000 --- a/test/fixtures/package/package.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "files": ["pay_attention.txt"] -} diff --git a/test/fixtures/package/source/ignore.txt b/test/fixtures/package/source/ignore.txt deleted file mode 100644 index 40f91d34..00000000 --- a/test/fixtures/package/source/ignore.txt +++ /dev/null @@ -1 +0,0 @@ -File is excluded from package.json diff --git a/test/fixtures/package/source/pay_attention.txt b/test/fixtures/package/source/pay_attention.txt deleted file mode 100644 index e5f3e01f..00000000 --- a/test/fixtures/package/source/pay_attention.txt +++ /dev/null @@ -1 +0,0 @@ -File in included in package.json diff --git a/test/integration.js b/test/integration.js index 83d43d6e..25abc62b 100644 --- a/test/integration.js +++ b/test/integration.js @@ -1,104 +1,106 @@ -/* eslint-disable ava/no-ignored-test-files */ -import process from 'node:process'; import path from 'node:path'; import fs from 'fs-extra'; import test from 'ava'; -import {$} from 'execa'; -import {deleteAsync} from 'del'; -import * as gitUtil from '../source/git-util.js'; -import * as util from '../source/util.js'; - -test.before(async t => { - await fs.emptyDir('integration'); - process.chdir('integration'); - - await $`git init`; - await t.throwsAsync(gitUtil.latestTag(), undefined, 'prerequisites not met: repository should not contain any tags'); - - await fs.createFile('temp'); - await $`git add .`; - await $`git commit -m 'init'`; - await deleteAsync('temp'); +import esmock from 'esmock'; +import {$, execa} from 'execa'; +import {temporaryDirectoryTask} from 'tempy'; +import {writePackage} from 'write-pkg'; + +const createEmptyGitRepo = async ($$, temporaryDir) => { + await $$`git init`; + + // `git tag` needs an initial commit + await fs.createFile(path.resolve(temporaryDir, 'temp')); + await $$`git add temp`; + await $$`git commit -m "init1"`; + await $$`git rm temp`; + await $$`git commit -m "init2"`; +}; + +const createIntegrationTest = async (t, assertions) => { + await temporaryDirectoryTask(async temporaryDir => { + const $$ = $({cwd: temporaryDir}); + + await createEmptyGitRepo($$, temporaryDir); + + t.context.createFile = async file => fs.createFile(path.resolve(temporaryDir, file)); + await assertions($$, temporaryDir); + }); +}; + +test('main', async t => { + await createIntegrationTest(t, async $$ => { + await t.context.createFile('testFile'); + + const {stdout} = await $$`git status -u`; + + t.true( + stdout.includes('Untracked files') && stdout.includes('testFile'), + 'File wasn\'t created properly!', + ); + }); }); -test.after.always(async () => { - process.chdir('..'); - await deleteAsync('integration'); +const createFixture = test.macro(async (t, pkgFiles, commands, {unpublished, firstTime}) => { + await createIntegrationTest(t, async ($$, temporaryDir) => { + /** @type {import('../source/util.js')} */ + const util = await esmock('../source/util.js', {}, { + 'node:process': {cwd: () => temporaryDir}, + execa: {execa: async (...args) => execa(...args, {cwd: temporaryDir})}, + 'pkg-dir': {packageDirectory: async () => temporaryDir}, + }); + + await commands(t, $$, temporaryDir); + + await writePackage(temporaryDir, { + name: 'foo', + version: '0.0.0', + ...pkgFiles.length > 0 ? {files: pkgFiles} : {}, + }); + + t.deepEqual( + await util.getNewFiles(), + {unpublished, firstTime}, + ); + }); }); -test.afterEach.always(async t => { - if (typeof t.context.teardown === 'function') { - await t.context.teardown(); - } -}); - -test.serial('files to package with tags added', async t => { - await $`git tag v0.0.0`; - await fs.createFile('new'); - await fs.createFile('index.js'); - await $`git add new index.js`; - await $`git commit -m "added"`; - - t.context.teardown = async () => { - await $`git rm new`; - await $`git rm index.js`; - await $`git tag -d v0.0.0`; - await $`git commit -m "deleted"`; - }; - - t.deepEqual( - await util.getNewFiles({files: ['*.js']}), - {unpublished: ['new'], firstTime: ['index.js']}, - ); -}); +test('files to package with tags added', createFixture, ['*.js'], async (t, $$) => { + await $$`git tag v0.0.0`; + await t.context.createFile('new'); + await t.context.createFile('index.js'); + await $$`git add -A`; + await $$`git commit -m "added"`; +}, {unpublished: ['new'], firstTime: ['index.js']}); -test.serial.failing('file `new` to package without tags added', async t => { - await fs.createFile('new'); - await fs.createFile('index.js'); - - t.context.teardown = async () => { - await deleteAsync(['new', 'index.js']); - }; - - t.deepEqual( - await util.getNewFiles({files: ['index.js']}), - {unpublished: ['new'], firstTime: ['index.js']}, - ); -}); +test('file `new` to package without tags added', createFixture, ['index.js'], async t => { + await t.context.createFile('new'); + await t.context.createFile('index.js'); +}, {unpublished: ['new'], firstTime: ['index.js', 'package.json']}); -test.serial('files with long pathnames added', async t => { +(() => { // Wrapper to have constants with macro const longPath = path.join('veryLonggggggDirectoryName', 'veryLonggggggDirectoryName'); const filePath1 = path.join(longPath, 'file1'); const filePath2 = path.join(longPath, 'file2'); - await $`git tag v0.0.0`; - await fs.mkdir(longPath, {recursive: true}); - await fs.createFile(filePath1); - await fs.createFile(filePath2); - await $`git add ${filePath1} ${filePath2}`; - await $`git commit -m "added"`; - - t.context.teardown = async () => { - await $`git rm -r ${longPath}`; - await $`git tag -d v0.0.0`; - await $`git commit -m "deleted"`; - }; - - t.deepEqual( - await util.getNewFiles({files: ['*.js']}), - {unpublished: [filePath1, filePath2], firstTime: []}, - ); -}); - -test.serial('no new files added', async t => { - await $`git tag v0.0.0`; - - t.context.teardown = async () => { - await $`git tag -d v0.0.0`; - }; - - t.deepEqual( - await util.getNewFiles({files: ['*.js']}), - {unpublished: [], firstTime: []}, - ); -}); + test('files with long pathnames added', createFixture, ['*.js'], async (t, $$) => { + await $$`git tag v0.0.0`; + await t.context.createFile(filePath1); + await t.context.createFile(filePath2); + await $$`git add -A`; + await $$`git commit -m "added"`; + }, {unpublished: [filePath1, filePath2], firstTime: []}); +})(); + +test('no new files added', createFixture, [], async (_t, $$) => { + await $$`git tag v0.0.0`; +}, {unpublished: [], firstTime: []}); + +test('ignores .git and .github files', createFixture, ['*.js'], async (t, $$) => { + await $$`git tag v0.0.0`; + await t.context.createFile('.github/workflows/main.yml'); + await t.context.createFile('.github/pull_request_template'); + await t.context.createFile('index.js'); + await $$`git add -A`; + await $$`git commit -m "added"`; +}, {unpublished: [], firstTime: ['index.js']}); diff --git a/test/new-files.js b/test/new-files.js new file mode 100644 index 00000000..66da1f0e --- /dev/null +++ b/test/new-files.js @@ -0,0 +1,87 @@ +import path from 'node:path'; +import fs from 'node:fs/promises'; +import test from 'ava'; +import esmock from 'esmock'; +import {runIfExists} from './_utils.js'; + +const getFixture = name => path.resolve('test', 'fixtures', 'files', name); + +const mockPkgDir = test.macro(async (t, fixture, expectedFiles, {before, after} = {}) => { + const fixtureDir = getFixture(fixture); + + await runIfExists(before, fixtureDir); + t.teardown(async () => runIfExists(after, fixtureDir)); + + const npmUtil = await esmock('../source/npm/util.js', { + 'pkg-dir': {packageDirectory: async () => fixtureDir}, + }); + + const files = await npmUtil.getFilesToBePacked(); + t.deepEqual(files.sort(), [...expectedFiles, 'package.json'].sort(), 'Files different from expectations!'); +}); + +test('package.json files field - one file', mockPkgDir, 'one-file', [ + 'index.js', +]); + +test('package.json files field - source dir', mockPkgDir, 'source-dir', [ + 'source/foo.js', + 'source/bar.js', +]); + +test('package.json files field - source and dist dirs', mockPkgDir, 'source-and-dist-dir', [ + 'source/foo.js', + 'source/bar.js', +]); + +test('package.json files field - leading slash', mockPkgDir, 'files-slash', [ + 'index.js', +]); + +test('package.json files field - has readme and license', mockPkgDir, 'has-readme-and-license', [ + 'readme.md', + 'license.md', + 'index.js', +]); + +test('npmignore', mockPkgDir, 'npmignore', [ + 'readme.md', + 'index.js', + 'index.d.ts', +]); + +test('package.json files field and npmignore', mockPkgDir, 'files-and-npmignore', [ + 'readme.md', + 'source/foo.js', + 'source/bar.js', + 'source/index.d.ts', +]); + +const renameDotGitignore = { + async before(fixtureDir) { + await fs.rename(`${fixtureDir}/gitignore`, `${fixtureDir}/.gitignore`); + }, + async after(fixtureDir) { + await fs.rename(`${fixtureDir}/.gitignore`, `${fixtureDir}/gitignore`); + }, +}; + +test('package.json files field and gitignore', mockPkgDir, 'gitignore', [ + 'readme.md', + 'dist/index.js', +], renameDotGitignore); + +test('npmignore and gitignore', mockPkgDir, 'npmignore-and-gitignore', [ + 'readme.md', + 'dist/index.js', +], renameDotGitignore); + +test('package.json main field not in files field', mockPkgDir, 'main', [ + 'foo.js', + 'bar.js', +]); + +test('doesn\'t show files in .github', mockPkgDir, 'dot-github', [ + 'index.js', +]); + diff --git a/test/npmignore.js b/test/npmignore.js deleted file mode 100644 index 4f02492a..00000000 --- a/test/npmignore.js +++ /dev/null @@ -1,118 +0,0 @@ -import path from 'node:path'; -import test from 'ava'; -import esmock from 'esmock'; - -const newFiles = [ - 'source/ignore.txt', - 'source/pay_attention.txt', - '.hg', - 'test/file.txt', - 'readme.md', - 'README.txt', -]; - -const mockPkgDir = test.macro(async (t, paths, impl) => { - const testedModule = await esmock('../source/npm/util.js', { - 'pkg-dir': {packageDirectorySync: () => path.resolve(...paths)}, - }); - - await impl(t, testedModule); -}); - -test.serial('ignored files using file-attribute in package.json with one file', mockPkgDir, ['test', 'fixtures', 'package'], - async (t, {getNewAndUnpublishedFiles}) => { - t.deepEqual(await getNewAndUnpublishedFiles({files: ['pay_attention.txt']}, newFiles), ['source/ignore.txt']); - }, -); - -test.serial('ignored file using file-attribute in package.json with directory', mockPkgDir, ['test', 'fixtures', 'package'], - async (t, {getNewAndUnpublishedFiles}) => { - t.deepEqual(await getNewAndUnpublishedFiles({files: ['source']}, newFiles), []); - }, -); - -test.serial('ignored test files using files attribute and directory structure in package.json', mockPkgDir, ['test', 'fixtures', 'package'], - async (t, {getNewAndUnpublishedFiles}) => { - t.deepEqual(await getNewAndUnpublishedFiles({files: ['source'], directories: {test: 'test-tap'}}, newFiles), ['test/file.txt']); - t.deepEqual(await getNewAndUnpublishedFiles({files: ['source'], directories: {test: ['test-tap']}}, newFiles), ['test/file.txt']); - }, -); - -test.serial('ignored files using .npmignore', mockPkgDir, ['test', 'fixtures', 'npmignore'], - async (t, {getNewAndUnpublishedFiles}) => { - t.deepEqual(await getNewAndUnpublishedFiles({name: 'npmignore'}, newFiles), ['source/ignore.txt']); - }, -); - -test.serial('ignored test files using files attribute and .npmignore', mockPkgDir, ['test', 'fixtures', 'npmignore'], - async (t, {getNewAndUnpublishedFiles}) => { - t.deepEqual(await getNewAndUnpublishedFiles({directories: {test: 'test-tap'}}, newFiles), ['source/ignore.txt', 'test/file.txt']); - t.deepEqual(await getNewAndUnpublishedFiles({directories: {test: ['test-tap']}}, newFiles), ['source/ignore.txt', 'test/file.txt']); - }, -); - -test.serial('ignored files - dot files using files attribute', mockPkgDir, ['test', 'fixtures', 'package'], - async (t, {getNewAndUnpublishedFiles}) => { - t.deepEqual(await getNewAndUnpublishedFiles({files: ['source']}, ['test/.dotfile']), []); - }, -); - -test.serial('ignored files - dot files using .npmignore', mockPkgDir, ['test', 'fixtures', 'npmignore'], - async (t, {getNewAndUnpublishedFiles}) => { - t.deepEqual(await getNewAndUnpublishedFiles({}, ['test/.dot']), []); - }, -); - -test.serial('ignored files - ignore strategy is not used', mockPkgDir, ['test', 'fixtures'], - async (t, {getNewAndUnpublishedFiles}) => { - t.deepEqual(await getNewAndUnpublishedFiles({name: 'no ignore strategy'}, newFiles), []); - }, -); - -test.serial('first time published files using file-attribute in package.json with one file', mockPkgDir, ['test', 'fixtures', 'package'], - async (t, {getFirstTimePublishedFiles}) => { - t.deepEqual(await getFirstTimePublishedFiles({files: ['pay_attention.txt']}, newFiles), ['source/pay_attention.txt']); - }, -); - -test.serial('first time published files using file-attribute in package.json with directory', mockPkgDir, ['test', 'fixtures', 'package'], - async (t, {getFirstTimePublishedFiles}) => { - t.deepEqual(await getFirstTimePublishedFiles({files: ['source']}, newFiles), ['source/ignore.txt', 'source/pay_attention.txt']); - }, -); - -test.serial('first time published files using .npmignore', mockPkgDir, ['test', 'fixtures', 'npmignore'], - async (t, {getFirstTimePublishedFiles}) => { - t.deepEqual(await getFirstTimePublishedFiles({name: 'npmignore'}, newFiles), ['source/pay_attention.txt']); - }, -); - -test.serial('first time published dot files using files attribute', mockPkgDir, ['test', 'fixtures', 'package'], - async (t, {getFirstTimePublishedFiles}) => { - t.deepEqual(await getFirstTimePublishedFiles({files: ['source']}, ['source/.dotfile']), ['source/.dotfile']); - }, -); - -test.serial('first time published dot files using .npmignore', mockPkgDir, ['test', 'fixtures', 'npmignore'], - async (t, {getFirstTimePublishedFiles}) => { - t.deepEqual(await getFirstTimePublishedFiles({}, ['source/.dotfile']), ['source/.dotfile']); - }, -); - -test.serial('first time published files - ignore strategy is not used', mockPkgDir, ['test', 'fixtures'], - async (t, {getFirstTimePublishedFiles}) => { - t.deepEqual(await getFirstTimePublishedFiles({name: 'no ignore strategy'}, newFiles), ['source/ignore.txt', 'source/pay_attention.txt', 'test/file.txt']); - }, -); - -test.serial('first time published files - empty files property', mockPkgDir, ['test', 'fixtures', 'package'], - async (t, {getFirstTimePublishedFiles}) => { - t.deepEqual(await getFirstTimePublishedFiles({files: []}, newFiles), []); - }, -); - -test.serial('first time published files - .npmignore excludes everything', mockPkgDir, ['test', 'fixtures', 'npmignore'], - async (t, {getFirstTimePublishedFiles}) => { - t.deepEqual(await getFirstTimePublishedFiles({name: 'excluded everything'}, ['source/ignore.txt']), []); - }, -);