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
2 changes: 2 additions & 0 deletions lib/cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import unregister from './commands/unregister.js'
import update from './commands/update.js'
import version from './commands/version.js'
import logger from './logger.js'
import { isNPM } from './integration/PluginManagement/npm.js'
import './econnreset.js'

const commands = {
Expand Down Expand Up @@ -53,6 +54,7 @@ class CLI {

async execute () {
try {
logger.info(`using ${await isNPM() ? 'NPM' : 'BOWER'} registry...`)
if (!commands[this.command.name]) {
const e = new Error(`Unknown command "${this.command.name}", please check the documentation.`)
logger?.log(e.message)
Expand Down
58 changes: 50 additions & 8 deletions lib/integration/Plugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import endpointParser from 'bower-endpoint-parser'
import semver from 'semver'
import fs from 'fs-extra'
import path from 'path'
import { fetchAllInfo, fetchVersionInfo, fetchRepoUrl } from './PluginManagement/npm.js'
import getBowerRegistryConfig from './getBowerRegistryConfig.js'
import { ADAPT_ALLOW_PRERELEASE, PLUGIN_TYPES, PLUGIN_TYPE_FOLDERS, PLUGIN_DEFAULT_TYPE } from '../util/constants.js'
/** @typedef {import("./Project.js").default} Project */
Expand Down Expand Up @@ -57,7 +58,7 @@ export default class Plugin {
const isLocalPath = (isNameAPath || isVersionAPath)
if (isLocalPath) {
// wait to name the plugin until the local config file is loaded
this.sourcePath = isNameAPath ? this.name : this.requestedVersion
this.sourcePath = path.resolve(this.cwd, isNameAPath ? this.name : this.requestedVersion)
this.name = isVersionAPath ? this.packageName : ''
this.packageName = isNameAPath ? '' : this.packageName
this.requestedVersion = '*'
Expand All @@ -79,7 +80,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 @@ -178,24 +179,30 @@ export default class Plugin {

async fetchSourceInfo () {
if (this.isLocalSource) return await this.fetchLocalSourceInfo()
await this.fetchBowerInfo()
await this.fetchRegistryInfo()
}

async fetchLocalSourceInfo () {
if (this._sourceInfo) return this._sourceInfo
this._sourceInfo = null
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')
// TODO: sourcePath for adapt devinstall modules
this._sourceInfo = await new Promise((resolve, reject) => {
// get bower.json data
// get package.json or bower.json data
const paths = [
path.resolve(this.cwd, `${this.sourcePath}/package.json`),
path.resolve(this.cwd, `${this.sourcePath}/bower.json`)
]
const bowerJSON = paths.reduce((bowerJSON, bowerJSONPath) => {
if (bowerJSON) return bowerJSON
if (!fs.existsSync(bowerJSONPath)) return null
return fs.readJSONSync(bowerJSONPath)
}, null)
const hasPackageJSON = fs.existsSync(paths[0])
if (this.project.isNPM && !hasPackageJSON) {
fs.copySync(paths[1], paths[0])
}
resolve(bowerJSON)
})
if (!this._sourceInfo) return
Expand All @@ -204,12 +211,20 @@ export default class Plugin {
this.packageName = this.name
}

async fetchBowerInfo () {
async fetchRegistryInfo () {
if (this._sourceInfo) return this._sourceInfo
this._sourceInfo = null
if (this.isLocalSource) return
const isNPM = await this.project.isNPM()
const perform = async (attemptCount = 0) => {
try {
if (isNPM) {
return await fetchAllInfo({
logger: this.logger,
cwd: this.cwd,
packageName: this.packageName
})
}
return await new Promise((resolve, reject) => {
bower.commands.info(`${this.packageName}`, null, { cwd: this.cwd, registry: this.BOWER_REGISTRY_CONFIG })
.on('end', resolve)
Expand All @@ -227,12 +242,19 @@ 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
// get package.json or bower.json data
globs([
`${this.cwd.replace(/\\/g, '/')}/src/node_modules/${this.packageName}/.package.json`,
`${this.cwd.replace(/\\/g, '/')}/src/node_modules/${this.packageName}/package.json`,
`${this.cwd.replace(/\\/g, '/')}/src/*/${this.packageName}/.bower.json`,
`${this.cwd.replace(/\\/g, '/')}/src/*/${this.packageName}/bower.json`
], (err, matches) => {
Expand All @@ -242,8 +264,10 @@ export default class Plugin {
if (!match) {
// widen the search
globs([
`${this.cwd.replace(/\\/g, '/')}/src/**/.bower.json`,
`${this.cwd.replace(/\\/g, '/')}/src/**/bower.json`
`${this.cwd.replace(/\\/g, '/')}/src/node_modules/adapt-*/.package.json`,
`${this.cwd.replace(/\\/g, '/')}/src/node_modules/adapt-*/package.json`,
`${this.cwd.replace(/\\/g, '/')}/src/*/adapt-*/.bower.json`,
`${this.cwd.replace(/\\/g, '/')}/src/*/adapt-*/bower.json`
], (err, matches) => {
if (err) return resolve(null)
const tester = new RegExp(`/${this.packageName}/`, 'i')
Expand All @@ -264,9 +288,18 @@ export default class Plugin {
}

async findCompatibleVersion (framework) {
const isNPM = await this.project.isNPM()
const getBowerVersionInfo = async (version) => {
const perform = async (attemptCount = 0) => {
try {
if (isNPM) {
return await fetchVersionInfo({
logger: this.logger,
cwd: this.cwd,
packageName: this.packageName,
version
})
}
return await new Promise((resolve, reject) => {
bower.commands.info(`${this.packageName}@${version}`, null, { cwd: this.cwd, registry: this.BOWER_REGISTRY_CONFIG })
.on('end', resolve)
Expand Down Expand Up @@ -352,6 +385,15 @@ export default class Plugin {
async getRepositoryUrl () {
if (this._repositoryUrl) return this._repositoryUrl
if (this.isLocalSource) return
const isNPM = await this.project.isNPM()
if (isNPM) {
const url = await fetchRepoUrl({
logger: this.logger,
cwd: this.cwd,
packageName: this.packageName
})
return (this._repositoryUrl = url)
}
const url = await new Promise((resolve, reject) => {
bower.commands.lookup(this.packageName, { cwd: this.cwd, registry: this.BOWER_REGISTRY_CONFIG })
.on('end', resolve)
Expand Down
20 changes: 20 additions & 0 deletions lib/integration/PluginManagement/bower.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import nodeFetch from 'node-fetch'
import getBowerRegistryConfig from '../getBowerRegistryConfig.js'

export async function searchInfo ({
logger,
cwd,
term
}) {
const BOWER_REGISTRY_CONFIG = getBowerRegistryConfig({ cwd })
for (const url of BOWER_REGISTRY_CONFIG.search) {
try {
const pluginUrl = `${url}packages/search/${term}`
const req = await nodeFetch(pluginUrl)
const data = await req.json()
return data ?? []
} catch (err) {
}
}
return []
}
28 changes: 26 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,10 +21,15 @@ 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))
const project = new Project({ cwd, logger })
project.tryThrowInvalidPath()

const isNPM = await project.isNPM()

!isNPM && isClean && await new Promise(resolve => {
bower.commands.cache.clean().on('end', resolve)
})

logger?.log(chalk.cyan(`${dev ? 'cloning' : 'installing'} adapt dependencies...`))

const targets = await getInstallTargets({ logger, project, plugins, isCompatibleEnabled })
Expand All @@ -40,8 +46,26 @@ 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 / (isNPM ? 2 : 1))}% complete`)
)
if (isNPM) {
// Batch install npm plugins as it's faster
const installArgs = installTargetsToBeInstalled
.filter(target => target.isNPMInstall)
.map(target => {
if (target.isLocalSource) {
return `${target.sourcePath}`
}
return `${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
Loading