Skip to content
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