diff --git a/lib/integration/PluginManagement/install.js b/lib/integration/PluginManagement/install.js index 1098bfd..e955c47 100644 --- a/lib/integration/PluginManagement/install.js +++ b/lib/integration/PluginManagement/install.js @@ -95,6 +95,12 @@ async function loadPluginData ({ logger, project, targets }) { percentage => logger?.logProgress?.(`${chalk.bold.cyan('')} Getting plugin info ${percentage}% complete`) ) logger?.log(`${chalk.bold.cyan('')} Getting plugin info 100% complete`) + await eachOfLimitProgress( + targets, + target => target.fetchProjectInfo(), + percentage => logger?.logProgress?.(`${chalk.bold.cyan('')} Checking installed plugins ${percentage}% complete`) + ) + logger?.log(`${chalk.bold.cyan('')} Checking installed plugins 100% complete`) await eachOfLimitProgress( targets, target => target.findCompatibleVersion(frameworkVersion), diff --git a/lib/integration/Target.js b/lib/integration/Target.js index 5bf271c..9e73120 100644 --- a/lib/integration/Target.js +++ b/lib/integration/Target.js @@ -4,6 +4,7 @@ import { exec } from 'child_process' import semver from 'semver' import fs from 'fs-extra' import path from 'path' +import os from 'os' import { ADAPT_ALLOW_PRERELEASE } from '../util/constants.js' import Plugin from './Plugin.js' /** @typedef {import("./Project.js").default} Project */ @@ -122,6 +123,7 @@ export default class Target extends Plugin { markInstallable () { if (!this.isApplyLatestCompatibleVersion && !(this.isLocalSource && this.latestSourceVersion)) return + if (this.projectVersion === this.matchedVersion) return this.versionToApply = this.matchedVersion } @@ -156,6 +158,39 @@ export default class Target extends Plugin { this.versionToApply = this.projectVersion } + /** + * Install a plugin via bower into outputPath. Runs from an isolated working + * directory so an ambient project bower.json cannot inject its own + * dependencies into the install directory (fixes #235). The project .bowerrc + * is copied across so registry, proxy and other bower settings are preserved. + * @param {string} pluginNameVersion e.g. adapt-contrib-media@7.0.6 + * @param {string} outputPath absolute path to the plugin type folder + */ + async bowerInstall (pluginNameVersion, outputPath) { + const isolatedCwd = await fs.mkdtemp(path.join(os.tmpdir(), 'adapt-cli-')) + const bowerrcPath = path.join(this.cwd, '.bowerrc') + if (await fs.pathExists(bowerrcPath)) { + await fs.copy(bowerrcPath, path.join(isolatedCwd, '.bowerrc')) + } + try { + await new Promise((resolve, reject) => { + bower.commands.install([pluginNameVersion], null, { + directory: outputPath, + cwd: isolatedCwd, + registry: this.BOWER_REGISTRY_CONFIG + }) + .on('end', resolve) + .on('error', err => { + err = new Error(`Bower reported ${err}`) + this._error = err + reject(err) + }) + }) + } finally { + await fs.rm(isolatedCwd, { recursive: true, force: true }) + } + } + async install ({ clone = false } = {}) { const logger = this.logger const pluginTypeFolder = await this.getTypeFolder() @@ -212,20 +247,7 @@ export default class Target extends Plugin { } catch (err) { throw new Error(`There was a problem writing to the target directory ${pluginPath}`) } - await new Promise((resolve, reject) => { - const pluginNameVersion = `${this.packageName}@${this.versionToApply}` - bower.commands.install([pluginNameVersion], null, { - directory: outputPath, - cwd: this.cwd, - registry: this.BOWER_REGISTRY_CONFIG - }) - .on('end', resolve) - .on('error', err => { - err = new Error(`Bower reported ${err}`) - this._error = err - reject(err) - }) - }) + await this.bowerInstall(`${this.packageName}@${this.versionToApply}`, outputPath) const bowerJSON = await fs.readJSON(path.join(pluginPath, 'bower.json')) bowerJSON.version = bowerJSON.version ?? this.versionToApply; await fs.writeJSON(path.join(pluginPath, '.bower.json'), bowerJSON, { spaces: 2, replacer: null }) @@ -243,20 +265,7 @@ export default class Target extends Plugin { } catch (err) { throw new Error(`There was a problem writing to the target directory ${pluginPath}`) } - await new Promise((resolve, reject) => { - const pluginNameVersion = `${this.packageName}@${this.matchedVersion}` - bower.commands.install([pluginNameVersion], null, { - directory: outputPath, - cwd: this.cwd, - registry: this.BOWER_REGISTRY_CONFIG - }) - .on('end', resolve) - .on('error', err => { - err = new Error(`Bower reported ${err}`) - this._error = err - reject(err) - }) - }) + await this.bowerInstall(`${this.packageName}@${this.matchedVersion}`, outputPath) this.preUpdateProjectVersion = this.projectVersion this._projectInfo = null await this.fetchProjectInfo()