From 9326dca0bf7cf5c5a37a7d1c895881b2414a4a33 Mon Sep 17 00:00:00 2001 From: Michael Garvin Date: Mon, 6 Apr 2026 11:58:29 -0700 Subject: [PATCH] fix: stop auto populating dependencies BREAKING CHANGE: existing packages in `node_modules` are no longer used to try to pre-populate dependencies and devDependencies --- lib/default-input.js | 47 -------------------------------------------- test/dependencies.js | 34 +++++++++++++++++--------------- 2 files changed, 18 insertions(+), 63 deletions(-) diff --git a/lib/default-input.js b/lib/default-input.js index 7b9c8f4..b18bfa7 100644 --- a/lib/default-input.js +++ b/lib/default-input.js @@ -7,47 +7,8 @@ const validateName = require('validate-npm-package-name') const npa = require('npm-package-arg') const semver = require('semver') -// more popular packages should go here, maybe? -const testPkgs = [ - 'coco', - 'coffee-script', - 'expresso', - 'jasmine', - 'jest', - 'mocha', - 'streamline', - 'tap', -] -const isTestPkg = p => testPkgs.includes(p) - const invalid = (msg) => Object.assign(new Error(msg), { notValid: true }) -const readDeps = (test, excluded) => async () => { - const dirs = await fs.readdir('node_modules').catch(() => null) - - if (!dirs) { - return - } - - const deps = {} - for (const dir of dirs) { - if (dir.match(/^\./) || test !== isTestPkg(dir) || excluded[dir]) { - continue - } - - const dp = path.join(dirname, 'node_modules', dir, 'package.json') - const p = await fs.readFile(dp, 'utf8').then((d) => JSON.parse(d)).catch(() => null) - - if (!p || !p.version || p?._requiredBy?.some((r) => r === '#USER')) { - continue - } - - deps[dir] = config.get('save-exact') ? p.version : config.get('save-prefix') + p.version - } - - return deps -} - const getConfig = (key) => { // dots take precedence over dashes const def = config?.defaults?.[`init.${key}`] @@ -167,14 +128,6 @@ exports.directories = async () => { return Object.keys(res).length === 0 ? undefined : res } -if (!package.dependencies) { - exports.dependencies = readDeps(false, package.devDependencies || {}) -} - -if (!package.devDependencies) { - exports.devDependencies = readDeps(true, package.dependencies || {}) -} - // MUST have a test script! if (!package.scripts) { const scripts = package.scripts || {} diff --git a/test/dependencies.js b/test/dependencies.js index 55ee86c..5013a02 100644 --- a/test/dependencies.js +++ b/test/dependencies.js @@ -5,7 +5,7 @@ if (isChild()) { return child({ chdir: true }) } -t.test('read in dependencies and dev deps', async (t) => { +t.test('existing dependencies', async (t) => { const testdirContents = { 'package.json': JSON.stringify({ dependencies: { @@ -16,16 +16,6 @@ t.test('read in dependencies and dev deps', async (t) => { abbrev: '*', }, }), - node_modules: {}, - } - - for (const fakedep of ['mocha', 'tap', 'async', 'foobar']) { - testdirContents.node_modules[fakedep] = { - 'package.json': JSON.stringify({ - name: fakedep, - version: '1.0.0', - }), - } } const { data } = await setup(t, __filename, { @@ -34,23 +24,35 @@ t.test('read in dependencies and dev deps', async (t) => { }) t.same(data, { - name: 'tap-testdir-dependencies-read-in-dependencies-and-dev-deps', + name: 'tap-testdir-dependencies-existing-dependencies', version: '1.0.0', type: 'commonjs', description: '', author: '', - scripts: { test: 'mocha' }, + scripts: { test: 'echo "Error: no test specified" && exit 1' }, main: 'index.js', keywords: [], license: 'ISC', dependencies: { tap: '*', }, - devDependencies: { - mocha: '^1.0.0', - }, optionalDependencies: { abbrev: '*', }, }, 'used the correct dependency information') }) + +t.test('delete empty dependencies', async (t) => { + const testdirContents = { + 'package.json': JSON.stringify({ + dependencies: {}, + }), + } + + const { data } = await setup(t, __filename, { + testdir: testdirContents, + config: { yes: 'yes', 'save-prefix': '^' }, + }) + + t.same(data.dependencies, undefined, 'empty dependencies is removed') +})