From c46951f3fe8761da5966004ba17cb99030fc1f17 Mon Sep 17 00:00:00 2001 From: Bert De Block Date: Thu, 12 Dec 2024 14:04:37 +0100 Subject: [PATCH] Introduce a BaseAdapter class to remove all duplication --- lib/dependency-manager-adapters/base.js | 177 ++++++++++++++++++ lib/dependency-manager-adapters/npm.js | 175 +---------------- lib/dependency-manager-adapters/pnpm.js | 160 ++-------------- lib/dependency-manager-adapters/workspace.js | 11 +- lib/dependency-manager-adapters/yarn.js | 155 +-------------- lib/utils/package-managers.js | 9 + package.json | 1 + .../npm-adapter-test.js | 6 +- .../pnpm-adapter-test.js | 16 +- .../workspace-adapter-test.js | 2 +- .../yarn-adapter-test.js | 6 +- test/tasks/try-each-test.js | 2 +- yarn.lock | 5 + 13 files changed, 245 insertions(+), 480 deletions(-) create mode 100644 lib/dependency-manager-adapters/base.js create mode 100644 lib/utils/package-managers.js diff --git a/lib/dependency-manager-adapters/base.js b/lib/dependency-manager-adapters/base.js new file mode 100644 index 00000000..cb95f5fa --- /dev/null +++ b/lib/dependency-manager-adapters/base.js @@ -0,0 +1,177 @@ +'use strict'; + +const chalk = require('chalk'); +const debug = require('debug'); +const { get, set } = require('es-toolkit/compat'); +const fs = require('fs-extra'); +const path = require('node:path'); +const semver = require('semver'); +const Backup = require('../utils/backup'); +const { LOCKFILE, PACKAGE_JSON } = require('../utils/package-managers'); + +class BaseAdapter { + configKey = 'npm'; + defaultInstallOptions = []; + lockfile = ''; + name = ''; + overridesKey = ''; + + backup = null; + debugFunction = null; + + constructor(options) { + this.backup = new Backup({ cwd: options.cwd }); + this.buildManagerOptions = options.buildManagerOptions; + this.cwd = options.cwd; + this.managerOptions = options.managerOptions; + this.run = options.run ?? require('../utils/run'); + } + + debug(...args) { + if (this.debugFunction === null) { + this.debugFunction = debug(`ember-try:dependency-manager-adapter:${this.name}`); + } + + this.debugFunction(...args); + } + + async setup(options = {}) { + this._checkForDifferentLockfiles(options.ui); + + await this.backup.addFiles([PACKAGE_JSON, this.lockfile]); + } + + async changeToDependencySet(dependencySet) { + await this.applyDependencySet(dependencySet); + await this._install(dependencySet); + + const dependencies = { + ...dependencySet.dependencies, + ...dependencySet.devDependencies, + }; + + const currentDependencies = Object.keys(dependencies).map((name) => ({ + name, + packageManager: this.name, + versionExpected: dependencies[name], + versionSeen: this._findCurrentVersionOf(name), + })); + + this.debug('Switched to dependencies: \n', currentDependencies); + + return currentDependencies; + } + + async applyDependencySet(dependencySet) { + if (dependencySet === undefined) { + return; + } + + this.debug('Changing to dependency set: %s', JSON.stringify(dependencySet)); + + const oldPackageJSON = JSON.parse(fs.readFileSync(this.backup.pathForFile(PACKAGE_JSON))); + const newPackageJSON = this._packageJSONForDependencySet(oldPackageJSON, dependencySet); + + this.debug('Write package.json with: \n', JSON.stringify(newPackageJSON)); + + fs.writeFileSync(path.join(this.cwd, PACKAGE_JSON), JSON.stringify(newPackageJSON, null, 2)); + } + + async cleanup() { + try { + await this.backup.restoreFiles([PACKAGE_JSON, this.lockfile]); + await this.backup.cleanUp(); + await this._install(); + } catch (error) { + console.error('Error cleaning up scenario:', error); + } + } + + _checkForDifferentLockfiles(ui) { + for (const packageManager in LOCKFILE) { + const lockfile = LOCKFILE[packageManager]; + + if (lockfile === this.lockfile) { + continue; + } + + try { + if (fs.statSync(path.join(this.cwd, lockfile)).isFile()) { + ui.writeLine( + chalk.yellow( + `Detected a \`${lockfile}\` file. Add \`packageManager: '${packageManager}'\` to your \`config/ember-try.js\` configuration file if you want to use ${packageManager} to install dependencies.`, + ), + ); + } + } catch { + // Move along. + } + } + } + + _findCurrentVersionOf(name) { + const filename = path.join(this.cwd, 'node_modules', name, PACKAGE_JSON); + + if (fs.existsSync(filename)) { + return JSON.parse(fs.readFileSync(filename)).version; + } else { + return null; + } + } + + async _install(dependencySet) { + let managerOptions = this.managerOptions || []; + + if (typeof this.buildManagerOptions === 'function') { + managerOptions = this.buildManagerOptions(dependencySet); + + if (Array.isArray(managerOptions) === false) { + throw new Error('buildManagerOptions must return an array of options'); + } + } else if (this.defaultInstallOptions.length) { + for (const option of this.defaultInstallOptions) { + if (managerOptions.includes(option) === false) { + managerOptions.push(option); + } + } + } + + this.debug(`Running ${this.name} install with options %s`, managerOptions); + + await this.run(this.name, ['install', ...managerOptions], { cwd: this.cwd }); + } + + _packageJSONForDependencySet(packageJSON, dependencySet) { + this._overridePackageJSONDependencies(packageJSON, dependencySet, 'dependencies'); + this._overridePackageJSONDependencies(packageJSON, dependencySet, 'devDependencies'); + this._overridePackageJSONDependencies(packageJSON, dependencySet, 'peerDependencies'); + this._overridePackageJSONDependencies(packageJSON, dependencySet, 'ember'); + this._overridePackageJSONDependencies(packageJSON, dependencySet, this.overridesKey); + + return packageJSON; + } + + _overridePackageJSONDependencies(packageJSON, dependencySet, kindOfDependency) { + if (get(dependencySet, kindOfDependency) === undefined) { + return; + } + + let packageNames = Object.keys(get(dependencySet, kindOfDependency)); + + for (let packageName of packageNames) { + let version = get(dependencySet, `${kindOfDependency}.${packageName}`); + + if (version === null) { + delete get(packageJSON, kindOfDependency)[packageName]; + } else { + set(packageJSON, `${kindOfDependency}.${packageName}`, version); + + if (semver.prerelease(version) || /^https*:\/\/.*\.tg*z/.test(version)) { + set(packageJSON, `${this.overridesKey}.${packageName}`, `$${packageName}`); + } + } + } + } +} + +module.exports = { BaseAdapter }; diff --git a/lib/dependency-manager-adapters/npm.js b/lib/dependency-manager-adapters/npm.js index 064e4683..47d5e8c1 100644 --- a/lib/dependency-manager-adapters/npm.js +++ b/lib/dependency-manager-adapters/npm.js @@ -1,170 +1,11 @@ 'use strict'; -const fs = require('fs-extra'); -const path = require('path'); -const debug = require('debug')('ember-try:dependency-manager-adapter:npm'); -const chalk = require('chalk'); -const semver = require('semver'); -const Backup = require('../utils/backup'); - -module.exports = class { - configKey = 'npm'; - packageJSON = 'package.json'; - packageLock = 'package-lock.json'; - - constructor(options) { - this.buildManagerOptions = options.buildManagerOptions; - this.cwd = options.cwd; - this.managerOptions = options.managerOptions; - this.run = options.run || require('../utils/run'); - - this.backup = new Backup({ cwd: this.cwd }); - } - - async setup(options) { - if (!options) { - options = {}; - } - - this._runYarnCheck(options.ui); - - return await this._backupOriginalDependencies(); - } - - async changeToDependencySet(depSet) { - this.applyDependencySet(depSet); - - await this._install(depSet); - - let deps = Object.assign({}, depSet.dependencies, depSet.devDependencies); - let currentDeps = Object.keys(deps).map((dep) => { - return { - name: dep, - versionExpected: deps[dep], - versionSeen: this._findCurrentVersionOf(dep), - packageManager: 'npm', - }; - }); - - debug('Switched to dependencies: \n', currentDeps); - - return currentDeps; - } - - async cleanup() { - try { - await this._restoreOriginalDependencies(); - } catch (e) { - console.log('Error cleaning up npm scenario:', e); // eslint-disable-line no-console - } - } - - _runYarnCheck(ui) { - try { - if (fs.statSync(path.join(this.cwd, 'yarn.lock')).isFile()) { - ui.writeLine( - chalk.yellow( - "Detected a yarn.lock file. Add `packageManager: 'yarn'` to your `config/ember-try.js` configuration file if you want to use Yarn to install npm dependencies.", - ), - ); - } - } catch { - // If no yarn.lock is found, no need to warn. - } - } - - _findCurrentVersionOf(packageName) { - let filename = path.join(this.cwd, 'node_modules', packageName, this.packageJSON); - if (fs.existsSync(filename)) { - return JSON.parse(fs.readFileSync(filename)).version; - } else { - return null; - } - } - - async _install(depSet) { - let mgrOptions = this.managerOptions || []; - - // buildManagerOptions overrides all default - if (typeof this.buildManagerOptions === 'function') { - mgrOptions = this.buildManagerOptions(depSet); - - if (!Array.isArray(mgrOptions)) { - throw new Error('buildManagerOptions must return an array of options'); - } - } else if (mgrOptions.indexOf('--no-package-lock') === -1) { - mgrOptions = mgrOptions.concat(['--no-package-lock']); - } - - debug('Run npm install with options %s', mgrOptions); - - await this.run('npm', [].concat(['install'], mgrOptions), { cwd: this.cwd }); - } - - applyDependencySet(depSet) { - debug('Changing to dependency set: %s', JSON.stringify(depSet)); - - if (!depSet) { - return; - } - - let backupPackageJSON = this.backup.pathForFile(this.packageJSON); - let packageJSONFile = path.join(this.cwd, this.packageJSON); - let packageJSON = JSON.parse(fs.readFileSync(backupPackageJSON)); - let newPackageJSON = this._packageJSONForDependencySet(packageJSON, depSet); - - debug('Write package.json with: \n', JSON.stringify(newPackageJSON)); - - fs.writeFileSync(packageJSONFile, JSON.stringify(newPackageJSON, null, 2)); - } - - _packageJSONForDependencySet(packageJSON, depSet) { - this._overridePackageJSONDependencies(packageJSON, depSet, 'dependencies'); - this._overridePackageJSONDependencies(packageJSON, depSet, 'devDependencies'); - this._overridePackageJSONDependencies(packageJSON, depSet, 'peerDependencies'); - this._overridePackageJSONDependencies(packageJSON, depSet, 'ember'); - this._overridePackageJSONDependencies(packageJSON, depSet, 'overrides'); - - return packageJSON; - } - - _overridePackageJSONDependencies(packageJSON, depSet, kindOfDependency) { - if (!depSet[kindOfDependency]) { - return; - } - - let packageNames = Object.keys(depSet[kindOfDependency]); - - packageNames.forEach((packageName) => { - if (!packageJSON[kindOfDependency]) { - packageJSON[kindOfDependency] = {}; - } - - let version = depSet[kindOfDependency][packageName]; - if (version === null) { - delete packageJSON[kindOfDependency][packageName]; - } else { - packageJSON[kindOfDependency][packageName] = version; - - // in npm we need to always add an override if the version is a pre-release - if (semver.prerelease(version) || /^https*:\/\/.*\.tg*z/.test(version)) { - if (!packageJSON.overrides) { - packageJSON.overrides = {}; - } - - packageJSON.overrides[packageName] = `$${packageName}`; - } - } - }); - } - - async _restoreOriginalDependencies() { - await this.backup.restoreFiles([this.packageJSON, this.packageLock]); - await this.backup.cleanUp(); - await this._install(); - } - - async _backupOriginalDependencies() { - await this.backup.addFiles([this.packageJSON, this.packageLock]); - } +const { LOCKFILE } = require('../utils/package-managers'); +const { BaseAdapter } = require('./base'); + +module.exports = class NpmAdapter extends BaseAdapter { + defaultInstallOptions = ['--no-package-lock']; + lockfile = LOCKFILE.npm; + name = 'npm'; + overridesKey = 'overrides'; }; diff --git a/lib/dependency-manager-adapters/pnpm.js b/lib/dependency-manager-adapters/pnpm.js index 81517150..891f0053 100644 --- a/lib/dependency-manager-adapters/pnpm.js +++ b/lib/dependency-manager-adapters/pnpm.js @@ -1,70 +1,18 @@ 'use strict'; -const fs = require('fs-extra'); -const path = require('path'); -const debug = require('debug')('ember-try:dependency-manager-adapter:pnpm'); -const Backup = require('../utils/backup'); -const semverLt = require('semver/functions/lt'); -const semverGte = require('semver/functions/gte'); +const semver = require('semver'); +const { LOCKFILE } = require('../utils/package-managers'); +const { BaseAdapter } = require('./base'); -const PACKAGE_JSON = 'package.json'; -const PNPM_LOCKFILE = 'pnpm-lock.yaml'; +module.exports = class PnpmAdapter extends BaseAdapter { + defaultInstallOptions = ['--no-lockfile', '--ignore-scripts']; + lockfile = LOCKFILE.pnpm; + name = 'pnpm'; + overridesKey = 'pnpm.overrides'; -module.exports = class { - // This still needs to be `npm` because we're still reading the dependencies - // from the `npm` key of the ember-try config. - configKey = 'npm'; - - constructor(options) { - this.buildManagerOptions = options.buildManagerOptions; - this.cwd = options.cwd; - this.managerOptions = options.managerOptions; - this.run = options.run || require('../utils/run'); - - this.backup = new Backup({ cwd: this.cwd }); - } - - async setup() { + async setup(options) { await this._throwOnResolutionMode(); - await this.backup.addFiles([PACKAGE_JSON, PNPM_LOCKFILE]); - } - - async changeToDependencySet(depSet) { - await this.applyDependencySet(depSet); - await this._install(depSet); - - let deps = Object.assign({}, depSet.dependencies, depSet.devDependencies); - let currentDeps = Object.keys(deps).map((dep) => { - return { - name: dep, - versionExpected: deps[dep], - versionSeen: this._findCurrentVersionOf(dep), - packageManager: 'pnpm', - }; - }); - - debug('Switched to dependencies: \n', currentDeps); - - return currentDeps; - } - - async cleanup() { - try { - await this.backup.restoreFiles([PACKAGE_JSON, PNPM_LOCKFILE]); - await this.backup.cleanUp(); - await this._install(); - } catch (e) { - console.log('Error cleaning up scenario:', e); // eslint-disable-line no-console - } - } - - _findCurrentVersionOf(packageName) { - let filename = path.join(this.cwd, 'node_modules', packageName, PACKAGE_JSON); - if (fs.existsSync(filename)) { - return JSON.parse(fs.readFileSync(filename)).version; - } else { - return null; - } + await super.setup(options); } /** @@ -103,92 +51,14 @@ module.exports = class { _isResolutionModeWrong(versionStr, resolutionMode) { // The `resolution-mode` is not set explicitly, and the current pnpm version makes it default // to `lowest-direct` - if (!resolutionMode.length && semverGte(versionStr, '8.0.0') && semverLt(versionStr, '8.7.0')) { + if ( + !resolutionMode.length && + semver.gte(versionStr, '8.0.0') && + semver.lt(versionStr, '8.7.0') + ) { return true; } return false; } - - async _install(depSet) { - let mgrOptions = this.managerOptions || []; - - // buildManagerOptions overrides all default - if (typeof this.buildManagerOptions === 'function') { - mgrOptions = this.buildManagerOptions(depSet); - - if (!Array.isArray(mgrOptions)) { - throw new Error('buildManagerOptions must return an array of options'); - } - } else { - if (!mgrOptions.includes('--no-lockfile')) { - mgrOptions.push('--no-lockfile'); - } - - if (!mgrOptions.includes('--ignore-scripts')) { - mgrOptions.push('--ignore-scripts'); - } - } - - // Note: We are explicitly *not* using `--no-lockfile` here, so that we - // only have to resolve the dependencies that have actually changed. - - debug('Run pnpm install with options %s', mgrOptions); - - await this.run('pnpm', [].concat(['install'], mgrOptions), { cwd: this.cwd }); - } - - async applyDependencySet(depSet) { - debug('Changing to dependency set: %s', JSON.stringify(depSet)); - - if (!depSet) { - return; - } - - let backupPackageJSON = this.backup.pathForFile(PACKAGE_JSON); - let packageJSONFile = path.join(this.cwd, PACKAGE_JSON); - let packageJSON = JSON.parse(fs.readFileSync(backupPackageJSON)); - let newPackageJSON = this._packageJSONForDependencySet(packageJSON, depSet); - - debug('Write package.json with: \n', JSON.stringify(newPackageJSON)); - fs.writeFileSync(packageJSONFile, JSON.stringify(newPackageJSON, null, 2)); - - // We restore the original lockfile here, so that we always create a minimal - // diff compared to the original locked dependency set. - - await this.backup.restoreFile(PNPM_LOCKFILE); - } - - _packageJSONForDependencySet(packageJSON, depSet) { - this._overridePackageJSONDependencies(packageJSON, depSet, 'dependencies'); - this._overridePackageJSONDependencies(packageJSON, depSet, 'devDependencies'); - this._overridePackageJSONDependencies(packageJSON, depSet, 'peerDependencies'); - this._overridePackageJSONDependencies(packageJSON, depSet, 'ember'); - - // see https://pnpm.io/package_json#pnpmoverrides - this._overridePackageJSONDependencies(packageJSON, depSet, 'overrides'); - - return packageJSON; - } - - _overridePackageJSONDependencies(packageJSON, depSet, kindOfDependency) { - if (!depSet[kindOfDependency]) { - return; - } - - let packageNames = Object.keys(depSet[kindOfDependency]); - - for (let packageName of packageNames) { - if (!packageJSON[kindOfDependency]) { - packageJSON[kindOfDependency] = {}; - } - - let version = depSet[kindOfDependency][packageName]; - if (version === null) { - delete packageJSON[kindOfDependency][packageName]; - } else { - packageJSON[kindOfDependency][packageName] = version; - } - } - } }; diff --git a/lib/dependency-manager-adapters/workspace.js b/lib/dependency-manager-adapters/workspace.js index f70b4a28..38c03457 100644 --- a/lib/dependency-manager-adapters/workspace.js +++ b/lib/dependency-manager-adapters/workspace.js @@ -4,12 +4,10 @@ const fs = require('fs-extra'); const path = require('path'); const debug = require('debug')('ember-try:dependency-manager-adapter:workspaces'); const walkSync = require('walk-sync'); - +const { PACKAGE_JSON } = require('../utils/package-managers'); const YarnAdapter = require('./yarn'); module.exports = class { - packageJSON = 'package.json'; - constructor(options) { this.buildManagerOptions = options.buildManagerOptions; this.cwd = options.cwd; @@ -21,7 +19,8 @@ module.exports = class { 'workspaces are currently only supported by Yarn, you must set `packageManager` to `yarn`', ); } - let packageJSON = JSON.parse(fs.readFileSync(this.packageJSON)); + + let packageJSON = JSON.parse(fs.readFileSync(PACKAGE_JSON)); let workspaceGlobs; if (Array.isArray(packageJSON.workspaces)) { @@ -56,10 +55,6 @@ module.exports = class { } setup(options) { - if (!options) { - options = {}; - } - return Promise.all(this._packageAdapters.map((adapter) => adapter.setup(options))); } diff --git a/lib/dependency-manager-adapters/yarn.js b/lib/dependency-manager-adapters/yarn.js index e2c5af23..5e775e16 100644 --- a/lib/dependency-manager-adapters/yarn.js +++ b/lib/dependency-manager-adapters/yarn.js @@ -1,150 +1,11 @@ 'use strict'; -const fs = require('fs-extra'); -const path = require('path'); -const debug = require('debug')('ember-try:dependency-manager-adapter:yarn'); -const Backup = require('../utils/backup'); - -module.exports = class { - configKey = 'npm'; // Still use `npm` for now! - packageJSON = 'package.json'; - yarnLock = 'yarn.lock'; - - constructor(options) { - this.buildManagerOptions = options.buildManagerOptions; - this.cwd = options.cwd; - this.managerOptions = options.managerOptions; - this.run = options.run || require('../utils/run'); - - this.backup = new Backup({ cwd: this.cwd }); - } - - async setup(options) { - if (!options) { - options = {}; - } - - return await this._backupOriginalDependencies(); - } - - async changeToDependencySet(depSet) { - this.applyDependencySet(depSet); - - await this._install(depSet); - - let deps = Object.assign({}, depSet.dependencies, depSet.devDependencies); - let currentDeps = Object.keys(deps).map((dep) => { - return { - name: dep, - versionExpected: deps[dep], - versionSeen: this._findCurrentVersionOf(dep), - packageManager: 'yarn', - }; - }); - - debug('Switched to dependencies: \n', currentDeps); - - return currentDeps; - } - - async cleanup() { - try { - await this._restoreOriginalDependencies(); - } catch (e) { - console.log('Error cleaning up npm scenario:', e); // eslint-disable-line no-console - } - } - - _findCurrentVersionOf(packageName) { - let filename = path.join(this.cwd, 'node_modules', packageName, this.packageJSON); - if (fs.existsSync(filename)) { - return JSON.parse(fs.readFileSync(filename)).version; - } else { - return null; - } - } - - async _install(depSet) { - let mgrOptions = this.managerOptions || []; - - // buildManagerOptions overrides all default - if (typeof this.buildManagerOptions === 'function') { - mgrOptions = this.buildManagerOptions(depSet); - - if (!Array.isArray(mgrOptions)) { - throw new Error('buildManagerOptions must return an array of options'); - } - } else { - if (mgrOptions.indexOf('--no-lockfile') === -1) { - mgrOptions = mgrOptions.concat(['--no-lockfile']); - } - - // yarn errors on incompatible engines, not a good experience - if (mgrOptions.indexOf('--ignore-engines') === -1) { - mgrOptions = mgrOptions.concat(['--ignore-engines']); - } - } - - debug('Run yarn install with options %s', mgrOptions); - - await this.run('yarn', [].concat(['install'], mgrOptions), { cwd: this.cwd }); - } - - applyDependencySet(depSet) { - debug('Changing to dependency set: %s', JSON.stringify(depSet)); - - if (!depSet) { - return; - } - - let backupPackageJSON = this.backup.pathForFile(this.packageJSON); - let packageJSONFile = path.join(this.cwd, this.packageJSON); - let packageJSON = JSON.parse(fs.readFileSync(backupPackageJSON)); - let newPackageJSON = this._packageJSONForDependencySet(packageJSON, depSet); - - debug('Write package.json with: \n', JSON.stringify(newPackageJSON)); - - fs.writeFileSync(packageJSONFile, JSON.stringify(newPackageJSON, null, 2)); - } - - _packageJSONForDependencySet(packageJSON, depSet) { - this._overridePackageJSONDependencies(packageJSON, depSet, 'dependencies'); - this._overridePackageJSONDependencies(packageJSON, depSet, 'devDependencies'); - this._overridePackageJSONDependencies(packageJSON, depSet, 'peerDependencies'); - this._overridePackageJSONDependencies(packageJSON, depSet, 'ember'); - this._overridePackageJSONDependencies(packageJSON, depSet, 'resolutions'); - - return packageJSON; - } - - _overridePackageJSONDependencies(packageJSON, depSet, kindOfDependency) { - if (!depSet[kindOfDependency]) { - return; - } - - let packageNames = Object.keys(depSet[kindOfDependency]); - - packageNames.forEach((packageName) => { - if (!packageJSON[kindOfDependency]) { - packageJSON[kindOfDependency] = {}; - } - - let version = depSet[kindOfDependency][packageName]; - if (version === null) { - delete packageJSON[kindOfDependency][packageName]; - } else { - packageJSON[kindOfDependency][packageName] = version; - } - }); - } - - async _restoreOriginalDependencies() { - await this.backup.restoreFiles([this.packageJSON, this.yarnLock]); - await this.backup.cleanUp(); - await this._install(); - } - - async _backupOriginalDependencies() { - await this.backup.addFiles([this.packageJSON, this.yarnLock]); - } +const { LOCKFILE } = require('../utils/package-managers'); +const { BaseAdapter } = require('./base'); + +module.exports = class YarnAdapter extends BaseAdapter { + defaultInstallOptions = ['--no-lockfile', '--ignore-engines']; + lockfile = LOCKFILE.yarn; + name = 'yarn'; + overridesKey = 'resolutions'; }; diff --git a/lib/utils/package-managers.js b/lib/utils/package-managers.js new file mode 100644 index 00000000..ab17cf24 --- /dev/null +++ b/lib/utils/package-managers.js @@ -0,0 +1,9 @@ +const LOCKFILE = { + npm: 'package-lock.json', + pnpm: 'pnpm-lock.yaml', + yarn: 'yarn.lock', +}; + +const PACKAGE_JSON = 'package.json'; + +module.exports = { LOCKFILE, PACKAGE_JSON }; diff --git a/package.json b/package.json index 404f1dc6..5ec8c00a 100644 --- a/package.json +++ b/package.json @@ -38,6 +38,7 @@ "cli-table3": "^0.6.5", "debug": "^4.4.0", "ember-try-config": "^4.0.0", + "es-toolkit": "^1.29.0", "execa": "^4.1.0", "fs-extra": "^6.0.1", "resolve": "^1.22.8", diff --git a/test/dependency-manager-adapters/npm-adapter-test.js b/test/dependency-manager-adapters/npm-adapter-test.js index b30fd9b8..f70c1123 100644 --- a/test/dependency-manager-adapters/npm-adapter-test.js +++ b/test/dependency-manager-adapters/npm-adapter-test.js @@ -144,7 +144,7 @@ describe('npm Adapter', () => { }); }); - describe('#_restoreOriginalDependencies', () => { + describe('#cleanup', () => { it('restores the `package.json` and `package-lock.json` files if they exist', async () => { writeJSONFile('package.json', { originalPackageJSON: true }); writeJSONFile('package-lock.json', { originalPackageLock: true }); @@ -157,7 +157,7 @@ describe('npm Adapter', () => { writeJSONFile('package.json', { originalPackageJSON: false }); writeJSONFile('package-lock.json', { originalPackageLock: false }); - await adapter._restoreOriginalDependencies(); + await adapter.cleanup(); assertFileContainsJSON(path.join(tmpdir, 'package.json'), { originalPackageJSON: true, @@ -187,7 +187,7 @@ describe('npm Adapter', () => { run: stubbedRun, }); - await adapter._restoreOriginalDependencies(); + await adapter.cleanup(); expect(runCount).to.equal(1); }); diff --git a/test/dependency-manager-adapters/pnpm-adapter-test.js b/test/dependency-manager-adapters/pnpm-adapter-test.js index ee134d7f..bd16a80e 100644 --- a/test/dependency-manager-adapters/pnpm-adapter-test.js +++ b/test/dependency-manager-adapters/pnpm-adapter-test.js @@ -349,12 +349,14 @@ describe('pnpm Adapter', () => { }; let depSet = { dependencies: { 'ember-cli-babel': '6.0.0' }, - overrides: { 'ember-cli-babel': '6.0.0' }, + pnpm: { + overrides: { 'ember-cli-babel': '6.0.0' }, + }, }; let resultJSON = adapter._packageJSONForDependencySet(packageJSON, depSet); - expect(resultJSON.overrides['ember-cli-babel']).to.equal('6.0.0'); + expect(resultJSON.pnpm.overrides['ember-cli-babel']).to.equal('6.0.0'); }); it('removes a dependency from overrides if its version is null', () => { @@ -363,16 +365,20 @@ describe('pnpm Adapter', () => { }); let packageJSON = { dependencies: { 'ember-cli-babel': '5.0.0' }, - overrides: { 'ember-cli-babel': '5.0.0' }, + pnpm: { + overrides: { 'ember-cli-babel': '5.0.0' }, + }, }; let depSet = { dependencies: { 'ember-cli-babel': '6.0.0' }, - overrides: { 'ember-cli-babel': null }, + pnpm: { + overrides: { 'ember-cli-babel': null }, + }, }; let resultJSON = adapter._packageJSONForDependencySet(packageJSON, depSet); - expect(resultJSON.overrides['ember-cli-babel']).to.be.undefined; + expect(resultJSON.pnpm.overrides['ember-cli-babel']).to.be.undefined; }); it('changes specified npm dev dependency versions', () => { diff --git a/test/dependency-manager-adapters/workspace-adapter-test.js b/test/dependency-manager-adapters/workspace-adapter-test.js index 6f13a3aa..be34e08f 100644 --- a/test/dependency-manager-adapters/workspace-adapter-test.js +++ b/test/dependency-manager-adapters/workspace-adapter-test.js @@ -238,7 +238,7 @@ describe('workspace Adapter', () => { let adapter = workspaceAdapter._packageAdapters[0]; - await adapter._backupOriginalDependencies(); + await adapter.setup(); // Simulate modifying the file: writeJSONFile('packages/test/package.json', { originalPackageJSON: false }); diff --git a/test/dependency-manager-adapters/yarn-adapter-test.js b/test/dependency-manager-adapters/yarn-adapter-test.js index 55ad3516..665a431a 100644 --- a/test/dependency-manager-adapters/yarn-adapter-test.js +++ b/test/dependency-manager-adapters/yarn-adapter-test.js @@ -144,7 +144,7 @@ describe('yarn Adapter', () => { }); }); - describe('#_restoreOriginalDependencies', () => { + describe('#cleanup', () => { it('restores the `package.json` and `yarn.lock` files if they exist', async () => { writeJSONFile('package.json', { originalPackageJSON: true }); writeJSONFile('yarn.lock', { originalYarnLock: true }); @@ -157,7 +157,7 @@ describe('yarn Adapter', () => { writeJSONFile('package.json', { originalPackageJSON: false }); writeJSONFile('yarn.lock', { originalYarnLock: false }); - await adapter._restoreOriginalDependencies(); + await adapter.cleanup(); assertFileContainsJSON(path.join(tmpdir, 'package.json'), { originalPackageJSON: true, @@ -187,7 +187,7 @@ describe('yarn Adapter', () => { run: stubbedRun, }); - await adapter._restoreOriginalDependencies(); + await adapter.cleanup(); expect(runCount).to.equal(1); }); diff --git a/test/tasks/try-each-test.js b/test/tasks/try-each-test.js index 21d0cc3a..11beb377 100644 --- a/test/tasks/try-each-test.js +++ b/test/tasks/try-each-test.js @@ -97,7 +97,7 @@ describe('tryEach', () => { return tryEachTask.run(config.scenarios, {}).then((exitCode) => { expect(exitCode).to.equal(0, 'exits 0 when all scenarios succeed'); expect(output).to.include( - "Detected a yarn.lock file. Add `packageManager: 'yarn'` to your `config/ember-try.js` configuration file if you want to use Yarn to install npm dependencies.", + "Detected a `yarn.lock` file. Add `packageManager: 'yarn'` to your `config/ember-try.js` configuration file if you want to use yarn to install dependencies.", ); expect(output).to.include('Scenario first: SUCCESS'); expect(output).to.include('Scenario second: SUCCESS'); diff --git a/yarn.lock b/yarn.lock index c41bdee6..f26e2502 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3185,6 +3185,11 @@ es-errors@^1.3.0: resolved "https://registry.yarnpkg.com/es-errors/-/es-errors-1.3.0.tgz#05f75a25dab98e4fb1dcd5e1472c0546d5057c8f" integrity sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw== +es-toolkit@^1.29.0: + version "1.29.0" + resolved "https://registry.yarnpkg.com/es-toolkit/-/es-toolkit-1.29.0.tgz#a9c54e87880002e4186560fe0a567e76a61cb61a" + integrity sha512-GjTll+E6APcfAQA09D89HdT8Qn2Yb+TeDSDBTMcxAo+V+w1amAtCI15LJu4YPH/UCPoSo/F47Gr1LIM0TE0lZA== + es6-error@^4.0.1: version "4.1.1" resolved "https://registry.yarnpkg.com/es6-error/-/es6-error-4.1.1.tgz#9e3af407459deed47e9a91f9b885a84eb05c561d"