function addNameRange (name, range, data, cb) { if (typeof cb !== "function") cb = data, data = null range = semver.validRange(range) if (range === null) return cb(new Error( "Invalid version range: "+range)) log.silly("addNameRange", {name:name, range:range, hasData:!!data}) if (data) return next() registry.get(name, function (er, d, json, response) { if (er) return cb(er) data = d next() }) function next () { log.silly( "addNameRange", "number 2" , {name:name, range:range, hasData:!!data}) engineFilter(data) log.silly("addNameRange", "versions" , [data.name, Object.keys(data.versions || {})]) // if the tagged version satisfies, then use that. var tagged = data["dist-tags"][npm.config.get("tag")] if (tagged && data.versions[tagged] && semver.satisfies(tagged, range)) { return addNamed(name, tagged, data.versions[tagged], cb) } // find the max satisfying version. var ms = semver.maxSatisfying(Object.keys(data.versions || {}), range) if (!ms) { return cb(installTargetsError(range, data)) } // if we don't have a registry connection, try to see if // there's a cached copy that will be ok. addNamed(name, ms, data.versions[ms], cb) } }
Object.keys(deps).forEach(function (name) { var version = deps[name] var repo var gh if (semver.valid(version, true) || semver.validRange(version)) { // maybe make loose? repo = 'https://nlz.io/npm/-/' + name + '/' + version } else if (gh = parseGH(version)) { // github dependencies repo = 'https://nlz.io/github/' + gh[0] + '/' + gh[1] + '/' + (gh[2] || '*') } else { // everything else is * log(this.root + 'normalize-debug.log', 'error', 'could not resolve dependency ' + name + '@"' + version + '". resolving to *') repo = 'https://nlz.io/npm/-/' + name + '/*' } repos.push(repo) dependencies[name] = repo }, this)
const getInstallPackage = function (version, tag, useStable) { const packageToInstall = 'react-native-windows'; const validVersion = semver.valid(version); const validRange = semver.validRange(version); if ((validVersion && !semver.gtr(validVersion, '0.26.*')) || (!validVersion && validRange && semver.gtr('0.27.0', validRange))) { console.error( 'Please upgrade react-native to ^0.27 or specify a --windowsVersion that is >=0.27.0' ); process.exit(1); } if (validVersion) { return Promise.resolve(`${packageToInstall}@${resultVersion}`); } else if (validRange) { return getMatchingVersion(version, tag, useStable) .then(resultVersion => `${packageToInstall}@${resultVersion}`); } else { return Promise.resolve(version); } };
function makeCaretRange(dependencies, name) { const version = dependencies[name]; if (typeof version === 'undefined') { console.error(chalk.red(`Missing ${name} dependency in package.json`)); process.exit(1); } let patchedVersion = `^${version}`; if (!semver.validRange(patchedVersion)) { console.error( `Unable to patch ${name} dependency version because version ${chalk.red( version )} will become invalid ${chalk.red(patchedVersion)}` ); patchedVersion = version; } dependencies[name] = patchedVersion; }
/* * Returns an array full of objects of dependency requirements that are not met. * reqs - CordovaDependency object from plugin's package.json * pluginMap - previously installed plugins in the project * platformMap - previously installed platforms in the project * cordovaVersion - version of cordova being used */ function getFailedRequirements (reqs, pluginMap, platformMap, cordovaVersion) { var failed = []; var version = cordovaVersion; if (semver.prerelease(version)) { // semver.inc with 'patch' type removes prereleased tag from version version = semver.inc(version, 'patch'); } for (var req in reqs) { if (reqs.hasOwnProperty(req) && typeof req === 'string' && semver.validRange(reqs[req])) { var badInstalledVersion = null; // remove potential whitespace var trimmedReq = req.trim(); if (pluginMap[trimmedReq] && !semver.satisfies(pluginMap[trimmedReq], reqs[req])) { badInstalledVersion = pluginMap[req]; } else if (trimmedReq === 'cordova' && !semver.satisfies(version, reqs[req])) { badInstalledVersion = cordovaVersion; } else if (trimmedReq.indexOf('cordova-') === 0) { // Might be a platform constraint var platform = trimmedReq.substring(8); if (platformMap[platform] && !semver.satisfies(platformMap[platform], reqs[req])) { badInstalledVersion = platformMap[platform]; } } if (badInstalledVersion) { failed.push({ dependency: trimmedReq, installed: badInstalledVersion.trim(), required: reqs[req].trim() }); } } else { events.emit('verbose', 'Ignoring invalid plugin dependency constraint ' + req + ':' + reqs[req]); } } return failed; }
components.forEach(function(item) { if (typeof posMap[item.name] !== 'undefined') { var target = finalList[posMap[item.name]]; var finalItem = target; // 版本一致直接跳过。 if (target.version === item.version) { return; } // 原有版本不符合制定版本要求,而先版本符合,那就直接替换吧。 if (specified[item.name] && !satisfies(target.version, specified[item.name]) && satisfies(item.version, specified[item.name])) { finalItem = item; finalList.splice(posMap[item.name], 1, item); return; } // 现有版本不符合制定要求,那还是不要换了。 if (specified[item.name] && !satisfies(item.version, specified[item.name])) { !notified[item.name + '@' + item.version] && fis.log.warning(item.name + '@' + item.version + ' don\'t satisfy the version ' + item.name + '@' + specified[item.name] + ' you specified. The version ' + finalItem.name + '@' + finalItem.version + ' will be keeped!'); notified[item.name + '@' + item.version] = true; return; } // 用户没有指定要什么版本,那就用最新的版本 // 不满足需求,那就在入口指定版本吧。 if (semver.valid(item.version) && semver.validRange(target.version) && semver.gt(item.version, target.version)) { finalItem = item; finalList.splice(posMap[item.name], 1, item); } if (!alerted[item.name + '@' + item.version]) { fis.log.warning(item.name + '@' + item.version + ' conflict againest with ' + target.name + '@' + target.version + ', version ' + finalItem.name + '@' + finalItem.version + ' will be used!'); alerted[item.name + '@' + item.version] = true; } } else { posMap[item.name] = finalList.length; finalList.push(item); } });
Package.prototype.updateRequired = function() { if (!this.versionInstalled) { return true; } var version = this.versionSpecified; if (isGitRepo(version)) { var parts = version.split('#'); if (parts.length === 2) { version = semver.valid(parts[1]); if (!version) { return false; } } } if (!semver.validRange(version)) { return false; } return !semver.satisfies(this.versionInstalled, version); };
var server = http.createServer(function(request, response) { if (!request.headers.hasOwnProperty(HEADER)) { response.statusCode = 400 response.end('Missing X-API-Version header') } else { var range = request.headers[HEADER] if (!semver.validRange(range)) { response.statusCode = 400 response.end('Invalid X-API-Version range') } else { // Iterate version-to-host mappings. var matching = versions .filter(function(version) { return semver.satisfies(version, range) }) .sort(semver.rcompare) // If we find matches, proxy to the highest-version host. if (matching.length !== 0) { var latestTarget = targets[matching[0]] proxy.web(request, response, { target: latestTarget }) } else { response.statusCode = 400 response.end('Unsupported X-API-Version') } } } })
.then(function(lookup) { if (!(nodeSemver.validRange(version))) vMatch = version; else vMatch = Object.keys(lookup.versions) .filter(nodeSemver.valid) .sort(nodeSemver.compare).reverse() .filter(function(v) { return nodeSemver.satisfies(v, version); })[0]; vMatchLookup = lookup.versions[vMatch]; return asp(fs.readFile)(path.resolve(dlDir, '.hash')) .then(function(_hash) { return _hash.toString() === vMatchLookup.hash; }, function (e) { if (e.code === 'ENOENT') return; throw e; }); })
versions.every(function(current) { var normalized = current.replace(/^v\s*/i, ''); if (normalized === version || semver.valid(current) && semver.validRange(version) && semver.satisfies(current, version) ) { resolved = current; return false; } // if (!/^\d+(\.\d+)*$/.test(normalized) && normalized === version) { // resolved = current; // return false; // } else if (/\d/.test(normalized) && semver.satisfies(normalized, version)) { // resolved = current; // return false; // } return true; });
}, function(err, pkgData) { // If a bundled plugin/theme is not present, skip the dep check (#3384) if (err && err.code === 'ENOENT' && (module.startsWith('nodebb-plugin') || module.startsWith('nodebb-theme'))) { winston.warn('[meta/dependencies] Bundled plugin ' + module + ' not found, skipping dependency check.'); return next(true); } try { pkgData = JSON.parse(pkgData); var ok = !semver.validRange(pkg.dependencies[module]) || semver.satisfies(pkgData.version, pkg.dependencies[module]); if (ok || (pkgData._resolved && pkgData._resolved.indexOf('//github.com') !== -1)) { next(true); } else { process.stdout.write('[' + 'outdated'.yellow + '] ' + module.bold + ' installed v' + pkgData.version + ', package.json requires ' + pkg.dependencies[module] + '\n'); next(false); } } catch(e) { winston.error('[meta/dependencies] Could not read: ' + module); process.exit(); } });
it('installs an adapter with --save-exact', function() { this.timeout(config.maxTimeout); // this could take a while // SETUP // Add a first adapter sh.cd(config.paths.endUserRepo); commitizenInit(sh, config.paths.endUserRepo, 'cz-conventional-changelog', {saveExact: true}); let packageJson = util.getParsedPackageJsonFromPath(config.paths.endUserRepo); // TEST expect(packageJson.devDependencies).to.have.property('cz-conventional-changelog'); let range = packageJson.devDependencies['cz-conventional-changelog']; // It should satisfy the requirements of a range expect(semver.validRange(range)).to.not.equal(null); // But you CAN increment a single version expect(semver.inc(range, 'major')).not.to.equal(null); });
// For each name-and-range pair... function (dependency, done) { var range = semver.validRange(dependency.range) if (range === null) { done(null, [ { name: dependency.name, version: dependency.range, range: range, links: [] } ]) } else { // ...find the dependency tree for the highest version that // satisfies the range. findMaxSatisfying( directory, sequence, dependency.name, dependency.range, function (error, result) { if (error) { /* istanbul ignore else */ if (error.noSatisfying) { done(null, [ { name: error.dependency.name, range: error.dependency.range, missing: true, links: [] } ]) } else { done(error) } } else { done(null, result) } } ) } },
module.exports = function (bin, versionRange, cb) { if (typeof bin !== 'string' || typeof versionRange !== 'string') { throw new Error('`binary` and `versionRange` required'); } if (!semver.validRange(versionRange)) { return cb(new Error('Invalid version range')); } binVersion(bin, function (err, binVersion) { if (err) { return cb(err); } if (!semver.satisfies(semverTruncate(binVersion, 'patch'), versionRange)) { err = new Error(bin + ' ' + binVersion + ' does not satisfy the version requirement of ' + versionRange); err.name = 'InvalidBinVersion'; return cb(err); } cb(); }); };
function deprecate (name, ver, message, cb) { if (!this.conf.get('username')) { return cb(new Error("Must be logged in to deprecate a package")) } if (semver.validRange(ver) === null) { return cb(new Error("invalid version range: "+ver)) } var users = {} this.get(name + '?write=true', function (er, data) { if (er) return cb(er) // filter all the versions that match Object.keys(data.versions).filter(function (v) { return semver.satisfies(v, ver) }).forEach(function (v) { data.versions[v].deprecated = message }) // now update the doc on the registry this.request('PUT', data._id, data, cb) }.bind(this)) }
server.query = function (roleVer) { if (roleVer === undefined) { return roles; } else { var role = roleVer.split('@')[0]; var version = roleVer.split('@')[1]; if (version === undefined) { return roles[role] || []; } else if (!semver.validRange(version)) { return (roles[role] || []).filter(function (r) { return version === r.version; }); } else { return (roles[role] || []).filter(function (r) { return semver.satisfies(r.version, version); }); } } };
function addNamed (name, version, data, cb_) { assert(typeof name === "string", "must have module name") assert(typeof cb_ === "function", "must have callback") var key = name + "@" + version log.silly("addNamed", key) function cb (er, data) { if (data && !data._fromGithub) data._from = key cb_(er, data) } if (semver.valid(version, true)) { log.verbose('addNamed', JSON.stringify(version), 'is a plain semver version for', name) addNameVersion(name, version, data, cb) } else if (semver.validRange(version, true)) { log.verbose('addNamed', JSON.stringify(version), 'is a valid semver range for', name) addNameRange(name, version, data, cb) } else { log.verbose('addNamed', JSON.stringify(version), 'is being treated as a dist-tag for', name) addNameTag(name, version, data, cb) } }
/** * Returns the latest version of the specified module on npm that matches the specified version or range. * @param {string} module_name - npm module name. * @param {string} version - semver version or range (loose allowed). * @returns {Promise} Promise for version (a valid semver version if one is found, otherwise whatever was provided). */ function getLatestMatchingNpmVersion(module_name, version) { if (!version) { // If no version specified, get the latest return getLatestNpmVersion(module_name); } var validVersion = semver.valid(version, /* loose */ true); if (validVersion) { // This method is really intended to work with ranges, so if a version rather than a range is specified, we just // assume it is available and return it, bypassing the need for the npm call. return Q(validVersion); } var validRange = semver.validRange(version, /* loose */ true); if (!validRange) { // Just return what we were passed return Q(version); } return getAvailableNpmVersions(module_name).then(function (versions) { return semver.maxSatisfying(versions, validRange) || version; }); }
const hasDepVersZero = (packageJsonData, nodeName) => { if (!packageJsonData.hasOwnProperty(nodeName)) { return false; } for (const dependencyName in packageJsonData[nodeName]) { const dependencyVersRange = packageJsonData[nodeName][dependencyName]; if (semver.validRange(dependencyVersRange)) { const startIndex = 0; const length = 1; const dependencyVersion = dependencyVersRange.replace(/[\D]+/g, ''); const dependencyMjrVersion = dependencyVersion.substr(startIndex, length); // if first char is 0 then major version is 0 if (dependencyMjrVersion === '0') { return true; } } } return false; };
.then(function() { var saveVersion = !spec || semver.validRange(spec, true); // Save platform@spec into platforms.json, where 'spec' is a version or a soure location. If a // source location was specified, we always save that. Otherwise we save the version that was // actually installed. var versionToSave = saveVersion ? platDetails.version : spec; events.emit('verbose', 'Saving ' + platform + '@' + versionToSave + ' into platforms.json'); platformMetadata.save(projectRoot, platform, versionToSave); if(opts.save || autosave){ // Similarly here, we save the source location if that was specified, otherwise the version that // was installed. However, we save it with the "~" attribute (this allows for patch updates). spec = saveVersion ? '~' + platDetails.version : spec; // Save target into config.xml, overriding already existing settings events.emit('log', '--save flag or autosave detected'); events.emit('log', 'Saving ' + platform + '@' + spec + ' into config.xml file ...'); cfg.removeEngine(platform); cfg.addEngine(platform, spec); cfg.write(); } });
getDependency(depName, function(err, dep) { processedDeps++; if(err) { console.log('Failed to get dependency', depName, err); } else { var pkgDepVersion = manifest.dependencies[depName]; var range = semver.validRange(pkgDepVersion); if(!range || !semver.satisfies(dep.version, range)) { updatedPkgs[depName] = dep.version; } } if(processedDeps == depNames.length) { callback(null, updatedPkgs); } });
/** * Given dep, an object obtained by calling getDependencies, determine whether dep.required (the version specified * in package.json) is out of date wrt dep.stable or dep.latest. * @param {Object} dep * @param {Object} [opts] Options * @param {Boolean} [opts.stable] Consider only stable packages * @param {Boolean} [opts.loose] Use loose option when querying semver * @returns {boolean} */ function isUpdated (dep, opts) { var required = dep.required || "*" // TODO: Handle tags correctly if (required != "latest" && required != "*") { var range = semver.validRange(required, opts.loose) || "" , version = opts.stable ? dep.stable : dep.latest if (version) { if (!range) { return true } else if (!semver.satisfies(version, range, opts.loose)) { if (opts.stable && semverext.gtr(version, range, opts.loose)) { return true } else if (!opts.stable) { return true } } } } return false }
function deprecate (args, cb) { var pkg = args[0] , msg = args[1] if (msg === undefined) return cb("Usage: " + deprecate.usage) // fetch the data and make sure it exists. pkg = pkg.split(/@/) var name = pkg.shift() , ver = pkg.join("@") if (semver.validRange(ver) === null) { return cb(new Error("invalid version range: "+ver)) } registry.get(name, function (er, data) { if (er) return cb(er) // filter all the versions that match Object.keys(data.versions).filter(function (v) { return semver.satisfies(v, ver, true) }).forEach(function (v) { data.versions[v].deprecated = msg }) // now update the doc on the registry registry.request('PUT', data._id, data, cb) }) }
var getValidRange4Version = function(category, name, range) { var ans = []; var str = undefined; var vers = undefined; var idx = 0; str = semver.validRange(range); vers = str.split(" "); name = normalizePkgName(name); for (idx in vers) { if (vers[idx].substring(0,1) == ">=") { ans.push(sprintf(">=%s/%s-%s", category, name, replaceall('-rc', '_rc', vers[idx].substring(2)))); } else if (vers[idx].substring(0,1) == "<") { ans.push(sprintf("<%s/%s-%s", category, name, replaceall('-rc', '_rc', vers[idx].substring(1)))); } else if (vers[idx].substring(0,1) == ">") { ans.push(sprintf(">%s/%s-%s", category, name, replaceall('-rc', '_rc', vers[idx].substring(1)))); } } // end for return ans; };
Package.prototype.resolve = unyield(function *() { // if it's a valid version // or invalid range, no need to resolve. if (semver.valid(this.ref) || !semver.validRange(this.ref)) { this.debug('don\'t need to resolve %s', this.ref); this.resolved = this.ref; return this.resolved; } // check if ref is in the cache var slug = this.repo + '@' + this.ref; this.resolved = this.resolved || cached(this.repo, this.ref); // resolved if (this.resolved) { this.debug('resolved from cache %s', this.resolved); return this.resolved; } // resolving this.emit('resolving'); this.debug('resolving'); // resolve var ref = yield resolve(slug, { token: this.tok }); // couldn't resolve if (!ref) throw this.error('%s: reference %s not found', this.slug(), this.ref); // resolved this.resolved = ref.name; (refs[this.repo] = refs[this.repo] || []).push(ref.name); this.debug('resolved'); this.emit('resolve'); return ref.name; });
var plugins = cfg.getPlugins().map(function (plugin) { var result = { name: plugin.name }; if (semver.validRange(plugin.spec, true)) { result.version = plugin.spec; } else { result.src = plugin.spec; } var variablesObject = plugin.variables; var variablesArray = []; if (variablesObject) { for (var variable in variablesObject) { variablesArray.push({ name: variable, value: variablesObject[variable] }); } } result.variables = variablesArray; return result; });
function next (er) { if (errState) return if (er) { errState = er return cb(null, []) } //console.error('next', installed, obj && typeof obj, name, real) if (!installed || !obj || !real || called) return called = true if (rpSeen[real]) return cb(null, rpSeen[real]) if (obj === true) { obj = {dependencies:{}, path:folder} installed.forEach(function (i) { obj.dependencies[i] = "*" }) } if (name && obj.name !== name) obj.invalid = true obj.realName = name || obj.name obj.dependencies = obj.dependencies || {} // "foo":"http://blah" is always presumed valid if (reqver && semver.validRange(reqver) && !semver.satisfies(obj.version, reqver)) { obj.invalid = true } if (parent && !(name in parent.dependencies) && !(name in (parent.devDependencies || {}))) { obj.extraneous = true } obj.path = obj.path || folder obj.realPath = real obj.link = link if (parent && !obj.link) obj.parent = parent rpSeen[real] = obj obj.depth = depth //if (depth >= maxDepth) return cb(null, obj) asyncMap(installed, function (pkg, cb) { var rv = obj.dependencies[pkg] if (!rv && obj.devDependencies) rv = obj.devDependencies[pkg] if (depth >= maxDepth) { // just try to get the version number var pkgfolder = path.resolve(folder, "node_modules", pkg) , jsonFile = path.resolve(pkgfolder, "package.json") return readJson(jsonFile, function (er, depData) { // already out of our depth, ignore errors if (er || !depData || !depData.version) return cb(null, obj) obj.dependencies[pkg] = depData.version cb(null, obj) }) } readInstalled_( path.resolve(folder, "node_modules/"+pkg) , obj, pkg, obj.dependencies[pkg], depth + 1, maxDepth , cb ) }, function (er, installedData) { if (er) return cb(er) installedData.forEach(function (dep) { obj.dependencies[dep.realName] = dep }) // any strings here are unmet things. however, if it's // optional, then that's fine, so just delete it. if (obj.optionalDependencies) { Object.keys(obj.optionalDependencies).forEach(function (dep) { if (typeof obj.dependencies[dep] === "string") { delete obj.dependencies[dep] } }) } return cb(null, obj) }) }
var _ref = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (config, reporter, flags, args) { const lockfile = yield (_wrapper || _load_wrapper()).default.fromDirectory(config.cwd); const install = new (_install || _load_install()).Install(flags, config, reporter, lockfile); function humaniseLocation(loc) { const relative = path.relative(path.join(config.cwd, 'node_modules'), loc); const normalized = path.normalize(relative).split(path.sep); return normalized.filter(p => p !== 'node_modules'); } let warningCount = 0; let errCount = 0; function reportError(msg) { reporter.error(msg); errCount++; } // get patterns that are installed when running `yarn install` var _ref2 = yield install.hydrate(); var _ref3 = (0, (_slicedToArray2 || _load_slicedToArray()).default)(_ref2, 2); const rawPatterns = _ref3[1]; // check if patterns exist in lockfile for (const pattern of rawPatterns) { if (!lockfile.getLocked(pattern)) { reportError(`Lockfile does not contain pattern: ${ pattern }`); } } if (flags.integrity) { // just check the integrity hash for validity const integrityLoc = yield install.getIntegrityHashLocation(); if (integrityLoc && (yield (_fs || _load_fs()).exists(integrityLoc))) { const match = yield install.matchesIntegrityHash(rawPatterns); if (match.matches === false) { reportError(`Integrity hashes don't match, expected ${ match.expected } but got ${ match.actual }`); } } else { reportError("Couldn't find an integrity hash file"); } } else { // check if any of the node_modules are out of sync const res = yield install.linker.getFlatHoistedTree(rawPatterns); for (const _ref4 of res) { var _ref5 = (0, (_slicedToArray2 || _load_slicedToArray()).default)(_ref4, 2); const loc = _ref5[0]; var _ref5$ = _ref5[1]; const originalKey = _ref5$.originalKey; const pkg = _ref5$.pkg; const parts = humaniseLocation(loc); // grey out hoisted portions of key let human = originalKey; const hoistedParts = parts.slice(); const hoistedKey = parts.join('#'); if (human !== hoistedKey) { const humanParts = human.split('#'); for (let i = 0; i < humanParts.length; i++) { const humanPart = humanParts[i]; if (hoistedParts[0] === humanPart) { hoistedParts.shift(); if (i < humanParts.length - 1) { humanParts[i] += '#'; } } else { humanParts[i] = reporter.format.dim(`${ humanPart }#`); } } human = humanParts.join(''); } const pkgLoc = path.join(loc, 'package.json'); if (!(yield (_fs || _load_fs()).exists(loc)) || !(yield (_fs || _load_fs()).exists(pkgLoc))) { reportError(`${ human } not installed`); continue; } const packageJson = yield (_fs || _load_fs()).readJson(pkgLoc); if (pkg.version !== packageJson.version) { // node_modules contains wrong version reportError(`${ human } is wrong version: expected ${ pkg.version }, got ${ packageJson.version }`); } const deps = Object.assign({}, packageJson.dependencies, packageJson.peerDependencies); for (const name in deps) { const range = deps[name]; if (!semver.validRange(range, config.looseSemver)) { continue; // exotic } const subHuman = `${ human }#${ name }@${ range }`; // find the package that this will resolve to, factoring in hoisting const possibles = []; let depPkgLoc; for (let i = parts.length; i >= 0; i--) { const myParts = parts.slice(0, i).concat(name); // build package.json location for this position const myDepPkgLoc = path.join(config.cwd, 'node_modules', myParts.join(`${ path.sep }node_modules${ path.sep }`), 'package.json'); possibles.push(myDepPkgLoc); } while (possibles.length) { const myDepPkgLoc = possibles.shift(); if (yield (_fs || _load_fs()).exists(myDepPkgLoc)) { depPkgLoc = myDepPkgLoc; break; } } if (!depPkgLoc) { // we'll hit the module not install error above when this module is hit continue; } // const depPkg = yield (_fs || _load_fs()).readJson(depPkgLoc); const foundHuman = `${ humaniseLocation(path.dirname(depPkgLoc)).join('#') }@${ depPkg.version }`; if (!semver.satisfies(depPkg.version, range, config.looseSemver)) { // module isn't correct semver reportError(`${ subHuman } doesn't satisfy found match of ${ foundHuman }`); continue; } // check for modules above us that this could be deduped to for (const loc of possibles) { if (!(yield (_fs || _load_fs()).exists(loc))) { continue; } const packageJson = yield (_fs || _load_fs()).readJson(loc); if (packageJson.version === depPkg.version || semver.satisfies(packageJson.version, range, config.looseSemver) && semver.gt(packageJson.version, depPkg.version, config.looseSemver)) { reporter.warn(`${ subHuman } could be deduped from ${ packageJson.version } to ` + `${ humaniseLocation(path.dirname(loc)).join('#') }@${ packageJson.version }`); warningCount++; } break; } } } } if (warningCount > 1) { reporter.info(reporter.lang('foundWarnings', warningCount)); } if (errCount > 0) { throw new (_errors || _load_errors()).MessageError(reporter.lang('foundErrors', errCount)); } else { reporter.success(reporter.lang('folderInSync')); } });
var process = function(d) { var dep = dependencies[d]; var match, name, version = ''; // 1. git://github.com/name/repo.git#version -> github:name/repo@version if ((match = dep.match(githubRegEx))) { dep = match[3]; name = 'github:' + dep.split('#')[0]; version = dep.split('#')[1] || '*'; if (version.substr(0, 1) == 'v' && version.substr(1).match(semverRegEx)) version = version.substr(1); if (name.substr(name.length - 4, 4) == '.git') name = name.substr(0, name.length - 4); ui.log('warn', 'npm dependency `' + name + '@' + version + '` will likely only work if its GitHub repo has %registry: npm% in its package.json'); } // 2. https?://github.com/name/repo/archive/v?[semver].tar.gz -> github:name/repo@[semver] else if ((match = dep.match(githubHttpRegEx))) { name = 'github:' + match[1]; version = match[2]; if (version.substr(0, 1) == 'v' && version.substr(1).match(semverRegEx)) version = version.substr(1); } // 3. url:// or file: -> not supported else if (dep.match(protocolRegEx) || dep.substr(0, 5) == 'file:') throw 'npm dependency format ' + dep + ' not supported by jspm.'; // 4. name/repo#version -> github:name/repo@version else if (dep.split('/').length == 2) { name = 'github:' + dep.split('#')[0]; version = dep.split('#')[1] || '*'; } // 5. github:package/name#version else if ((match = dep.match(githubShorthandRegEx))) { name = 'github:' + match[1]; version = match[2] ? match[2].substr(1) : '*'; } // 6. registry:package/name@version else if ((match = dep.match(canonicalRegEx))) { name = 'github:' + match[1]; version = match[2] ? match[2].substr(1) : '*'; } // 6. version -> name@version else { name = d; version = dep; } // otherwise, we convert an npm range into something jspm-compatible // if it is an exact semver, or a tag, just use it directly if (!nodeSemver.valid(version)) { var range; // comma space is allowed on npm for some reason version = version.replace(/, /g, ' '); if (!version || version == 'latest' || version == '*') version = '*'; // if we have a semver or fuzzy range, just keep as-is else if (version.indexOf(/[ <>=]/) != -1 || !version.substr(1).match(semverRegEx) || !version.substr(0, 1).match(/[\^\~]/)) range = nodeSemver.validRange(version); if (range == '*') version = '*'; else if (range) { // if it has OR semantics, we only support the last range if (range.indexOf('||') != -1) range = range.split('||').pop(); var rangeParts = range.split(' '); // convert AND statements into a single lower bound and upper bound // enforcing the lower bound as inclusive and the upper bound as exclusive var lowerBound, upperBound, lEq, uEq; for (var i = 0; i < rangeParts.length; i++) { var part = rangeParts[i]; var a = part.charAt(0); var b = part.charAt(1); // get the version var v = part; if (b == '=') v = part.substr(2); else if (a == '>' || a == '<' || a == '=') v = part.substr(1); // and the operator var gt = a == '>'; var lt = a == '<'; if (gt) { // take the highest lower bound if (!lowerBound || nodeSemver.gt(lowerBound, v)) { lowerBound = v; lEq = b == '='; } } else if (lt) { // take the lowest upper bound if (!upperBound || nodeSemver.lt(upperBound, v)) { upperBound = v; uEq = b == '='; } } else { // equality lowerBound = upperBound = (part.substr(0, 1) == '=' ? part.substr(1) : part); lEq = uEq = true; break; } } // for some reason nodeSemver adds "-0" when not appropriate if (lowerBound && lowerBound.substr(lowerBound.length - 2, 2) == '-0') lowerBound = lowerBound.substr(0, lowerBound.length - 2); if (upperBound && upperBound.substr(upperBound.length - 2, 2) == '-0') upperBound = upperBound.substr(0, upperBound.length - 2); var lowerSemver, upperSemver; if (lowerBound) { lowerSemver = lowerBound.match(semverRegEx); lowerSemver[1] = parseInt(lowerSemver[1], 10); lowerSemver[2] = parseInt(lowerSemver[2], 10); lowerSemver[3] = parseInt(lowerSemver[3], 10); if (!lEq) { //if (!lowerSemver[4]) lowerSemver[4] = '0'; // NB support incrementing existing preleases } } if (upperBound) { upperSemver = upperBound.match(semverRegEx); upperSemver[1] = parseInt(upperSemver[1], 10); upperSemver[2] = parseInt(upperSemver[2], 10); upperSemver[3] = parseInt(upperSemver[3], 10); } if (!upperBound && !lowerBound) { version = ''; } // if not upperBound, then just treat as a wildcard else if (!upperBound) { version = '*'; } // if no lowerBound, use the upperBound directly, with sensible decrementing if necessary else if (!lowerBound) { if (uEq) { version = upperBound; } else { if (!upperSemver[4]) { lEq = true; if (upperSemver[3] > 0) { lowerSemver = [undefined, upperSemver[1], upperSemver[2], upperSemver[3] - 1]; } else if (upperSemver[2] > 0) { lowerSemver = [undefined, upperSemver[1], upperSemver[2] - 1, 0]; } else if (upperSemver[1] > 0) { lowerSemver = [undefined, upperSemver[1] - 1, 0, 0]; } } else { upperSemver[4] = undefined; version = getVersion(upperSemver); } } } if (upperSemver && lowerSemver) { // if upper bound is inclusive, use it if (uEq) version = upperBound; // if upper bound is exact major else if (upperSemver[2] === 0 && upperSemver[3] === 0 && !upperSemver[4]) { // if previous major is 0 if (upperSemver[1] - 1 === 0) { version = '0'; } else { // if lower bound is major below, we are semver compatible if (lowerSemver[1] == upperSemver[1] - 1) version = '^' + getVersion(lowerSemver); // otherwise we are semver compatible with the previous exact major else version = '^' + (upperSemver[1] - 1); } } // if upper bound is exact minor else if (upperSemver[3] === 0 && !upperSemver[4]) { // if lower bound is minor below, we are fuzzy compatible if (lowerSemver[2] == upperSemver[2] - 1) version = '~' + getVersion(lowerSemver); // otherwise we are fuzzy compatible with previous else version = '~' + upperSemver[1] + '.' + (upperSemver[2] - 1) + '.0'; } // if upper bound is exact version -> use exact else { if (lEq) version = getVersion(lowerSemver); else throw 'Unable to translate npm version ' + version + ' into a jspm range.'; } } } } // replace ~x.y.0 with x.y shorthand var shorthandMatch = version && version.match(/^~(\d+)\.(\d+)\.0$/) if (shorthandMatch) version = shorthandMatch[1] + '.' + shorthandMatch[2]; outDependencies[d] = name + (version ? '@' + version : ''); };
/** * Get the available versions for each packages. * @param {Array} pkgs a list of the packages * @returns {Promise} a promise that will return all the available packages versions */ _getPackagesVersions: function (pkgs) { return Promise.all(pkgs.reduce((promises, pkg) => { promises.push(_npm.getVersions(pkg)) return promises }, [])) }, /** * Get the fixed package version. * @param {String} target the current version (might be a range) * @param {Array} availablePkgVersions the available versions * @returns {String} a fixed package version */ _getTargetVersion (target, availablePkgVersions) { const validRange = _semver.validRange(target) let version if (validRange) { version = _semver.maxSatisfying(availablePkgVersions, target) } else { version = _semver.valid(target) } return version } }