Example #1
0
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)
  }
}
Example #2
0
  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);
  }
};
Example #4
0
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;
}
Example #5
0
/*
 * 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') } } } })
Example #9
0
  .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;
    });
  })
Example #10
0
        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;
        });
Example #11
0
			}, 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();
				}
			});
Example #12
0
 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)
         }
       }
     )
   }
 },
Example #14
0
File: index.js Project: 02468/msb
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();
	});
};
Example #15
0
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))
}
Example #16
0
 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)
  }
}
Example #18
0
/**
 * 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();
                    }
                });
Example #21
0
			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);
				}
			});
Example #22
0
/**
 * 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
}
Example #23
0
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)
  })
}
Example #24
0
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;
};
Example #25
0
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;
});
Example #26
0
    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;
    });
Example #27
0
  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)
    })
  }
Example #28
0
  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'));
    }
  });
Example #29
0
  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 : '');
  };
Example #30
0
  /**
   * 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
  }
}