Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update: Use npm for install, update and uninstall where required (fixes #175) #189

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
13 changes: 12 additions & 1 deletion lib/integration/Plugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ export default class Plugin {
* @returns {boolean|null}
*/
get isUpToDate () {
if (!this.hasFrameworkCompatibleVersion) return true;
if (!this.hasFrameworkCompatibleVersion) return true
const canCheckSourceAgainstProject = (this.latestSourceVersion && this.projectVersion)
if (!canCheckSourceAgainstProject) return null
const isLatestVersion = (this.projectVersion === this.latestSourceVersion)
Expand Down Expand Up @@ -187,6 +187,7 @@ export default class Plugin {
if (!this.isLocalSource) throw new Error('Plugin name or version must be a path to the source')
if (this.isLocalSourceZip) throw new Error('Cannot install from zip files')
this._sourceInfo = await new Promise((resolve, reject) => {
// TODO: npm implementation
// get bower.json data
const paths = [
path.resolve(this.cwd, `${this.sourcePath}/bower.json`)
Expand All @@ -211,6 +212,7 @@ export default class Plugin {
const perform = async (attemptCount = 0) => {
try {
return await new Promise((resolve, reject) => {
// TODO: npm implementation
bower.commands.info(`${this.packageName}`, null, { cwd: this.cwd, registry: this.BOWER_REGISTRY_CONFIG })
.on('end', resolve)
.on('error', reject)
Expand All @@ -227,12 +229,18 @@ export default class Plugin {
this._versionsInfo = info.versions.filter(version => semverOptions.includePrerelease ? true : !semver.prerelease(version))
}

async refetchProjectInfo () {
this._projectInfo = null
return this.fetchProjectInfo()
}

async fetchProjectInfo () {
if (this._projectInfo) return this._projectInfo
this._projectInfo = null
this._projectInfo = await new Promise((resolve, reject) => {
// get bower.json data
globs([
// TODO: npm implementation
`${this.cwd.replace(/\\/g, '/')}/src/*/${this.packageName}/.bower.json`,
`${this.cwd.replace(/\\/g, '/')}/src/*/${this.packageName}/bower.json`
], (err, matches) => {
Expand All @@ -242,6 +250,7 @@ export default class Plugin {
if (!match) {
// widen the search
globs([
// TODO: npm implementation
`${this.cwd.replace(/\\/g, '/')}/src/**/.bower.json`,
`${this.cwd.replace(/\\/g, '/')}/src/**/bower.json`
], (err, matches) => {
Expand All @@ -268,6 +277,7 @@ export default class Plugin {
const perform = async (attemptCount = 0) => {
try {
return await new Promise((resolve, reject) => {
// TODO: npm implementation
bower.commands.info(`${this.packageName}@${version}`, null, { cwd: this.cwd, registry: this.BOWER_REGISTRY_CONFIG })
.on('end', resolve)
.on('error', reject)
Expand Down Expand Up @@ -353,6 +363,7 @@ export default class Plugin {
if (this._repositoryUrl) return this._repositoryUrl
if (this.isLocalSource) return
const url = await new Promise((resolve, reject) => {
// TODO: npm implementation
bower.commands.lookup(this.packageName, { cwd: this.cwd, registry: this.BOWER_REGISTRY_CONFIG })
.on('end', resolve)
.on('error', reject)
Expand Down
21 changes: 19 additions & 2 deletions lib/integration/PluginManagement/install.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import Target from '../Target.js'
import bower from 'bower'
import { difference } from 'lodash-es'
import path from 'path'
import { install as npmInstall } from './npm.js'

export default async function install ({
plugins,
Expand All @@ -20,7 +21,10 @@ export default async function install ({
logger = null
}) {
cwd = path.resolve(process.cwd(), cwd)
isClean && await new Promise(resolve => bower.commands.cache.clean().on('end', resolve))
isClean && await new Promise(resolve => {
// TODO: npm implementation
bower.commands.cache.clean().on('end', resolve)
})
const project = new Project({ cwd, logger })
project.tryThrowInvalidPath()

Expand All @@ -40,8 +44,21 @@ export default async function install ({
await eachOfSeriesProgress(
installTargetsToBeInstalled,
target => target.install({ clone: dev }),
percentage => logger?.logProgress?.(`${chalk.bold.cyan('<info>')} Installing plugins ${percentage}% complete`)
percentage => logger?.logProgress?.(`${chalk.bold.cyan('<info>')} Installing plugins ${(percentage / (project.isNPM ? 2 : 1))}% complete`)
)
if (project.isNPM) {
// Batch install npm plugins as it's faster
const installArgs = installTargetsToBeInstalled
.filter(target => target.isNPMInstall)
.map(target => `${target.packageName}@${target.versionToApply}`)
const outputPath = path.join(cwd, 'src')
await npmInstall({ logger, cwd: outputPath, args: installArgs })
await eachOfSeriesProgress(
installTargetsToBeInstalled,
target => target.postInstall(),
percentage => logger?.logProgress?.(`${chalk.bold.cyan('<info>')} Installing plugins ${50 + (percentage / 2)}% complete`)
)
}
logger?.log(`${chalk.bold.cyan('<info>')} Installing plugins 100% complete`)
const manifestDependencies = await project.getManifestDependencies()
await updateManifest({ logger, project, targets, manifestDependencies, isInteractive })
Expand Down
54 changes: 54 additions & 0 deletions lib/integration/PluginManagement/npm.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import chalk from 'chalk'
import { exec } from 'child_process'
import path from 'path'

export async function install ({
logger,
cwd,
args = []
} = {}) {
cwd = path.resolve(process.cwd(), cwd)
await new Promise((resolve, reject) => {
if (!args.length) logger?.log(chalk.cyan('installing node dependencies'))
exec([(process.platform === 'win32' ? 'npm.cmd' : 'npm'), '--unsafe-perm', 'install', ...args].join(' '), {
cwd
}, (err, stdout, stderr) => {
if (!err) return resolve()
reject(stderr)
})
})
}

export async function update ({
logger,
cwd,
args = []
} = {}) {
cwd = path.resolve(process.cwd(), cwd)
await new Promise((resolve, reject) => {
if (!args.length) logger?.log(chalk.cyan('installing node dependencies'))
oliverfoster marked this conversation as resolved.
Show resolved Hide resolved
exec([(process.platform === 'win32' ? 'npm.cmd' : 'npm'), '--unsafe-perm', 'update', ...args].join(' '), {
cwd
}, (err, stdout, stderr) => {
if (!err) return resolve()
reject(stderr)
})
})
}

export async function uninstall ({
logger,
cwd,
args = []
} = {}) {
cwd = path.resolve(process.cwd(), cwd)
await new Promise((resolve, reject) => {
if (!args.length) logger?.log(chalk.cyan('installing node dependencies'))
oliverfoster marked this conversation as resolved.
Show resolved Hide resolved
exec([(process.platform === 'win32' ? 'npm.cmd' : 'npm'), '--unsafe-perm', 'uninstall', ...args].join(' '), {
cwd
}, (err, stdout, stderr) => {
if (!err) return resolve()
reject(stderr)
})
})
oliverfoster marked this conversation as resolved.
Show resolved Hide resolved
}
3 changes: 3 additions & 0 deletions lib/integration/PluginManagement/register.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export default async function register ({
const BOWER_REGISTRY_CONFIG = getBowerRegistryConfig({ cwd })
logger?.warn('Using registry at', BOWER_REGISTRY_CONFIG.register)
try {
// TODO: npm implementation
const bowerJSONPath = path.join(cwd, 'bower.json')
const hasBowerJSON = fs.existsSync(bowerJSONPath)

Expand Down Expand Up @@ -108,6 +109,7 @@ async function confirm (properties) {
async function exists (BOWER_REGISTRY_CONFIG, plugin) {
const pluginName = plugin.toString().toLowerCase()
return new Promise((resolve, reject) => {
// TODO: npm implementation
bower.commands.search(pluginName, {
registry: BOWER_REGISTRY_CONFIG.register
})
Expand All @@ -121,6 +123,7 @@ async function exists (BOWER_REGISTRY_CONFIG, plugin) {

async function registerWithBowerRepo (BOWER_REGISTRY_CONFIG, plugin, repository) {
return new Promise((resolve, reject) => {
// TODO: npm implementation
bower.commands.register(plugin.toString(), repository.url || repository, {
registry: BOWER_REGISTRY_CONFIG
})
Expand Down
1 change: 1 addition & 0 deletions lib/integration/PluginManagement/rename.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ async function renameInBowerRepo ({
async function exists (BOWER_REGISTRY_CONFIG, plugin) {
const pluginName = plugin.toString().toLowerCase()
return new Promise((resolve, reject) => {
// TODO: npm implementation
bower.commands.search(pluginName, {
registry: BOWER_REGISTRY_CONFIG.register
})
Expand Down
19 changes: 17 additions & 2 deletions lib/integration/PluginManagement/uninstall.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { createPromptTask } from '../../util/createPromptTask.js'
import { errorPrinter, packageNamePrinter } from './print.js'
import { intersection } from 'lodash-es'
import path from 'path'
import { uninstall as npmUninstall } from './npm.js'

export default async function uninstall ({
plugins,
Expand All @@ -24,11 +25,25 @@ export default async function uninstall ({
if (!targets?.length) return targets

await loadPluginData({ logger, targets })
const uninstallTargetsToBeUninstalled = targets.filter(target => target.isToBeUninstalled)
await eachOfLimitProgress(
targets.filter(target => target.isToBeUninstalled),
uninstallTargetsToBeUninstalled,
target => target.uninstall(),
percentage => logger?.logProgress?.(`${chalk.bold.cyan('<info>')} Uninstalling plugins ${percentage}% complete`)
percentage => logger?.logProgress?.(`${chalk.bold.cyan('<info>')} Uninstalling plugins ${percentage / (project.isNPM ? 2 : 1)}% complete`)
)
if (project.isNPM) {
// Batch install npm plugins as it's faster
const installArgs = uninstallTargetsToBeUninstalled
.filter(target => target.isNPMUninstall)
.map(target => `${target.packageName}`)
const outputPath = path.join(cwd, 'src')
await npmUninstall({ logger, cwd: outputPath, args: installArgs })
await eachOfLimitProgress(
uninstallTargetsToBeUninstalled,
target => target.postUninstall(),
percentage => logger?.logProgress?.(`${chalk.bold.cyan('<info>')} Uninstalling plugins ${50 + (percentage / 2)}% complete`)
)
}
logger?.log(`${chalk.bold.cyan('<info>')} Uninstalling plugins 100% complete`)
const installedDependencies = await project.getInstalledDependencies()
await updateManifest({ project, targets, installedDependencies, isInteractive })
Expand Down
1 change: 1 addition & 0 deletions lib/integration/PluginManagement/unregister.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export default async function unregister ({
const BOWER_REGISTRY_CONFIG = getBowerRegistryConfig({ cwd })
logger?.warn('Using registry at', BOWER_REGISTRY_CONFIG.register)
try {
// TODO: npm implementation
const bowerJSONPath = path.join(cwd, 'bower.json')
const hasBowerJSON = fs.existsSync(bowerJSONPath)
const bowerJSON = hasBowerJSON ? await readValidateJSON(bowerJSONPath) : {}
Expand Down
16 changes: 15 additions & 1 deletion lib/integration/PluginManagement/update.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import Project from '../Project.js'
import { createPromptTask } from '../../util/createPromptTask.js'
import { errorPrinter, packageNamePrinter, versionPrinter, existingVersionPrinter } from './print.js'
import { eachOfLimitProgress, eachOfSeriesProgress } from '../../util/promises.js'
import { update as npmUpdate } from './npm.js'
/** @typedef {import("../Target.js").default} Target */

export default async function update ({
Expand Down Expand Up @@ -35,8 +36,21 @@ export default async function update ({
await eachOfSeriesProgress(
updateTargetsToBeUpdated,
target => target.update(),
percentage => logger?.logProgress?.(`${chalk.bold.cyan('<info>')} Updating plugins ${percentage}% complete`)
percentage => logger?.logProgress?.(`${chalk.bold.cyan('<info>')} Updating plugins ${percentage / (project.isNPM ? 2 : 1)}% complete`)
)
if (project.isNPM) {
// Batch install npm plugins as it's faster
const installArgs = updateTargetsToBeUpdated
.filter(target => target.isNPMUpdate)
.map(target => `${target.packageName}`)
const outputPath = path.join(cwd, 'src')
await npmUpdate({ logger, cwd: outputPath, args: installArgs })
await eachOfSeriesProgress(
updateTargetsToBeUpdated,
target => target.postUpdate(),
percentage => logger?.logProgress?.(`${chalk.bold.cyan('<info>')} Updating plugins ${50 + (percentage / 2)}% complete`)
)
}
logger?.log(`${chalk.bold.cyan('<info>')} Updating plugins 100% complete`)
}
await summariseUpdates({ logger, targets })
Expand Down
5 changes: 5 additions & 0 deletions lib/integration/Project.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ export default class Project {
}
}

isNPM() {
return fs.existsSync(path.join(cwd, 'src/package.json'))
}

tryThrowInvalidPath () {
if (this.containsManifestFile) return
this.logger?.error('Fatal error: please run above commands in adapt course directory.')
Expand Down Expand Up @@ -82,6 +86,7 @@ export default class Project {

async getInstalledDependencies () {
const getDependencyBowerJSONs = async () => {
// TODO: npm implementation
const glob = `${this.cwd.replace(/\\/g, '/')}/src/**/bower.json`
const bowerJSONPaths = await new Promise((resolve, reject) => {
globs(glob, (err, matches) => {
Expand Down
Loading