<commit_before>// ==========================================
// BOWER: Package Object Definition
// ==========================================
// Copyright 2012 Twitter, Inc
// Licensed under The MIT License
// http://opensource.org/licenses/MIT
// ==========================================
// Events:
//  - install: fired when package installed
//  - resolve: fired when deps resolved
//  - error: fired on all errors
//  - data: fired when trying to output data
// ==========================================

var spawn    = require('child_process').spawn;
var _        = require('lodash');
var fstream  = require('fstream');
var mkdirp   = require('mkdirp');
var events   = require('events');
var rimraf   = require('rimraf');
var semver   = require('semver');
var async    = require('async');
var https    = require('https');
var http     = require('http');
var path     = require('path');
var url      = require('url');
var tmp      = require('tmp');
var fs       = require('fs');

var config   = require('./config');
var source   = require('./source');
var template = require('../util/template');
var readJSON = require('../util/read-json');
var UnitWork = require('./unit_work');

var temp = process.env.TMPDIR
 || process.env.TMP
 || process.env.TEMP
 || process.platform === "win32" ? "c:\\windows\\temp" : "/tmp";

var home = (process.platform === "win32"
  ? process.env.USERPROFILE
  : process.env.HOME) || temp;

var cache = process.platform === "win32"
  ? path.resolve(process.env.APPDATA || home || temp, "bower-cache")
  : path.resolve(home || temp, ".bower");

var Package = function (name, endpoint, manager) {
  this.dependencies  = {};
  this.json          = {};
  this.name          = name;
  this.manager       = manager;
  this.unitWork      = manager ? manager.unitWork : new UnitWork;

  if (endpoint) {

    if (/^(.*\.git)$/.exec(endpoint)) {
      this.gitUrl = RegExp.$1.replace(/^git\+/, '');
      this.tag    = false;

    } else if (/^(.*\.git)#(.*)$/.exec(endpoint)) {
      this.tag    = RegExp.$2;
      this.gitUrl = RegExp.$1.replace(/^git\+/, '');

    } else if (/^(?:(git):|git\+(https?):)\/\/([^#]+)#?(.*)$/.exec(endpoint)) {
      this.gitUrl = (RegExp.$1 || RegExp.$2) + "://" + RegExp.$3;
      this.tag    = RegExp.$4;

    } else if (semver.validRange(endpoint)) {
      this.tag = endpoint;

    } else if (/^[\.\/~]\.?[^.]*\.(js|css)/.test(endpoint) && fs.statSync(endpoint).isFile()) {

      this.path      = path.resolve(endpoint);
      this.assetType = path.extname(endpoint);
      this.name      = this.name.replace(this.assetType, '');

    } else if (/^[\.\/~]/.test(endpoint)) {
      this.path = path.resolve(endpoint);

    } else if (/^https?:\/\//.exec(endpoint)) {
      this.assetUrl  = endpoint;
      this.assetType = path.extname(endpoint);
      this.name      = this.name.replace(this.assetType, '');

    } else {
      try {
        fs.statSync(endpoint);
        this.path = path.resolve(endpoint);
      } catch (e) {
        this.tag = endpoint.split('#', 2)[1];
      }
    }

    this.endpoint = endpoint;
    this.originalTag = this.tag;

    // Generate an id and a resourceId
    // The id is an unique id that describes this package
    // The resourceId is an unique id that describes the resource of this package
    this.id = new Buffer(this.name + '%' + this.tag + '%' + this.gitUrl +  '%' + this.path + '%' + this.assetUrl).toString('base64');
    this.resourceId = new Buffer(this.gitUrl + '%' + this.path + '%' + this.assetUrl).toString('base64');
  }

  if (this.manager) {
    this.on('data',  this.manager.emit.bind(this.manager, 'data'));
    this.on('error', this.manager.emit.bind(this.manager, 'error'));
  }

  // Cache a self bound function
  this.waitUnlock = this.waitUnlock.bind(this);

  this.setMaxListeners(30);   // Increase the number of listeners because a package can have more than the default 10 dependencies
};

Package.prototype = Object.create(events.EventEmitter.prototype);

Package.prototype.constructor = Package;

Package.prototype.resolve = function () {
  if (this.unitWork) {
    // Ensure that nobody is resolving the same dep at the same time
    // If there is, we wait for the unlock event
    if (this.unitWork.isLocked(this.name)) return this.unitWork.on('unlock', this.waitUnlock);
    else {
      var data = this.unitWork.retrieve(this.name);
      if (data) {
        // Check if this exact package is the last resolved one
        // If so, we copy the resolved result and we don't need to do anything else
        if (data.id === this.id) {
          this.unserialize(data);
          return this.emit('resolve');
        // Check if this exact package resource is the last resolved one
        // This is to prevent it from being downloaded over and over again in such case
        } else if (data.resourceId === this.resourceId) {
          this.path = data.path;
          this.unitWork.lock(this.name, this);
          return this.once('loadJSON', this.saveUnit).checkout();
        }
      }
    }

    // If not, we lock and resolve it
    this.unitWork.lock(this.name, this);
  }

  if (this.assetUrl) {
    this.download();
  } else if (this.gitUrl) {
    this.clone();
  } else if (this.path) {
    this.copy();
  } else {<commit_msg>Ensure that an unit of work is always present, remove unnecessary if statement.<commit_after>// ==========================================
// BOWER: Package Object Definition
// ==========================================
// Copyright 2012 Twitter, Inc
// Licensed under The MIT License
// http://opensource.org/licenses/MIT
// ==========================================
// Events:
//  - install: fired when package installed
//  - resolve: fired when deps resolved
//  - error: fired on all errors
//  - data: fired when trying to output data
// ==========================================

var spawn    = require('child_process').spawn;
var _        = require('lodash');
var fstream  = require('fstream');
var mkdirp   = require('mkdirp');
var events   = require('events');
var rimraf   = require('rimraf');
var semver   = require('semver');
var async    = require('async');
var https    = require('https');
var http     = require('http');
var path     = require('path');
var url      = require('url');
var tmp      = require('tmp');
var fs       = require('fs');

var config   = require('./config');
var source   = require('./source');
var template = require('../util/template');
var readJSON = require('../util/read-json');
var UnitWork = require('./unit_work');

var temp = process.env.TMPDIR
 || process.env.TMP
 || process.env.TEMP
 || process.platform === "win32" ? "c:\\windows\\temp" : "/tmp";

var home = (process.platform === "win32"
  ? process.env.USERPROFILE
  : process.env.HOME) || temp;

var cache = process.platform === "win32"
  ? path.resolve(process.env.APPDATA || home || temp, "bower-cache")
  : path.resolve(home || temp, ".bower");

var Package = function (name, endpoint, manager) {
  this.dependencies  = {};
  this.json          = {};
  this.name          = name;
  this.manager       = manager;
  this.unitWork      = manager && manager.unitWork ? manager.unitWork : new UnitWork;

  if (endpoint) {

    if (/^(.*\.git)$/.exec(endpoint)) {
      this.gitUrl = RegExp.$1.replace(/^git\+/, '');
      this.tag    = false;

    } else if (/^(.*\.git)#(.*)$/.exec(endpoint)) {
      this.tag    = RegExp.$2;
      this.gitUrl = RegExp.$1.replace(/^git\+/, '');

    } else if (/^(?:(git):|git\+(https?):)\/\/([^#]+)#?(.*)$/.exec(endpoint)) {
      this.gitUrl = (RegExp.$1 || RegExp.$2) + "://" + RegExp.$3;
      this.tag    = RegExp.$4;

    } else if (semver.validRange(endpoint)) {
      this.tag = endpoint;

    } else if (/^[\.\/~]\.?[^.]*\.(js|css)/.test(endpoint) && fs.statSync(endpoint).isFile()) {

      this.path      = path.resolve(endpoint);
      this.assetType = path.extname(endpoint);
      this.name      = this.name.replace(this.assetType, '');

    } else if (/^[\.\/~]/.test(endpoint)) {
      this.path = path.resolve(endpoint);

    } else if (/^https?:\/\//.exec(endpoint)) {
      this.assetUrl  = endpoint;
      this.assetType = path.extname(endpoint);
      this.name      = this.name.replace(this.assetType, '');

    } else {
      try {
        fs.statSync(endpoint);
        this.path = path.resolve(endpoint);
      } catch (e) {
        this.tag = endpoint.split('#', 2)[1];
      }
    }

    this.endpoint = endpoint;
    this.originalTag = this.tag;

    // Generate an id and a resourceId
    // The id is an unique id that describes this package
    // The resourceId is an unique id that describes the resource of this package
    this.id = new Buffer(this.name + '%' + this.tag + '%' + this.gitUrl +  '%' + this.path + '%' + this.assetUrl).toString('base64');
    this.resourceId = new Buffer(this.gitUrl + '%' + this.path + '%' + this.assetUrl).toString('base64');
  }

  if (this.manager) {
    this.on('data',  this.manager.emit.bind(this.manager, 'data'));
    this.on('error', this.manager.emit.bind(this.manager, 'error'));
  }

  // Cache a self bound function
  this.waitUnlock = this.waitUnlock.bind(this);

  this.setMaxListeners(30);   // Increase the number of listeners because a package can have more than the default 10 dependencies
};

Package.prototype = Object.create(events.EventEmitter.prototype);

Package.prototype.constructor = Package;

Package.prototype.resolve = function () {
  // Ensure that nobody is resolving the same dep at the same time
  // If there is, we wait for the unlock event
  if (this.unitWork.isLocked(this.name)) return this.unitWork.on('unlock', this.waitUnlock);
  else {
    var data = this.unitWork.retrieve(this.name);
    if (data) {
      // Check if this exact package is the last resolved one
      // If so, we copy the resolved result and we don't need to do anything else
      if (data.id === this.id) {
        this.unserialize(data);
        return this.emit('resolve');
      // Check if this exact package resource is the last resolved one
      // This is to prevent it from being downloaded over and over again in such case
      } else if (data.resourceId === this.resourceId) {
        this.path = data.path;
        this.unitWork.lock(this.name, this);
        return this.once('loadJSON', this.saveUnit).checkout();
      }
    }
  }

  // If not, we lock and resolve it
  this.unitWork.lock(this.name, this);

  if (this.assetUrl) {
    this.download();
  } else if (this.gitUrl) {
    this.clone();
  } else if (this.path) {
    this.copy();
  } else {
{'fraction_non_alphanumeric': 0.19759629033784423, 'fraction_numerical': 0.005110248888047696, 'mean_word_length': 2.793251974156497, 'pattern_counts': {'":': 2, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6569794', 'n_tokens_mistral': 3305, 'n_tokens_neox': 3207, 'n_words': 825}