UNPKG

ember-try

Version:

An ember-cli addon to test against multiple dependencies, such as ember and ember-data.

176 lines (138 loc) 5.4 kB
'use strict'; 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 { warn } = require('../utils/console'); 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() { this._checkForDifferentLockfiles(); 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() { for (const packageManager in LOCKFILE) { const lockfile = LOCKFILE[packageManager]; if (lockfile === this.lockfile) { continue; } try { if (fs.statSync(path.join(this.cwd, lockfile)).isFile()) { warn( `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 };