<commit_before>/*
 *   Copyright 2014 <NAME> (http://guybedford.com)
 *
 *   Licensed under the Apache License, Version 2.0 (the "License");
 *   you may not use this file except in compliance with the License.
 *   You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *   Unless required by applicable law or agreed to in writing, software
 *   distributed under the License is distributed on an "AS IS" BASIS,
 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *   See the License for the specific language governing permissions and
 *   limitations under the License.
 */

var request = require('request');
var ui = require('./ui');
var semver = require('./semver');
var nodeSemver = require('semver');
var Promise = require('rsvp').Promise;
var asp = require('rsvp').denodeify;
var build = require('./build');
var config = require('./config');
var mkdirp = require('mkdirp');
var rimraf = require('rimraf');
var path = require('path');

var ncp = require('ncp');

var crypto = require('crypto');

function md5(input) {
  var md5 = crypto.createHash('md5');
  md5.update(input);
  return md5.digest('hex');
}

var exec = require('child_process').exec;

var fs = require('graceful-fs');

function extend(a, b) {
  for (var p in b)
    a[p] = b[p];
  return a;
}

var _pkg = module.exports;


/*
  Endpoint API

  METHODS
    configure (config) 
      -> Promise for config, expects "name"
    parse (name) 
      -> { package, path }
    lookup (packageName)
      -> { notfound: true } / { redirect: 'new:package' } / { versions: {...} }
    download (packageName, version, hash, dir)
      -> Promise pjson
    getPackageConfig (packageName, version, hash) (optional)
      -> Promise pjson
    build (optional)
      -> pjson (optional)
  
  PROPERTIES
    remote 
      -> remote URL used for jspm setmode remote and injectino

  User-Configuration
    jspm endpoint create jspm-myspecial-endpoint [name]
    jspm endpoint configure github
    jspm config endpoints.github.remote https://custom-remote
*/
var endpointClasses = {};
exports.loadEndpoint = function(endpoint) {
  if (endpointClasses[endpoint])
    return endpointClasses[endpoint];

  try {
    // ensure the tmpDir exists
    var tmpDir = path.resolve(process.env.HOME, '.jspm', 'tmp-' + endpoint);
    if (!fs.existsSync(tmpDir))
      fs.mkdirSync(tmpDir);

    var options = {
      timeout: 120, 
      tmpDir: tmpDir
    };
    extend(options, config.globalConfig.endpoints[endpoint] || {});

    var endpointClass = require(options.handler);

    return endpointClasses[endpoint] = new endpointClass(options);
  }
  catch(e) {
    ui.log('err', e.stack || e);
    throw 'Unable to load endpoint %' + endpoint + '%';
  }
}

/*
  Parse a package name into endpoint:package@version

  name: 'github:jquery/jquery',
  exactName: 'github:jquery/jquery@2.0.3',
  exactPackage: 'jquery/jquery@2.0.3',

  endpoint: 'github',
  package: 'jquery/jquery',
  version: '2.0.3'
*/
var Package = exports.Package = function Package(name) {
  this.exactName = name;

  if (name.indexOf(':') != -1)
    this.endpoint = name.split(':')[0];

  var packageParts = (this.endpoint ? name.substr(this.endpoint.length + 1) : name).split('/');

  var versionSplit = (packageParts[packageParts.length - 1] || '').split('@');

  var version = versionSplit[1] || '';

  packageParts[packageParts.length - 1] = versionSplit[0];
  this.package = packageParts.join('/');

  this.name = (this.endpoint ? this.endpoint + ':' : '') + this.package;

  this.setVersion(version);
}
Package.prototype.setVersion = function(version) {
  this.version = version;
  var v = this.version ? '@' + this.version : '';
  this.exactPackage = this.package + v;
  this.exactName = this.name + v;
}

// lookup a package in the registry if necessary
exports.registryCache;

exports.locate = function(target) {
  if (target.endpoint)
    return Promise.resolve(target);

  if (_pkg.registryCache) {
    var registryEntry = _pkg.registryCache[target.package];
    if (!registryEntry)
      throw '`' + target.exactName + '` not found in registry.';
    return Promise.resolve(new Package(registryEntry));
  }

  // we haven't loaded the registry yet -> load the registry file
  return _pkg.updateRegistry()
  .then(function() {
    return readJSON(path.resolve(registryPath, 'registry.json'));
  })
  .then(function(json) {
    _pkg.registryCache = json;
  })
  .then(function() {
    return _pkg.locate(target);
  });
}

// lookup the latest suitable version for this package range
// if the range is a tag or prerelease, then it is just that
// if the range is compatible with a prerelease, then it is just that
// if the range is compatible with a semver, then it is the 
//   associated stable compatible semver
// if the range is a semver, then it is the latest minor, patch or exact
// also create pkg.hash for the lookup version
var versionCache = {};<commit_msg>fixes #121<commit_after>/*
 *   Copyright 2014 <NAME> (http://guybedford.com)
 *
 *   Licensed under the Apache License, Version 2.0 (the "License");
 *   you may not use this file except in compliance with the License.
 *   You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *   Unless required by applicable law or agreed to in writing, software
 *   distributed under the License is distributed on an "AS IS" BASIS,
 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *   See the License for the specific language governing permissions and
 *   limitations under the License.
 */

var request = require('request');
var ui = require('./ui');
var semver = require('./semver');
var nodeSemver = require('semver');
var Promise = require('rsvp').Promise;
var asp = require('rsvp').denodeify;
var build = require('./build');
var config = require('./config');
var mkdirp = require('mkdirp');
var rimraf = require('rimraf');
var path = require('path');

var ncp = require('ncp');

var crypto = require('crypto');

function md5(input) {
  var md5 = crypto.createHash('md5');
  md5.update(input);
  return md5.digest('hex');
}

var exec = require('child_process').exec;

var fs = require('graceful-fs');

function extend(a, b) {
  for (var p in b)
    a[p] = b[p];
  return a;
}

var _pkg = module.exports;


/*
  Endpoint API

  METHODS
    configure (config) 
      -> Promise for config, expects "name"
    parse (name) 
      -> { package, path }
    lookup (packageName)
      -> { notfound: true } / { redirect: 'new:package' } / { versions: {...} }
    download (packageName, version, hash, dir)
      -> Promise pjson
    getPackageConfig (packageName, version, hash) (optional)
      -> Promise pjson
    build (optional)
      -> pjson (optional)
  
  PROPERTIES
    remote 
      -> remote URL used for jspm setmode remote and injectino

  User-Configuration
    jspm endpoint create jspm-myspecial-endpoint [name]
    jspm endpoint configure github
    jspm config endpoints.github.remote https://custom-remote
*/
var endpointClasses = {};
exports.loadEndpoint = function(endpoint) {
  if (endpointClasses[endpoint])
    return endpointClasses[endpoint];

  try {
    // ensure the tmpDir exists
    var tmpDir = path.resolve(process.env.HOME, '.jspm', 'tmp-' + endpoint);
    if (!fs.existsSync(tmpDir))
      fs.mkdirSync(tmpDir);

    var options = {
      timeout: 120, 
      tmpDir: tmpDir
    };
    extend(options, config.globalConfig.endpoints[endpoint] || {});

    var endpointClass = require(options.handler);

    return endpointClasses[endpoint] = new endpointClass(options);
  }
  catch(e) {
    ui.log('err', e.stack || e);
    throw 'Unable to load endpoint %' + endpoint + '%';
  }
}

/*
  Parse a package name into endpoint:package@version

  name: 'github:jquery/jquery',
  exactName: 'github:jquery/jquery@2.0.3',
  exactPackage: 'jquery/jquery@2.0.3',

  endpoint: 'github',
  package: 'jquery/jquery',
  version: '2.0.3'
*/
var Package = exports.Package = function Package(name) {
  this.exactName = name;

  if (name.indexOf(':') != -1)
    this.endpoint = name.split(':')[0];

  var packageParts = (this.endpoint ? name.substr(this.endpoint.length + 1) : name).split('/');

  var versionSplit = (packageParts[packageParts.length - 1] || '').split('@');

  var version = versionSplit[1] || '';

  packageParts[packageParts.length - 1] = versionSplit[0];
  this.package = packageParts.join('/');

  this.name = (this.endpoint ? this.endpoint + ':' : '') + this.package;

  this.setVersion(version);
}
Package.prototype.setVersion = function(version) {
  this.version = version;
  var v = this.version ? '@' + this.version : '';
  this.exactPackage = this.package + v;
  this.exactName = this.name + v;
}

// lookup a package in the registry if necessary
exports.registryCache;

exports.locate = function(target) {
  if (target.endpoint)
    return Promise.resolve(target);

  if (_pkg.registryCache) {
    var registryEntry = _pkg.registryCache[target.package];
    if (!registryEntry)
      throw '`' + target.exactName + '` not found in registry.';
    var pkg = new Package(registryEntry);
    pkg.setVersion(target.version);
    return Promise.resolve(pkg);
  }

  // we haven't loaded the registry yet -> load the registry file
  return _pkg.updateRegistry()
  .then(function() {
    return readJSON(path.resolve(registryPath, 'registry.json'));
  })
  .then(function(json) {
    _pkg.registryCache = json;
  })
  .then(function() {
    return _pkg.locate(target);
  });
}

// lookup the latest suitable version for this package range
// if the range is a tag or prerelease, then it is just that
// if the range is compatible with a prerelease, then it is just that
// if the range is compatible with a semver, then it is the 
//   associated stable compatible semver
// if the range is a semver, then it is the latest minor, patch or exact
// also create pkg.hash for the lookup version
var versionCache = {};
{'fraction_non_alphanumeric': 0.1362179487179487, 'fraction_numerical': 0.006710737179487179, 'mean_word_length': 3.4318686196182866, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 21, 'https://': 2, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2703951', 'n_tokens_mistral': 3096, 'n_tokens_neox': 2989, 'n_words': 921}