<commit_before>var spawn = require('child_process').spawn
  , pipeline = require('stream-combiner')
  , map = require('map-stream')
  , split = require('split')
  , path = require('path')

var format = {
  sha: '%H'
, author: {
    name: '%an'
  , email: '%ae'
  , date: '%ad'
  }
, committer: {
    name: '%cn'
  , email: '%ce'
  , date: '%cd'
  }
, body: '%B'
}

// Dirty hack, but it works a charm.
module.exports = function(dir, options) {
  dir = path.resolve(dir || process.cwd)

  var extras = []
    , options = options || {}
    , fieldDelimiter = '$@$@$@$@$'
    , lineDelimiter = '@$!$@$!$!'

  if (options.since) extras = extras.concat(['--since', options.since / 1000])
  if (options.until) extras = extras.concat(['--until', options.until / 1000])
  if (options.format) format = options.format

  var params = pluck(format)
  // get all format params - even nested ones
  function pluck (obj) {
    var params = []
    Object.keys(obj).forEach(function(key) {
      var args = ('string' === typeof obj[key]) ? [obj[key]] : pluck(obj[key])
      params.push.apply(params, args)
    })
    return params
  }

  var proc = spawn('git', ['log', '--format=' + params.join(fieldDelimiter) + lineDelimiter].concat(extras), { cwd: dir })

  var splitter = split(lineDelimiter)
    , mapper = map(function write(entry, next) {
      entry = entry.split(fieldDelimiter)

      if (!entry[0] || entry[0] === '\n') return next()

      var last = entry.length - 1
      entry[0] = entry[0].replace(/^\n/, '') // Remove leading newline
      entry[last] = entry[last].replace(/\n$/, '') // Remove trailing newline

      var index = 0
      var commit = assign(format)
      // assign entries to their respective properties
      function assign(obj) {
        var commit = {}
        Object.keys(obj).forEach(function(key) {
          commit[key] = ('string' === typeof obj[key]) ? entry[index++] : assign(obj[key])
        })
        return commit
      }

      return next(null, commit)
    })

  return pipeline(proc.stdout, splitter, mapper)
};
<commit_msg>Scoping tweaks<commit_after>var spawn = require('child_process').spawn
  , pipeline = require('stream-combiner')
  , map = require('map-stream')
  , split = require('split')
  , path = require('path')

var defaultFormat = {
  sha: '%H'
, author: {
    name: '%an'
  , email: '%ae'
  , date: '%ad'
  }
, committer: {
    name: '%cn'
  , email: '%ce'
  , date: '%cd'
  }
, body: '%B'
}

// get all format params - even nested ones
function pluck (obj) {
  var params = []
  Object.keys(obj).forEach(function(key) {
    var args = 'string' === typeof obj[key] ? [obj[key]] : pluck(obj[key])
    params.push.apply(params, args)
  })
  return params
};

// Dirty hack, but it works a charm.
module.exports = function(dir, options) {
  dir = path.resolve(dir || process.cwd)

  var extras = []
    , options = options || {}
    , fieldDelimiter = '$@$@$@$@$'
    , lineDelimiter = '@$!$@$!$!'
    , format = options.format || defaultFormat

  if (options.since) extras = extras.concat(['--since', options.since / 1000])
  if (options.until) extras = extras.concat(['--until', options.until / 1000])

  var params = pluck(format)

  var proc = spawn('git', ['log', '--format=' + params.join(fieldDelimiter) + lineDelimiter].concat(extras), { cwd: dir })

  var splitter = split(lineDelimiter)
    , mapper = map(function write(entry, next) {
      entry = entry.split(fieldDelimiter)

      if (!entry[0] || entry[0] === '\n') return next()

      var last = entry.length - 1
      entry[0] = entry[0].replace(/^\n/, '') // Remove leading newline
      entry[last] = entry[last].replace(/\n$/, '') // Remove trailing newline

      var index = 0
      var commit = assign(format)
      // assign entries to their respective properties
      function assign(obj) {
        var commit = {}
        Object.keys(obj).forEach(function(key) {
          commit[key] = ('string' === typeof obj[key]) ? entry[index++] : assign(obj[key])
        })
        return commit
      }

      return next(null, commit)
    })

  return pipeline(proc.stdout, splitter, mapper)
};
<|endoftext|>


<commit_before>var express = require('express');
var app = express();

app.set('port', (process.env.PORT || 5000));

app.use(express.static(__dirname + '/public'));

// views is directory for all template files
app.set('views', __dirname + '/views');
app.set('view engine', 'ejs');

app.get('/', function(request, response) {
  response.render('pages/index');
});

app.get('/webhook/pullrequest/', function(request, response) {
  // TODO: Read CODEREVIEW.md at the root of repo
  // TODO: HTTP-POST a new checklist onto the PR
  // TODO: Use async task to create a new checklist
  response.render('pages/index');
});

// TODO: Read Github access token from environment
// TODO: Configure repo location
// TODO: Setup webhook on Github

app.listen(app.get('port'), function() {
  console.log('Node app is running on port', app.get('port'));
});

<commit_msg>Read settings from environment<commit_after>var express = require('express');
var util = require('util');

var app = express();

app.set('port', (process.env.PORT || 5000));

// Github username and access token used for Basic Auth.
var username = process.env.GITHUB_USERNAME || null;
var token = process.env.ACCESS_TOKEN || null;
var repo = process.env.GITHUB_REPO || null;

if (!username) {
  var msg = 'Please specify Github %s via environment variable: %s';
  msg = util.format(msg, 'username', 'GITHUB_USERNAME');
  console.warn(msg);

  process.exit(1);
}

if (!token) {
  var msg = 'Please specify Github %s via environment variable: %s';
  msg = util.format(msg, 'access token', 'ACCESS_TOKEN');
  console.warn(msg);

  process.exit(1);
}

if (!repo) {
  var msg = 'Please specify Github %s via environment variable: %s';
  msg = util.format(msg, 'repository', 'GITHUB_REPO');
  console.warn(msg);

  process.exit(1);
}

app.use(express.static(__dirname + '/public'));

// views is directory for all template files
app.set('views', __dirname + '/views');
app.set('view engine', 'ejs');

app.get('/', function(request, response) {
  response.render('pages/index');
});

app.get('/webhook/pullrequest/', function(request, response) {
  // TODO: Read CODEREVIEW.md at the root of repo
  // TODO: HTTP-POST a new checklist onto the PR
  // TODO: Use async task to create a new checklist
  response.render('pages/index');
});

// TODO: Setup webhook on Github

app.listen(app.get('port'), function() {
  console.log('Node app is running on port', app.get('port'));
});

<|endoftext|>


<commit_before>'use strict';
var assert = require('assert');

function HtmlWebpackExcludeAssetsPlugin (options) {
  assert.equal(options, undefined, 'The HtmlWebpackExcludeAssetsPlugin does not accept any options');
}

HtmlWebpackExcludeAssetsPlugin.prototype.apply = function (compiler) {
  var self = this;

  // Hook into the html-webpack-plugin processing
  compiler.plugin('compilation', function (compilation) {
    compilation.plugin('html-webpack-plugin-alter-asset-tags', function (htmlPluginData, callback) {
      var excludeAssets = htmlPluginData.plugin.options.excludeAssets;
      // Skip if the plugin configuration didn't set `excludeAssets`
      if (!excludeAssets) {
        if (callback) {
          return callback(null, htmlPluginData);
        } else {
          return Promise.resolve(htmlPluginData)
        }
      }

      if (excludeAssets.constructor !== Array) {
        excludeAssets = [excludeAssets];
      }

      // Skip invalid RegExp patterns
      var excludePatterns = excludeAssets.filter(function (excludePattern) {
        return excludePattern.constructor === RegExp;
      });

      var result = self.processAssets(excludePatterns, htmlPluginData);
      if (callback) {
        callback(null, result);
      } else {
        return Promise.resolve(result)
      }
    });
  });
};

HtmlWebpackExcludeAssetsPlugin.prototype.isExcluded = function (excludePatterns, assetPath) {
  return excludePatterns.filter(function (excludePattern) {
    return excludePattern.test(assetPath);
  }).length > 0;
};

HtmlWebpackExcludeAssetsPlugin.prototype.processAssets = function (excludePatterns, pluginData) {
  var self = this;
  var body = [];
  var head = [];

  pluginData.head.forEach(function (tag) {
    if (!tag.attributes || !self.isExcluded(excludePatterns, tag.attributes.src || tag.attributes.href)) {
      head.push(tag);
    }
  });

  pluginData.body.forEach(function (tag) {
    if (!tag.attributes || !self.isExcluded(excludePatterns, tag.attributes.src || tag.attributes.href)) {
      body.push(tag);
    }
  });

  return { head: head, body: body, plugin: pluginData.plugin, chunks: pluginData.chunks, outputName: pluginData.outputName };
};

module.exports = HtmlWebpackExcludeAssetsPlugin;
<commit_msg>Fix semistandard syntax issue<commit_after>'use strict';
var assert = require('assert');

function HtmlWebpackExcludeAssetsPlugin (options) {
  assert.equal(options, undefined, 'The HtmlWebpackExcludeAssetsPlugin does not accept any options');
}

HtmlWebpackExcludeAssetsPlugin.prototype.apply = function (compiler) {
  var self = this;

  // Hook into the html-webpack-plugin processing
  compiler.plugin('compilation', function (compilation) {
    compilation.plugin('html-webpack-plugin-alter-asset-tags', function (htmlPluginData, callback) {
      var excludeAssets = htmlPluginData.plugin.options.excludeAssets;
      // Skip if the plugin configuration didn't set `excludeAssets`
      if (!excludeAssets) {
        if (callback) {
          return callback(null, htmlPluginData);
        } else {
          return Promise.resolve(htmlPluginData);
        }
      }

      if (excludeAssets.constructor !== Array) {
        excludeAssets = [excludeAssets];
      }

      // Skip invalid RegExp patterns
      var excludePatterns = excludeAssets.filter(function (excludePattern) {
        return excludePattern.constructor === RegExp;
      });

      var result = self.processAssets(excludePatterns, htmlPluginData);
      if (callback) {
        callback(null, result);
      } else {
        return Promise.resolve(result);
      }
    });
  });
};

HtmlWebpackExcludeAssetsPlugin.prototype.isExcluded = function (excludePatterns, assetPath) {
  return excludePatterns.filter(function (excludePattern) {
    return excludePattern.test(assetPath);
  }).length > 0;
};

HtmlWebpackExcludeAssetsPlugin.prototype.processAssets = function (excludePatterns, pluginData) {
  var self = this;
  var body = [];
  var head = [];

  pluginData.head.forEach(function (tag) {
    if (!tag.attributes || !self.isExcluded(excludePatterns, tag.attributes.src || tag.attributes.href)) {
      head.push(tag);
    }
  });

  pluginData.body.forEach(function (tag) {
    if (!tag.attributes || !self.isExcluded(excludePatterns, tag.attributes.src || tag.attributes.href)) {
      body.push(tag);
    }
  });

  return { head: head, body: body, plugin: pluginData.plugin, chunks: pluginData.chunks, outputName: pluginData.outputName };
};

module.exports = HtmlWebpackExcludeAssetsPlugin;
<|endoftext|>


<commit_before>var oneDay = 86400;

module.exports = function (session) {

  var Store = session.Store
    , PGStore;

  PGStore = function (options) {
    var self = this;

    options = options || {};
    Store.call(this, options);

    this.tableName = options.tableName || "session";
    this.conString = options.conString || process.env.DATABASE_URL;
    this.ttl =  options.ttl;
    this.pg = options.pg || require('pg.js');
  };

  /**
   * Inherit from `Store`.
   */

  PGStore.prototype.__proto__ = Store.prototype;

  /**
   * Query the database.
   *
   * @param {String} query
   * @param {Array} params
   * @param {Function} fn
   * @api public
   */

  PGStore.prototype.query = function (query, params, fn) {
    if (!fn && typeof params === 'function') {
      fn = params;
    }
    this.pg.connect(this.conString, function (err, client, done) {
      if (err) {
        done(client);
        fn && fn(err);
      } else {
        client.query(query, params || [], function (err, result) {
          done(err || false);
          fn && fn(err, result && result.rows[0] ? result.rows[0] : false);
        });
      }
    });
  };

  /**
   * Attempt to fetch session by the given `sid`.
   *
   * @param {String} sid
   * @param {Function} fn
   * @api public
   */

  PGStore.prototype.get = function (sid, fn) {
    // Clean up occasionly – but not always...
    if (Math.random() < 0.05) {
      this.query('DELETE FROM "' + this.tableName + '" WHERE expire < NOW()');
    }
    this.query('SELECT sess FROM "' + this.tableName + '" WHERE sid = $1 AND expire >= NOW()', [sid], function (err, data) {
      if (err) return fn(err);
      if (!data) return fn();
      try {
        return fn(null, ("string" == typeof data.sess) ? JSON.parse(data.sess) : data.sess);
      } catch(e) {
        return this.destroy(sid, fn);
      }
    }.bind(this));
  };

  /**
   * Commit the given `sess` object associated with the given `sid`.
   *
   * @param {String} sid
   * @param {Session} sess
   * @param {Function} fn
   * @api public
   */

  PGStore.prototype.set = function (sid, sess, fn) {
    var self = this
      , maxAge = sess.cookie.maxAge
      , ttl = this.ttl;

    ttl = ttl || ('number' == typeof maxAge
        ? maxAge / 1000 | 0
        : oneDay);
    ttl += Date.now() / 1000;

    this.query('UPDATE "' + this.tableName + '" SET sess = $1, expire = to_timestamp($2) WHERE sid = $3 RETURNING sid', [sess, ttl, sid], function (err, data) {
      if (!err && data === false) {
        self.query('INSERT INTO "' + this.tableName + '" (sess, expire, sid) SELECT $1, to_timestamp($2), $3 WHERE NOT EXISTS (SELECT 1 FROM session WHERE sid = $4)', [sess, ttl, sid, sid], function (err) {
          fn && fn.apply(this, err);
        });
      } else {
        fn && fn.apply(this, err);
      }
    });
  };

  /**
   * Destroy the session associated with the given `sid`.
   *
   * @param {String} sid
   * @api public
   */

  PGStore.prototype.destroy = function (sid, fn) {
    this.query('DELETE FROM "' + this.tableName + '" WHERE sid = $1', [sid], function (err) {
      fn && fn(err);
    });
  };

  return PGStore;
};
<commit_msg>Some minor coding style improvements<commit_after>var oneDay = 86400;

module.exports = function (session) {

  var Store = session.Store
    , PGStore;

  PGStore = function (options) {
    var self = this;

    options = options || {};
    Store.call(this, options);

    this.tableName = options.tableName || 'session';
    this.conString = options.conString || process.env.DATABASE_URL;
    this.ttl =  options.ttl;
    this.pg = options.pg || require('pg.js');
  };

  /**
   * Inherit from `Store`.
   */

  PGStore.prototype.__proto__ = Store.prototype;

  /**
   * Query the database.
   *
   * @param {String} query
   * @param {Array} params
   * @param {Function} fn
   * @api public
   */

  PGStore.prototype.query = function (query, params, fn) {
    if (!fn && typeof params === 'function') {
      fn = params;
    }
    this.pg.connect(this.conString, function (err, client, done) {
      if (err) {
        done(client);
        fn && fn(err);
      } else {
        client.query(query, params || [], function (err, result) {
          done(err || false);
          fn && fn(err, result && result.rows[0] ? result.rows[0] : false);
        });
      }
    });
  };

  /**
   * Attempt to fetch session by the given `sid`.
   *
   * @param {String} sid
   * @param {Function} fn
   * @api public
   */

  PGStore.prototype.get = function (sid, fn) {
    // Clean up occasionly – but not always...
    if (Math.random() < 0.05) {
      this.query('DELETE FROM "' + this.tableName + '" WHERE expire < NOW()');
    }
    this.query('SELECT sess FROM "' + this.tableName + '" WHERE sid = $1 AND expire >= NOW()', [sid], function (err, data) {
      if (err) return fn(err);
      if (!data) return fn();
      try {
        return fn(null, ('string' === typeof data.sess) ? JSON.parse(data.sess) : data.sess);
      } catch(e) {
        return this.destroy(sid, fn);
      }
    }.bind(this));
  };

  /**
   * Commit the given `sess` object associated with the given `sid`.
   *
   * @param {String} sid
   * @param {Session} sess
   * @param {Function} fn
   * @api public
   */

  PGStore.prototype.set = function (sid, sess, fn) {
    var self = this
      , maxAge = sess.cookie.maxAge
      , ttl = this.ttl;

    ttl = ttl || ('number' == typeof maxAge
        ? maxAge / 1000 | 0
        : oneDay);
    ttl += Date.now() / 1000;

    this.query('UPDATE "' + this.tableName + '" SET sess = $1, expire = to_timestamp($2) WHERE sid = $3 RETURNING sid', [sess, ttl, sid], function (err, data) {
      if (!err && data === false) {
        self.query('INSERT INTO "' + this.tableName + '" (sess, expire, sid) SELECT $1, to_timestamp($2), $3 WHERE NOT EXISTS (SELECT 1 FROM session WHERE sid = $4)', [sess, ttl, sid, sid], function (err) {
          fn && fn.apply(this, err);
        });
      } else {
        fn && fn.apply(this, err);
      }
    });
  };

  /**
   * Destroy the session associated with the given `sid`.
   *
   * @param {String} sid
   * @api public
   */

  PGStore.prototype.destroy = function (sid, fn) {
    this.query('DELETE FROM "' + this.tableName + '" WHERE sid = $1', [sid], function (err) {
      fn && fn(err);
    });
  };

  return PGStore;
};
<|endoftext|>


<commit_before>/**
 * Module dependencies.
 */
var fs = require("fs")
var path = require("path")

var assign = require("object-assign")
var resolve = require("resolve")
var postcss = require("postcss")
var helpers = require("postcss-message-helpers")
var glob = require("glob")

var resolvedPromise = new Promise(function(resolvePromise) {
  resolvePromise()
})

/**
 * Constants
 */
var moduleDirectories = [
  "web_modules",
  "node_modules",
  "bower_components",
]

var warnNodesMessage =
  "It looks like you didn't end correctly your @import statement. " +
    "Some children nodes are attached to it."

/**
 * Inline `@import`ed files
 *
 * @param {Object} options
 */
function AtImport(options) {
  options = assign({
    root: process.cwd(),
    async: false,
    path: [],
    skipDuplicates: true,
  }, options || {})

  // convert string to an array of a single element
  if (typeof options.path === "string") {
    options.path = [ options.path ]
  }

  return function(styles, result) {
    var opts = assign({}, options || {})

    // auto add from option if possible
    if (
      !opts.from &&
      styles &&
      styles.nodes &&
      styles.nodes[0] &&
      styles.nodes[0].source &&
      styles.nodes[0].source.input &&
      styles.nodes[0].source.input.file
    ) {
      opts.from = styles.nodes[0].source.input.file
    }

    // if from available, prepend from directory in the path array
    addInputToPath(opts)

    // if we got nothing for the path, just use cwd
    if (opts.path.length === 0) {
      opts.path.push(process.cwd())
    }

    var state = {
      importedFiles: {},
      ignoredAtRules: [],
      hashFiles: {},
    }
    if (opts.from) {
      state.importedFiles[opts.from] = {
        "": true,
      }
    }

    var parsedStylesResult = parseStyles(
      result,
      styles,
      opts,
      state,
      null,
      createProcessor(result, options.plugins)
    )

    function onParseEnd() {
      addIgnoredAtRulesOnTop(styles, state.ignoredAtRules)

      if (
        typeof opts.addDependencyTo === "object" &&
        typeof opts.addDependencyTo.addDependency === "function"
      ) {
        Object.keys(state.importedFiles)
        .forEach(opts.addDependencyTo.addDependency)
      }

      if (typeof opts.onImport === "function") {
        opts.onImport(Object.keys(state.importedFiles))
      }
    }

    if (options.async) {
      return parsedStylesResult.then(onParseEnd)
    }
    // else (!options.async)
    onParseEnd()
  }
}

function createProcessor(result, plugins) {
  if (plugins) {
    if (!Array.isArray(plugins)) {
      throw new Error("plugins option must be an array")
    }
    return postcss(plugins)
  }
  return postcss()
}

/**
 * lookup for @import rules
 *
 * @param {Object} styles
 * @param {Object} options
 */
function parseStyles(
  result,
  styles,
  options,
  state,
  media,
  processor
) {
  var imports = []
  styles.walkAtRules("import", function checkAtRule(atRule) {
    if (atRule.nodes) {
      result.warn(warnNodesMessage, { node: atRule })
    }
    if (options.glob && glob.hasMagic(atRule.params)) {
      imports = parseGlob(atRule, options, imports)
    }
    else {
      imports.push(atRule)
    }
  })

  var importResults = imports.map(function(atRule) {
    return helpers.try(function transformAtImport() {
      return readAtImport(
        result,
        atRule,
        options,
        state,
        media,
        processor
      )
    }, atRule.source)
  })

  if (options.async) {
    return Promise.all(importResults)
  }
  // else (!options.async)
  // nothing
}

/**
 * parse glob patterns (for relative paths only)
 *
 * @param {Object} atRule
 * @param {Object} options
 * @param {Array} imports
 */
function parseGlob(atRule, options, imports) {
  var globPattern = atRule.params
    .replace(/['"]/g, "")
    .replace(/(?:url\(|\))/g, "")
  var paths = options.path.concat(moduleDirectories)
  var files = []
  var dir = options.source && options.source.input && options.source.input.file
    ? path.dirname(path.resolve(options.root, options.source.input.file))
    : options.root

  paths.forEach(function(p) {
    p = path.resolve(dir, p)
    var globbed = glob.sync(path.join(p, globPattern))
    globbed.forEach(function(file) {
      file = path.relative(p, file)
      files.push(file)
    })
  })

  files.forEach(function(file) {
    var deglobbedAtRule = atRule.clone({
      params: "\"" + file + "\"",
    })
    if (
      deglobbedAtRule.source &&
      deglobbedAtRule.source.input &&
      deglobbedAtRule.source.input.css
    ) {
      deglobbedAtRule.source.input.css = atRule.source.input.css
        .replace(globPattern, file)
    }
    atRule.parent.insertBefore(atRule, deglobbedAtRule)
    imports.push(deglobbedAtRule)
  })
  atRule.remove()

  return imports
}

/**
 * put back at the top ignored url (absolute url)
 *
 * @param {Object} styles
 * @param {Array} state
 */
function addIgnoredAtRulesOnTop(styles, ignoredAtRules) {
  var i = ignoredAtRules.length
  if (i) {
    var first = styles.first

    while (i--) {
      var ignoredAtRule = ignoredAtRules[i][0]
      ignoredAtRule.params = ignoredAtRules[i][1].fullUri +
        (ignoredAtRules[i][1].media ? " " + ignoredAtRules[i][1].media : "")

      // keep ast ref
      ignoredAtRule.parent = styles

      // don't use prepend() to avoid weird behavior of normalize()
      styles.nodes.unshift(ignoredAtRule)
    }

    // separate remote import a little with others rules if no newlines already
    if (first &&
      first.raws.before.indexOf("\n") === -1) {
      first.raws.before = "\n\n" + first.raws.before
    }
  }
}

/**
 * parse @import rules & inline appropriate rules
 *
 * @param {Object} atRule  postcss atRule
 * @param {Object} options
 */
function readAtImport(
  result,
  atRule,
  options,
  state,
  media,
  processor
) {
  // parse-import module parse entire line
  // @todo extract what can be interesting from this one
  var parsedAtImport = parseImport(atRule.params, atRule.source)

  // adjust media according to current scope
  media = parsedAtImport.media
    ? (media ? media + " and " : "") + parsedAtImport.media
    : (media ? media : null)

  // just update protocol base uri (protocol://url) or protocol-relative
  // (//url) if media needed
  if (parsedAtImport.uri.match(/^(?:[a-z]+:)?\/\//i)) {
    parsedAtImport.media = media

    // save
    state.ignoredAtRules.push([ atRule, parsedAtImport ])

    // detach
    detach(atRule)

    return resolvedPromise
  }

  addInputToPath(options)
  var resolvedFilename = resolveFilename(
    parsedAtImport.uri,
    options.root,
    options.path,
    atRule.source,
    options.resolve
  )

  if (options.skipDuplicates) {
    // skip files already imported at the same scope
    if (
      state.importedFiles[resolvedFilename] &&
      state.importedFiles[resolvedFilename][media]
    ) {
      detach(atRule)
      return resolvedPromise
    }

    // save imported files to skip them next time
    if (!state.importedFiles[resolvedFilename]) {
      state.importedFiles[resolvedFilename] = {}
    }
    state.importedFiles[resolvedFilename][media] = true
  }

  return readImportedContent(
    result,
    atRule,
    parsedAtImport,
    Object.assign({}, options),
    resolvedFilename,
    state,
    media,
    processor
  )
}

/**
 * insert imported content at the right place
 *
 * @param {Object} atRule
 * @param {Object} parsedAtImport
 * @param {Object} options
 * @param {String} resolvedFilename
 */
function readImportedContent(
  result,
  atRule,
  parsedAtImport,
  options,
  resolvedFilename,
  state,
  media,
  processor
) {
  // add directory containing the @imported file in the paths
  // to allow local import from this file
  var dirname = path.dirname(resolvedFilename)
  if (options.path.indexOf(dirname) === -1) {
    options.path = options.path.slice()
    options.path.unshift(dirname)
  }

  options.from = resolvedFilename
  var fileContent = readFile(
    resolvedFilename,
    options.encoding,
    options.transform || function(value) {
      return value
    }
  )

  if (fileContent.trim() === "") {
    result.warn(resolvedFilename + " is empty", { node: atRule })
    detach(atRule)
    return resolvedPromise
  }

  // skip previous imported files not containing @import rules
  if (
    state.hashFiles[fileContent] &&
    state.hashFiles[fileContent][media]
  ) {
    detach(atRule)
    return resolvedPromise
  }

  var newStyles = postcss.parse(fileContent, options)
  if (options.skipDuplicates) {
    var hasImport = newStyles.some(function(child) {
      return child.type === "atrule" && child.name === "import"
    })
    if (!hasImport) {
      // save hash files to skip them next time
      if (!state.hashFiles[fileContent]) {
        state.hashFiles[fileContent] = {}
      }
      state.hashFiles[fileContent][media] = true
    }
  }

  // recursion: import @import from imported file
  var parsedResult = parseStyles(
    result,
    newStyles,
    options,
    state,
    parsedAtImport.media,
    processor
  )

  if (options.async) {
    return parsedResult.then(function() {
      return processor.process(newStyles)
        .then(function(newResult) {
          result.messages = result.messages.concat(newResult.messages)
        })
    })
    .then(function() {
      insertRules(atRule, parsedAtImport, newStyles)
    })
  }
  // else (!options.async)
  var newResult = processor.process(newStyles)
  result.messages = result.messages.concat(newResult.messages)
  insertRules(atRule, parsedAtImport, newStyles)
}

/**
 * insert new imported rules at the right place
 *
 * @param {Object} atRule
 * @param {Object} parsedAtImport
 * @param {Object} newStyles
 */
function insertRules(atRule, parsedAtImport, newStyles) {
  var newNodes = newStyles.nodes

  // wrap rules if the @import have a media query
  if (parsedAtImport.media && parsedAtImport.media.length) {
    // better output
    if (newStyles.nodes && newStyles.nodes.length) {
      newStyles.nodes[0].raws.before = newStyles.nodes[0].raws.before || "\n"
    }

    // wrap new rules with media (media query)
    var wrapper = postcss.atRule({
      name: "media",
      params: parsedAtImport.media,
    })

    // keep AST clean
    newNodes.forEach(function(node) {
      node.parent = wrapper
    })
    wrapper.source = atRule.source

    // copy code style
    wrapper.raws.before = atRule.raws.before
    wrapper.raws.after = atRule.raws.after

    // move nodes
    wrapper.nodes = newNodes
    newNodes = [ wrapper ]
  }
  else if (newNodes && newNodes.length) {
    newNodes[0].raws.before = atRule.raws.before
  }

  // keep AST clean
  newNodes.forEach(function(node) {
    node.parent = atRule.parent
  })

  // replace atRule by imported nodes
  var nodes = atRule.parent.nodes
  nodes.splice.apply(nodes, [ nodes.indexOf(atRule), 0 ].concat(newNodes))
  detach(atRule)
}

/**
 * parse @import parameter
 */
function parseImport(str, source) {
  var regex = /((?:url\s?\()?(?:'|")?([^)'"]+)(?:'|")?\)?)(?:(?:\s)(.*))?/gi
  var matches = regex.exec(str)
  if (matches === null) {
    throw new Error("Unable to find uri in '" + str + "'", source)
  }

  return {
    fullUri: matches[1],
    uri: matches[2],
    media: matches[3] ? matches[3] : null,
  }
}

/**
 * Check if a file exists
 *
 * @param {String} name
 */
function resolveFilename(name, root, paths, source, resolver) {
  var dir = source && source.input && source.input.file
    ? path.dirname(path.resolve(root, source.input.file))
    : root

  try {
    var resolveOpts = {
      basedir: dir,
      moduleDirectory: moduleDirectories.concat(paths),
      paths: paths,
      extensions: [ ".css" ],
      packageFilter: function processPackage(pkg) {
        pkg.main = pkg.style || "index.css"
        return pkg
      },
    }
    var file
    resolver = resolver || resolve.sync
    try {
      file = resolver(name, resolveOpts)
    }
    catch (e) {
      // fix to try relative files on windows with "./"
      // if it's look like it doesn't start with a relative path already
      // if (name.match(/^\.\.?/)) {throw e}
      try {
        file = resolver("./" + name, resolveOpts)
      }
      catch (err) {
        // LAST HOPE
        if (!paths.some(function(dir2) {
          file = path.join(dir2, name)
          return fs.existsSync(file)
        })) {
          throw err
        }
      }
    }

    return path.normalize(file)
  }
  catch (e) {
    throw new Error(
      "Failed to find '" + name + "' from " + root +
      "\n    in [ " +
      "\n        " + paths.join(",\n        ") +
      "\n    ]",
      source
    )
  }
}

/**
 * Read the contents of a file
 *
 * @param {String} file
 */
function readFile(file, encoding, transform) {
  return transform(fs.readFileSync(file, encoding || "utf8"), file)
}

/**
 * add `from` dirname to `path` if not already present
 *
 * @param {Object} options
 */
function addInputToPath(options) {
  if (options.from) {
    var fromDir = path.dirname(options.from)
    if (options.path.indexOf(fromDir) === -1) {
      options.path.unshift(fromDir)
    }
  }
}

function detach(node) {
  node.parent.nodes.splice(node.parent.nodes.indexOf(node), 1)
}

module.exports = postcss.plugin(
  "postcss-import",
  AtImport
)
module.exports.warnNodesMessage = warnNodesMessage
<commit_msg>Fix Object.assign call<commit_after>/**
 * Module dependencies.
 */
var fs = require("fs")
var path = require("path")

var assign = require("object-assign")
var resolve = require("resolve")
var postcss = require("postcss")
var helpers = require("postcss-message-helpers")
var glob = require("glob")

var resolvedPromise = new Promise(function(resolvePromise) {
  resolvePromise()
})

/**
 * Constants
 */
var moduleDirectories = [
  "web_modules",
  "node_modules",
  "bower_components",
]

var warnNodesMessage =
  "It looks like you didn't end correctly your @import statement. " +
    "Some children nodes are attached to it."

/**
 * Inline `@import`ed files
 *
 * @param {Object} options
 */
function AtImport(options) {
  options = assign({
    root: process.cwd(),
    async: false,
    path: [],
    skipDuplicates: true,
  }, options || {})

  // convert string to an array of a single element
  if (typeof options.path === "string") {
    options.path = [ options.path ]
  }

  return function(styles, result) {
    var opts = assign({}, options || {})

    // auto add from option if possible
    if (
      !opts.from &&
      styles &&
      styles.nodes &&
      styles.nodes[0] &&
      styles.nodes[0].source &&
      styles.nodes[0].source.input &&
      styles.nodes[0].source.input.file
    ) {
      opts.from = styles.nodes[0].source.input.file
    }

    // if from available, prepend from directory in the path array
    addInputToPath(opts)

    // if we got nothing for the path, just use cwd
    if (opts.path.length === 0) {
      opts.path.push(process.cwd())
    }

    var state = {
      importedFiles: {},
      ignoredAtRules: [],
      hashFiles: {},
    }
    if (opts.from) {
      state.importedFiles[opts.from] = {
        "": true,
      }
    }

    var parsedStylesResult = parseStyles(
      result,
      styles,
      opts,
      state,
      null,
      createProcessor(result, options.plugins)
    )

    function onParseEnd() {
      addIgnoredAtRulesOnTop(styles, state.ignoredAtRules)

      if (
        typeof opts.addDependencyTo === "object" &&
        typeof opts.addDependencyTo.addDependency === "function"
      ) {
        Object.keys(state.importedFiles)
        .forEach(opts.addDependencyTo.addDependency)
      }

      if (typeof opts.onImport === "function") {
        opts.onImport(Object.keys(state.importedFiles))
      }
    }

    if (options.async) {
      return parsedStylesResult.then(onParseEnd)
    }
    // else (!options.async)
    onParseEnd()
  }
}

function createProcessor(result, plugins) {
  if (plugins) {
    if (!Array.isArray(plugins)) {
      throw new Error("plugins option must be an array")
    }
    return postcss(plugins)
  }
  return postcss()
}

/**
 * lookup for @import rules
 *
 * @param {Object} styles
 * @param {Object} options
 */
function parseStyles(
  result,
  styles,
  options,
  state,
  media,
  processor
) {
  var imports = []
  styles.walkAtRules("import", function checkAtRule(atRule) {
    if (atRule.nodes) {
      result.warn(warnNodesMessage, { node: atRule })
    }
    if (options.glob && glob.hasMagic(atRule.params)) {
      imports = parseGlob(atRule, options, imports)
    }
    else {
      imports.push(atRule)
    }
  })

  var importResults = imports.map(function(atRule) {
    return helpers.try(function transformAtImport() {
      return readAtImport(
        result,
        atRule,
        options,
        state,
        media,
        processor
      )
    }, atRule.source)
  })

  if (options.async) {
    return Promise.all(importResults)
  }
  // else (!options.async)
  // nothing
}

/**
 * parse glob patterns (for relative paths only)
 *
 * @param {Object} atRule
 * @param {Object} options
 * @param {Array} imports
 */
function parseGlob(atRule, options, imports) {
  var globPattern = atRule.params
    .replace(/['"]/g, "")
    .replace(/(?:url\(|\))/g, "")
  var paths = options.path.concat(moduleDirectories)
  var files = []
  var dir = options.source && options.source.input && options.source.input.file
    ? path.dirname(path.resolve(options.root, options.source.input.file))
    : options.root

  paths.forEach(function(p) {
    p = path.resolve(dir, p)
    var globbed = glob.sync(path.join(p, globPattern))
    globbed.forEach(function(file) {
      file = path.relative(p, file)
      files.push(file)
    })
  })

  files.forEach(function(file) {
    var deglobbedAtRule = atRule.clone({
      params: "\"" + file + "\"",
    })
    if (
      deglobbedAtRule.source &&
      deglobbedAtRule.source.input &&
      deglobbedAtRule.source.input.css
    ) {
      deglobbedAtRule.source.input.css = atRule.source.input.css
        .replace(globPattern, file)
    }
    atRule.parent.insertBefore(atRule, deglobbedAtRule)
    imports.push(deglobbedAtRule)
  })
  atRule.remove()

  return imports
}

/**
 * put back at the top ignored url (absolute url)
 *
 * @param {Object} styles
 * @param {Array} state
 */
function addIgnoredAtRulesOnTop(styles, ignoredAtRules) {
  var i = ignoredAtRules.length
  if (i) {
    var first = styles.first

    while (i--) {
      var ignoredAtRule = ignoredAtRules[i][0]
      ignoredAtRule.params = ignoredAtRules[i][1].fullUri +
        (ignoredAtRules[i][1].media ? " " + ignoredAtRules[i][1].media : "")

      // keep ast ref
      ignoredAtRule.parent = styles

      // don't use prepend() to avoid weird behavior of normalize()
      styles.nodes.unshift(ignoredAtRule)
    }

    // separate remote import a little with others rules if no newlines already
    if (first &&
      first.raws.before.indexOf("\n") === -1) {
      first.raws.before = "\n\n" + first.raws.before
    }
  }
}

/**
 * parse @import rules & inline appropriate rules
 *
 * @param {Object} atRule  postcss atRule
 * @param {Object} options
 */
function readAtImport(
  result,
  atRule,
  options,
  state,
  media,
  processor
) {
  // parse-import module parse entire line
  // @todo extract what can be interesting from this one
  var parsedAtImport = parseImport(atRule.params, atRule.source)

  // adjust media according to current scope
  media = parsedAtImport.media
    ? (media ? media + " and " : "") + parsedAtImport.media
    : (media ? media : null)

  // just update protocol base uri (protocol://url) or protocol-relative
  // (//url) if media needed
  if (parsedAtImport.uri.match(/^(?:[a-z]+:)?\/\//i)) {
    parsedAtImport.media = media

    // save
    state.ignoredAtRules.push([ atRule, parsedAtImport ])

    // detach
    detach(atRule)

    return resolvedPromise
  }

  addInputToPath(options)
  var resolvedFilename = resolveFilename(
    parsedAtImport.uri,
    options.root,
    options.path,
    atRule.source,
    options.resolve
  )

  if (options.skipDuplicates) {
    // skip files already imported at the same scope
    if (
      state.importedFiles[resolvedFilename] &&
      state.importedFiles[resolvedFilename][media]
    ) {
      detach(atRule)
      return resolvedPromise
    }

    // save imported files to skip them next time
    if (!state.importedFiles[resolvedFilename]) {
      state.importedFiles[resolvedFilename] = {}
    }
    state.importedFiles[resolvedFilename][media] = true
  }

  return readImportedContent(
    result,
    atRule,
    parsedAtImport,
    assign({}, options),
    resolvedFilename,
    state,
    media,
    processor
  )
}

/**
 * insert imported content at the right place
 *
 * @param {Object} atRule
 * @param {Object} parsedAtImport
 * @param {Object} options
 * @param {String} resolvedFilename
 */
function readImportedContent(
  result,
  atRule,
  parsedAtImport,
  options,
  resolvedFilename,
  state,
  media,
  processor
) {
  // add directory containing the @imported file in the paths
  // to allow local import from this file
  var dirname = path.dirname(resolvedFilename)
  if (options.path.indexOf(dirname) === -1) {
    options.path = options.path.slice()
    options.path.unshift(dirname)
  }

  options.from = resolvedFilename
  var fileContent = readFile(
    resolvedFilename,
    options.encoding,
    options.transform || function(value) {
      return value
    }
  )

  if (fileContent.trim() === "") {
    result.warn(resolvedFilename + " is empty", { node: atRule })
    detach(atRule)
    return resolvedPromise
  }

  // skip previous imported files not containing @import rules
  if (
    state.hashFiles[fileContent] &&
    state.hashFiles[fileContent][media]
  ) {
    detach(atRule)
    return resolvedPromise
  }

  var newStyles = postcss.parse(fileContent, options)
  if (options.skipDuplicates) {
    var hasImport = newStyles.some(function(child) {
      return child.type === "atrule" && child.name === "import"
    })
    if (!hasImport) {
      // save hash files to skip them next time
      if (!state.hashFiles[fileContent]) {
        state.hashFiles[fileContent] = {}
      }
      state.hashFiles[fileContent][media] = true
    }
  }

  // recursion: import @import from imported file
  var parsedResult = parseStyles(
    result,
    newStyles,
    options,
    state,
    parsedAtImport.media,
    processor
  )

  if (options.async) {
    return parsedResult.then(function() {
      return processor.process(newStyles)
        .then(function(newResult) {
          result.messages = result.messages.concat(newResult.messages)
        })
    })
    .then(function() {
      insertRules(atRule, parsedAtImport, newStyles)
    })
  }
  // else (!options.async)
  var newResult = processor.process(newStyles)
  result.messages = result.messages.concat(newResult.messages)
  insertRules(atRule, parsedAtImport, newStyles)
}

/**
 * insert new imported rules at the right place
 *
 * @param {Object} atRule
 * @param {Object} parsedAtImport
 * @param {Object} newStyles
 */
function insertRules(atRule, parsedAtImport, newStyles) {
  var newNodes = newStyles.nodes

  // wrap rules if the @import have a media query
  if (parsedAtImport.media && parsedAtImport.media.length) {
    // better output
    if (newStyles.nodes && newStyles.nodes.length) {
      newStyles.nodes[0].raws.before = newStyles.nodes[0].raws.before || "\n"
    }

    // wrap new rules with media (media query)
    var wrapper = postcss.atRule({
      name: "media",
      params: parsedAtImport.media,
    })

    // keep AST clean
    newNodes.forEach(function(node) {
      node.parent = wrapper
    })
    wrapper.source = atRule.source

    // copy code style
    wrapper.raws.before = atRule.raws.before
    wrapper.raws.after = atRule.raws.after

    // move nodes
    wrapper.nodes = newNodes
    newNodes = [ wrapper ]
  }
  else if (newNodes && newNodes.length) {
    newNodes[0].raws.before = atRule.raws.before
  }

  // keep AST clean
  newNodes.forEach(function(node) {
    node.parent = atRule.parent
  })

  // replace atRule by imported nodes
  var nodes = atRule.parent.nodes
  nodes.splice.apply(nodes, [ nodes.indexOf(atRule), 0 ].concat(newNodes))
  detach(atRule)
}

/**
 * parse @import parameter
 */
function parseImport(str, source) {
  var regex = /((?:url\s?\()?(?:'|")?([^)'"]+)(?:'|")?\)?)(?:(?:\s)(.*))?/gi
  var matches = regex.exec(str)
  if (matches === null) {
    throw new Error("Unable to find uri in '" + str + "'", source)
  }

  return {
    fullUri: matches[1],
    uri: matches[2],
    media: matches[3] ? matches[3] : null,
  }
}

/**
 * Check if a file exists
 *
 * @param {String} name
 */
function resolveFilename(name, root, paths, source, resolver) {
  var dir = source && source.input && source.input.file
    ? path.dirname(path.resolve(root, source.input.file))
    : root

  try {
    var resolveOpts = {
      basedir: dir,
      moduleDirectory: moduleDirectories.concat(paths),
      paths: paths,
      extensions: [ ".css" ],
      packageFilter: function processPackage(pkg) {
        pkg.main = pkg.style || "index.css"
        return pkg
      },
    }
    var file
    resolver = resolver || resolve.sync
    try {
      file = resolver(name, resolveOpts)
    }
    catch (e) {
      // fix to try relative files on windows with "./"
      // if it's look like it doesn't start with a relative path already
      // if (name.match(/^\.\.?/)) {throw e}
      try {
        file = resolver("./" + name, resolveOpts)
      }
      catch (err) {
        // LAST HOPE
        if (!paths.some(function(dir2) {
          file = path.join(dir2, name)
          return fs.existsSync(file)
        })) {
          throw err
        }
      }
    }

    return path.normalize(file)
  }
  catch (e) {
    throw new Error(
      "Failed to find '" + name + "' from " + root +
      "\n    in [ " +
      "\n        " + paths.join(",\n        ") +
      "\n    ]",
      source
    )
  }
}

/**
 * Read the contents of a file
 *
 * @param {String} file
 */
function readFile(file, encoding, transform) {
  return transform(fs.readFileSync(file, encoding || "utf8"), file)
}

/**
 * add `from` dirname to `path` if not already present
 *
 * @param {Object} options
 */
function addInputToPath(options) {
  if (options.from) {
    var fromDir = path.dirname(options.from)
    if (options.path.indexOf(fromDir) === -1) {
      options.path.unshift(fromDir)
    }
  }
}

function detach(node) {
  node.parent.nodes.splice(node.parent.nodes.indexOf(node), 1)
}

module.exports = postcss.plugin(
  "postcss-import",
  AtImport
)
module.exports.warnNodesMessage = warnNodesMessage
<|endoftext|>


<commit_before>var es = require('event-stream');
var fs = require('fs');
var path = require('path');
var child_process = require('child_process');
var async = require('async');
var PluginError = require('gulp-util').PluginError;
var winExt = /^win/.test(process.platform)?".cmd":"";

// optimization: cache for protractor binaries directory
var protractorDir = null;

function getProtractorDir() {
	if (protractorDir) {
		return protractorDir;
	}

	// how deep are we wrt filesystem root?
	var cwd = path.resolve(".");
	var depth = /^win/.test(process.platform) ? cwd.match(/\\/g).length :  cwd.match(/\//g).length;
	depth = depth - 1;

	var result = "./node_modules";
	var count = 0;
	while (count <= depth)
	{
		if (fs.existsSync(path.resolve(result + "/.bin/protractor")))
		{
			protractorDir = result + "/.bin";
			return protractorDir;
		}
		result = "../" + result;
		count++;
	}
	throw new Error("No protractor installation found.");
}

var protractor = function(options) {
	var files = [],
		child, args;

	options = options || {};
	args = options.args || [];

	if (!options.configFile) {
		this.emit('error', new PluginError('gulp-protractor', 'Please specify the protractor config file'));
	}
	return es.through(function(file) {
		files.push(file.path);
	}, function() {
		var stream = this;

		// Attach Files, if any
		if (files.length) {
			args.push('--specs');
			args.push(files.join(','));
		}

		// Pass in the config file
		args.unshift(options.configFile);

		child = child_process.spawn(path.resolve(getProtractorDir() + '/protractor'+winExt), args, {
			stdio: 'inherit'
		}).on('exit', function(code) {
			if (child) {
				child.kill();
			}
			if (stream) {
				if (code) {
					stream.emit('error', new PluginError('gulp-protractor', 'protractor exited with code ' + code));
				}
				else {
					stream.emit('end');
				}
			}
		});
	});
};

var webdriver_update = function(cb) {
	child_process.spawn(path.resolve(getProtractorDir() + '/webdriver-manager'+winExt), ['update'], {
		stdio: 'inherit'
	}).once('close', cb);
};

var webdriver_standalone = function(cb) {
	var child = child_process.spawn(path.resolve(getProtractorDir() + '/webdriver-manager'+winExt), ['start'], {
		stdio: 'inherit'
	}).once('close', cb);
};

module.exports = {
	protractor: protractor,
	webdriver_standalone: webdriver_standalone,
	webdriver_update: webdriver_update
};
<commit_msg>Add function to also update internet explorer driver.<commit_after>var es = require('event-stream');
var fs = require('fs');
var path = require('path');
var child_process = require('child_process');
var async = require('async');
var PluginError = require('gulp-util').PluginError;
var winExt = /^win/.test(process.platform)?".cmd":"";

// optimization: cache for protractor binaries directory
var protractorDir = null;

function getProtractorDir() {
	if (protractorDir) {
		return protractorDir;
	}

	// how deep are we wrt filesystem root?
	var cwd = path.resolve(".");
	var depth = /^win/.test(process.platform) ? cwd.match(/\\/g).length :  cwd.match(/\//g).length;
	depth = depth - 1;

	var result = "./node_modules";
	var count = 0;
	while (count <= depth)
	{
		if (fs.existsSync(path.resolve(result + "/.bin/protractor")))
		{
			protractorDir = result + "/.bin";
			return protractorDir;
		}
		result = "../" + result;
		count++;
	}
	throw new Error("No protractor installation found.");
}

var protractor = function(options) {
	var files = [],
		child, args;

	options = options || {};
	args = options.args || [];

	if (!options.configFile) {
		this.emit('error', new PluginError('gulp-protractor', 'Please specify the protractor config file'));
	}
	return es.through(function(file) {
		files.push(file.path);
	}, function() {
		var stream = this;

		// Attach Files, if any
		if (files.length) {
			args.push('--specs');
			args.push(files.join(','));
		}

		// Pass in the config file
		args.unshift(options.configFile);

		child = child_process.spawn(path.resolve(getProtractorDir() + '/protractor'+winExt), args, {
			stdio: 'inherit'
		}).on('exit', function(code) {
			if (child) {
				child.kill();
			}
			if (stream) {
				if (code) {
					stream.emit('error', new PluginError('gulp-protractor', 'protractor exited with code ' + code));
				}
				else {
					stream.emit('end');
				}
			}
		});
	});
};

var webdriver_update = function(opts, cb) {
	var callback = (cb ? cb : opts);
	var options = (cb ? opts : null);
	var args = ["update", "--standalone"];
	if (options) {
		if (options.browsers) {
			options.browsers.forEach(function(element, index, array) {
				args.push("--" + element);
			});
		}
	}
	child_process.spawn(path.resolve(getProtractorDir() + '/webdriver-manager'+winExt), args, {
		stdio: 'inherit'
	}).once('close', cb);
};

var webdriver_update_specific = function(opts) {
	return webdriver_update.bind(this, opts);
};

webdriver_update.bind(null, ["ie", "chrome"])

var webdriver_standalone = function(cb) {
	var child = child_process.spawn(path.resolve(getProtractorDir() + '/webdriver-manager'+winExt), ['start'], {
		stdio: 'inherit'
	}).once('close', cb);
};

module.exports = {
	protractor: protractor,
	webdriver_standalone: webdriver_standalone,
	webdriver_update: webdriver_update,
	webdriver_update_specific: webdriver_update_specific
};
<|endoftext|>


<commit_before>var extend   = require('extend')
var fs       = require('graceful-fs') || require('fs')
var path     = require('path')
var Readable = require('readable-stream').Readable
var util     = require('util')
var through  = require('through2')
var Vinyl    = require('vinyl')

/* A Stream can be turned into an EventEmitter, but not vice versa, because
 * EventEmitters have no sense of "backpressure", i.e. blocking when their
 * outgoing queue is full. I did not see any Stream-based directory walkers
 * that respond to pruning branches of the directory tree, so I am
 * implementing my own recursive walk.
 *
 * node-walk
 * : EventEmitter, not Stream
 * : cannot prune branches
 * node-findit
 * : EventEmitter, not Stream
 * node-glob
 * : EventEmitter, not Stream
 * : cannot prune branches
 * node-stream
 * : does not respond to backpressure
 * : cannot prune branches
 */

var defaultOpts = {
  fs:          fs,
  start:       ['.'],
  maxDepth:    Number.MAX_VALUE,
  insensitive: false,
  prune:       {},
}

/**
 * @return barrier A function that calls `fn` in context `ctx` on its `n`th
 * invocation.
 */
function barrier(n, fn, ctx) {
  var i = 0
  return function() {
    if (++i === n) {
      fn.apply(ctx, arguments)
    }
  }
}

/**
 * @param glob String Shell glob expression.
 * @param matchSep boolean True if wildcards should match the path component
 * separator (e.g. '/' on Unix).
 * @return regex
 */
function glob2regex(glob, matchSep) {
  var any = matchSep ? '.' : '[^/]'
  return glob
  .replace(/(\\)?\*/, function($0, $1) {
    return $1 ? $0 : (any + '*')
  })
  .replace(/(\\)?\?/, function($0, $1) {
    return $1 ? $0 : any
  })
}

function pathGlob2regex(glob) {
  return glob2regex(glob, true)
}

var alwaysMatch = function() { return true }
var neverMatch = function() { return false }

function compilePathMatch(opts) {
  var pats = []
  if (opts.name) {
    pats.push('^.*/(?:' + compilePathMatch1(opts.name, glob2regex) + ')$')
  }
  if (opts.path) {
    pats.push('^(?:' + compilePathMatch1(opts.path, pathGlob2regex) + ')$')
  }
  if (opts.regex) {
    pats.push(compilePathMatch1(opts.regex))
  if (!pats.length) {
    return
  }
  pats = new RegExp(pats.join('|'), opts.insensitive ? 'i' : '')
  return function(p) { return pats.test(p) }
}

function compilePathMatch1(pats, template) {
  if (!util.isArray(pats)) {
    pats = [pats]
  }
  if (template) {
    pats = pats.map(template)
  }
  return pats
  .map(function(pat) { return '(?:' + pat + ')' })
  .join('|')
}

var TEST_METHOD_NAME_FOR_TYPE = {
  b: 'isBlockDevice',
  c: 'isCharacterDevice',
  d: 'isDirectory',
  f: 'isFile',
  l: 'isSymbolicLink',
  p: 'isFIFO',
  s: 'isSocket',
}

function compileTypeMatch(opts) {
  if (!opts.type) {
    return alwaysMatch
  }
  var method = TEST_METHOD_NAME_FOR_TYPE[opts.type]
  return function(stats) {
    return stats[method]()
  }
}

function FindStream(opts) {
  Readable.call(this, {objectMode: true})
  this.opts      = extend({}, defaultOpts, opts)
  this.paused    = false
  this.buffer    = []
  this.pathMatch = compilePathMatch(this.opts) || alwaysMatch
  this.typeMatch = compileTypeMatch(this.opts)
  this.pruneMatch = compilePathMatch(this.opts.prune) || neverMatch

  var start = this.opts.start.map(function(name) {
    return path.resolve(process.cwd(), name)
  })
  var self = this
  var done = function() {
    self.push(null)
  }
  this.pushLevel(/*level=*/0, /*prefix=*/'', /*entries=*/start, done)
}

util.inherits(FindStream, Readable)

/**
 * lstat every path in `names` (prefixed by `prefix`), and pass to
 * `tryPushEntry`. Call `done` after traversing every path.
 */
FindStream.prototype.pushLevel = function pushLevel(level, prefix, names, done) {
  if (level > this.opts.maxDepth || !names.length) {
    done()
    return
  }

  var self = this
  var bar = barrier(names.length, done)
  names.forEach(function(name) {
    var fullPath = path.join(prefix, name)
    if (self.pruneMatch(fullPath)) {
      bar()
      return
    }
    self.opts.fs.lstat(fullPath, function(err, stats) {
      if (err) {
        self.emit('error', err)
      }
      self.tryPushEntry({
        value: {path: fullPath, stats: stats},
        done: bar,
        level: level,
      })
    })
  })
}

/**
 * Buffer `entry` if the stream is paused, otherwise pass to `pushEntry`.
 * Call `done` after pushing.
 */
FindStream.prototype.tryPushEntry = function tryPushEntry(entry) {
  if (this.paused) {
    this.buffer.push(entry)
  } else {
    this.pushEntry(entry)
  }
}

/**
 * Push entry downstream, and if it is a directory, call `pushLevel` on its
 * contents. Call `done` after traversing subtree.
 * @return mayContinue True if the downstream will accept more entries without
 * pausing.
 */
FindStream.prototype.pushEntry = function pushEntry(entry) {
  var self = this
  var value = entry.value
  if (this.pathMatch(value.path) && this.typeMatch(value.stats)) {
    this.paused = !this.push(value) || this.paused
  }
  if (value.stats.isDirectory()) {
    this.opts.fs.readdir(value.path, function(err, entries) {
      if (err) {
        self.emit('error', err)
      }
      self.pushLevel(entry.level + 1, value.path, entries, entry.done)
    })
  } else {
    entry.done()
  }
  return !this.paused
}

FindStream.prototype._read = function _read(size) {
  this.paused = false
  while (size-- && this.buffer.length) {
    if (!this.pushEntry(buffer.shift())) {
      return
    }
  }
}

function find(opts) {
  return new FindStream(opts)
  .pipe(through.obj(function(entry, enc, cb) {
    cb(null, new Vinyl({path: entry.path}))
  }))
}

module.exports = find

<commit_msg>document all options in defaultOpts<commit_after>var extend   = require('extend')
var fs       = require('graceful-fs') || require('fs')
var path     = require('path')
var Readable = require('readable-stream').Readable
var util     = require('util')
var through  = require('through2')
var Vinyl    = require('vinyl')

/* A Stream can be turned into an EventEmitter, but not vice versa, because
 * EventEmitters have no sense of "backpressure", i.e. blocking when their
 * outgoing queue is full. I did not see any Stream-based directory walkers
 * that respond to pruning branches of the directory tree, so I am
 * implementing my own recursive walk.
 *
 * node-walk
 * : EventEmitter, not Stream
 * : cannot prune branches
 * node-findit
 * : EventEmitter, not Stream
 * node-glob
 * : EventEmitter, not Stream
 * : cannot prune branches
 * node-stream
 * : does not respond to backpressure
 * : cannot prune branches
 */

var defaultOpts = {
  fs:          fs,
  start:       ['.'],
  maxDepth:    Number.MAX_VALUE,
  insensitive: false,
  name:        undefined,
  path:        undefined,
  regex:       undefined,
  prune:       {},
}

/**
 * @return barrier A function that calls `fn` in context `ctx` on its `n`th
 * invocation.
 */
function barrier(n, fn, ctx) {
  var i = 0
  return function() {
    if (++i === n) {
      fn.apply(ctx, arguments)
    }
  }
}

/**
 * @param glob String Shell glob expression.
 * @param matchSep boolean True if wildcards should match the path component
 * separator (e.g. '/' on Unix).
 * @return regex
 */
function glob2regex(glob, matchSep) {
  var any = matchSep ? '.' : '[^/]'
  return glob
  .replace(/(\\)?\*/, function($0, $1) {
    return $1 ? $0 : (any + '*')
  })
  .replace(/(\\)?\?/, function($0, $1) {
    return $1 ? $0 : any
  })
}

function pathGlob2regex(glob) {
  return glob2regex(glob, true)
}

var alwaysMatch = function() { return true }
var neverMatch = function() { return false }

function compilePathMatch(opts) {
  var pats = []
  if (opts.name) {
    pats.push('^.*/(?:' + compilePathMatch1(opts.name, glob2regex) + ')$')
  }
  if (opts.path) {
    pats.push('^(?:' + compilePathMatch1(opts.path, pathGlob2regex) + ')$')
  }
  if (opts.regex) {
    pats.push(compilePathMatch1(opts.regex))
  if (!pats.length) {
    return
  }
  pats = new RegExp(pats.join('|'), opts.insensitive ? 'i' : '')
  return function(p) { return pats.test(p) }
}

function compilePathMatch1(pats, template) {
  if (!util.isArray(pats)) {
    pats = [pats]
  }
  if (template) {
    pats = pats.map(template)
  }
  return pats
  .map(function(pat) { return '(?:' + pat + ')' })
  .join('|')
}

var TEST_METHOD_NAME_FOR_TYPE = {
  b: 'isBlockDevice',
  c: 'isCharacterDevice',
  d: 'isDirectory',
  f: 'isFile',
  l: 'isSymbolicLink',
  p: 'isFIFO',
  s: 'isSocket',
}

function compileTypeMatch(opts) {
  if (!opts.type) {
    return alwaysMatch
  }
  var method = TEST_METHOD_NAME_FOR_TYPE[opts.type]
  return function(stats) {
    return stats[method]()
  }
}

function FindStream(opts) {
  Readable.call(this, {objectMode: true})
  this.opts      = extend({}, defaultOpts, opts)
  this.paused    = false
  this.buffer    = []
  this.pathMatch = compilePathMatch(this.opts) || alwaysMatch
  this.typeMatch = compileTypeMatch(this.opts)
  this.pruneMatch = compilePathMatch(this.opts.prune) || neverMatch

  var start = this.opts.start.map(function(name) {
    return path.resolve(process.cwd(), name)
  })
  var self = this
  var done = function() {
    self.push(null)
  }
  this.pushLevel(/*level=*/0, /*prefix=*/'', /*entries=*/start, done)
}

util.inherits(FindStream, Readable)

/**
 * lstat every path in `names` (prefixed by `prefix`), and pass to
 * `tryPushEntry`. Call `done` after traversing every path.
 */
FindStream.prototype.pushLevel = function pushLevel(level, prefix, names, done) {
  if (level > this.opts.maxDepth || !names.length) {
    done()
    return
  }

  var self = this
  var bar = barrier(names.length, done)
  names.forEach(function(name) {
    var fullPath = path.join(prefix, name)
    if (self.pruneMatch(fullPath)) {
      bar()
      return
    }
    self.opts.fs.lstat(fullPath, function(err, stats) {
      if (err) {
        self.emit('error', err)
      }
      self.tryPushEntry({
        value: {path: fullPath, stats: stats},
        done: bar,
        level: level,
      })
    })
  })
}

/**
 * Buffer `entry` if the stream is paused, otherwise pass to `pushEntry`.
 * Call `done` after pushing.
 */
FindStream.prototype.tryPushEntry = function tryPushEntry(entry) {
  if (this.paused) {
    this.buffer.push(entry)
  } else {
    this.pushEntry(entry)
  }
}

/**
 * Push entry downstream, and if it is a directory, call `pushLevel` on its
 * contents. Call `done` after traversing subtree.
 * @return mayContinue True if the downstream will accept more entries without
 * pausing.
 */
FindStream.prototype.pushEntry = function pushEntry(entry) {
  var self = this
  var value = entry.value
  if (this.pathMatch(value.path) && this.typeMatch(value.stats)) {
    this.paused = !this.push(value) || this.paused
  }
  if (value.stats.isDirectory()) {
    this.opts.fs.readdir(value.path, function(err, entries) {
      if (err) {
        self.emit('error', err)
      }
      self.pushLevel(entry.level + 1, value.path, entries, entry.done)
    })
  } else {
    entry.done()
  }
  return !this.paused
}

FindStream.prototype._read = function _read(size) {
  this.paused = false
  while (size-- && this.buffer.length) {
    if (!this.pushEntry(buffer.shift())) {
      return
    }
  }
}

function find(opts) {
  return new FindStream(opts)
  .pipe(through.obj(function(entry, enc, cb) {
    cb(null, new Vinyl({path: entry.path}))
  }))
}

module.exports = find

<|endoftext|>


<commit_before>var spawn = require('child_process').spawn
  , concat = require('concat-stream')
  , nest = require('./nest')
  , walk = require('findit')
  , path = require('path')
  , fs = require('fs')

module.exports = blobify

var blob = {}

function blobify(entry_points, options, ready) {
  if(typeof options === 'function') {
    ready = options
    options = {}
  }

  entry_points.on('end', function() {
    var keys = Object.keys(blob)

    ready(null, options.flat ? blob : nest(blob) )

    return
  })

  entry_points.on('data', function(data) {
    if(!data) {
      return
    }

    data = data.toString()

    blob_one(data, options, done_one)
  })

  function done_one(err, data) {
    if(err) {
      return ready(err)
    }
  }
}

function blob_one(entry_point, options, ready) {
  var ended = false
    , pending = 0

  var absolute_path = path.resolve(entry_point)

  walker = walk(absolute_path, {followSymLinks: options.links})

  walker
    .on('file', onfile_found)
    .on('end', onend)
    .on('error', ready)

  if(options.links) {
    walker.on('link', onlink)
  }

  function onfile_found(to, stat) {
    pending++

    if(options.ignore && options.ignore.test(to)) {
      return
    }

    var aggregator_stream = concat(function(data) {
      blob[to] = data.toString()

      pending--

      return maybe_done()
    })

    var readstream = fs.createReadStream(to)

    if(!options['file-transform']) {
      return readstream.pipe(aggregator_stream)
    }

    var command = options['file-transform'].split(' ')[0]
      , args = options['file-transform'].split(' ').slice(1)

    var child = spawn(command, args)

    child.stdout
      .on('error', ready)
      .pipe(aggregator_stream)

    readstream.pipe(child.stdin)
  }

  function onend() {
    ended = true

    maybe_done()
  }

  function maybe_done() {
    if(!pending && ended) {
      ready(null, blob[''] || blob)
    }
  }
}
<commit_msg>fixed single arg issue<commit_after>var spawn = require('child_process').spawn
  , concat = require('concat-stream')
  , nest = require('./nest')
  , walk = require('findit')
  , path = require('path')
  , fs = require('fs')

module.exports = blobify

var blob = {}

function blobify(entry_points, options, ready) {
  if(typeof options === 'function') {
    ready = options
    options = {}
  }

  var ended
  var inflight = 0

  entry_points.on('end', function() {
    ended = true

    maybe_done()
  })

  entry_points.on('data', function(data) {
    if(!data) {
      return
    }

    data = data.toString()

    inflight++
    blob_one(data, options, done_one)
  })

  function done_one(err, data) {
    if(err) {
      return ready(err)
    }

    inflight--
    maybe_done()
  }

  function maybe_done() {
    var result

    if(Object.keys(blob).length) {
      result = options.flat ? blob : nest(blob)
    } else {
      result = {}
    }

    if(!inflight && ended) {
      ready(null, result)
    }
  }
}

function blob_one(entry_point, options, ready) {
  var ended = false
    , pending = 0

  var absolute_path = path.resolve(entry_point)

  walker = walk(absolute_path, {followSymLinks: options.links})

  walker
    .on('file', onfile_found)
    .on('end', onend)
    .on('error', ready)

  if(options.links) {
    walker.on('link', onlink)
  }

  function onfile_found(to, stat) {
    pending++

    if(options.ignore && options.ignore.test(to)) {
      return
    }

    var aggregator_stream = concat(function(data) {
      blob[to] = data.toString()

      pending--

      return maybe_done()
    })

    var readstream = fs.createReadStream(to)

    if(!options['file-transform']) {
      return readstream.pipe(aggregator_stream)
    }

    var command = options['file-transform'].split(' ')[0]
      , args = options['file-transform'].split(' ').slice(1)

    var child = spawn(command, args)

    child.stdout
      .on('error', ready)
      .pipe(aggregator_stream)

    readstream.pipe(child.stdin)
  }

  function onend() {
    ended = true

    maybe_done()
  }

  function maybe_done() {
    if(!pending && ended) {
      ready(null, blob[''] || blob)
    }
  }
}
<|endoftext|>


<commit_before>var _ = require('lodash');
var express = require('express');
var fs = require('fs');
var grappling = require('grappling-hook');
var path = require('path');
var utils = require('keystone-utils');

/**
 * Don't use process.cwd() as it breaks module encapsulation
 * Instead, let's use module.parent if it's present, or the module itself if there is no parent (probably testing keystone directly if that's the case)
 * This way, the consuming app/module can be an embedded node_module and path resolutions will still work
 * (process.cwd() breaks module encapsulation if the consuming app/module is itself a node_module)
 */
var moduleRoot = (function (_rootPath) {
	var parts = _rootPath.split(path.sep);
	parts.pop(); // get rid of /node_modules from the end of the path
	return parts.join(path.sep);
})(module.parent ? module.parent.paths[0] : module.paths[0]);

/**
 * Keystone Class
 */
var Keystone = function () {
	grappling.mixin(this).allowHooks('pre:static', 'pre:bodyparser', 'pre:session', 'pre:logger', 'pre:admin', 'pre:routes', 'pre:render', 'updates', 'signin', 'signout');
	this.lists = {};
	this.fieldTypes = {};
	this.paths = {};
	this._options = {
		'name': 'Keystone',
		'brand': 'Keystone',
		'admin path': 'keystone',
		'compress': true,
		'headless': false,
		'logger': ':method :url :status :response-time ms',
		'auto update': false,
		'model prefix': null,
		'module root': moduleRoot,
		'frame guard': 'sameorigin',
		'cache admin bundles': true,
	};
	this._redirects = {};

	// expose express
	this.express = express;

	// init environment defaults
	this.set('env', process.env.NODE_ENV || 'development');

	this.set('port', process.env.PORT || process.env.OPENSHIFT_NODEJS_PORT || '3000');
	this.set('host', process.env.HOST || process.env.IP || process.env.OPENSHIFT_NODEJS_IP || '0.0.0.0');
	this.set('listen', process.env.LISTEN);

	this.set('ssl', process.env.SSL);
	this.set('ssl port', process.env.SSL_PORT || '3001');
	this.set('ssl host', process.env.SSL_HOST || process.env.SSL_IP);
	this.set('ssl key', process.env.SSL_KEY);
	this.set('ssl cert', process.env.SSL_CERT);

	this.set('cookie secret', process.env.COOKIE_SECRET);
	this.set('cookie signin', (this.get('env') === 'development') ? true : false);

	this.set('embedly api key', process.env.EMBEDLY_API_KEY || process.env.EMBEDLY_APIKEY);
	this.set('mandrill api key', process.env.MANDRILL_API_KEY || process.env.MANDRILL_APIKEY);
	this.set('mandrill username', process.env.MANDRILL_USERNAME);
	this.set('google api key', process.env.GOOGLE_BROWSER_KEY);
	this.set('google server api key', process.env.GOOGLE_SERVER_KEY);
	this.set('ga property', process.env.GA_PROPERTY);
	this.set('ga domain', process.env.GA_DOMAIN);
	this.set('chartbeat property', process.env.CHARTBEAT_PROPERTY);
	this.set('chartbeat domain', process.env.CHARTBEAT_DOMAIN);
	this.set('allowed ip ranges', process.env.ALLOWED_IP_RANGES);

	if (process.env.S3_BUCKET && process.env.S3_KEY && process.env.S3_SECRET) {
		this.set('s3 config', { bucket: process.env.S3_BUCKET, key: process.env.S3_KEY, secret: process.env.S3_SECRET, region: process.env.S3_REGION });
	}

	if (process.env.AZURE_STORAGE_ACCOUNT && process.env.AZURE_STORAGE_ACCESS_KEY) {
		this.set('azurefile config', { account: process.env.AZURE_STORAGE_ACCOUNT, key: process.env.AZURE_STORAGE_ACCESS_KEY });
	}

	if (process.env.CLOUDINARY_URL) {
		// process.env.CLOUDINARY_URL is processed by the cloudinary package when this is set
		this.set('cloudinary config', true);
	}

	// init mongoose
	this.set('mongoose', require('mongoose'));
	this.mongoose.Promise = require('es6-promise').Promise;

	// Attach middleware packages, bound to this instance
	this.middleware = {
		api: require('./lib/middleware/api')(this),
		cors: require('./lib/middleware/cors')(this),
	};
};

_.extend(Keystone.prototype, require('./lib/core/options'));

Keystone.prototype.prefixModel = function (key) {
	var modelPrefix = this.get('model prefix');

	if (modelPrefix) {
		key = modelPrefix + '_' + key;
	}

	return require('mongoose/lib/utils').toCollectionName(key);
};

/* Attach core functionality to Keystone.prototype */
Keystone.prototype.createItems = require('./lib/core/createItems');
Keystone.prototype.createRouter = require('./lib/core/createRouter');
Keystone.prototype.getOrphanedLists = require('./lib/core/getOrphanedLists');
Keystone.prototype.importer = require('./lib/core/importer');
Keystone.prototype.init = require('./lib/core/init');
Keystone.prototype.initDatabaseConfig = require('./lib/core/initDatabaseConfig');
Keystone.prototype.initExpressApp = require('./lib/core/initExpressApp');
Keystone.prototype.initExpressSession = require('./lib/core/initExpressSession');
Keystone.prototype.initNav = require('./lib/core/initNav');
Keystone.prototype.list = require('./lib/core/list');
Keystone.prototype.openDatabaseConnection = require('./lib/core/openDatabaseConnection');
Keystone.prototype.closeDatabaseConnection = require('./lib/core/closeDatabaseConnection');
Keystone.prototype.populateRelated = require('./lib/core/populateRelated');
Keystone.prototype.redirect = require('./lib/core/redirect');
Keystone.prototype.start = require('./lib/core/start');
Keystone.prototype.wrapHTMLError = require('./lib/core/wrapHTMLError');
Keystone.prototype.createKeystoneHash = require('./lib/core/createKeystoneHash');

/* Deprecation / Change warnings for 0.4 */
Keystone.prototype.routes = function () {
	throw new Error('keystone.routes(fn) has been removed, use keystone.set(\'routes\', fn)');
};

/**
 * The exports object is an instance of Keystone.
 */
var keystone = module.exports = new Keystone();

/*
	Note: until #1777 is complete, the order of execution here with the requires
	(specifically, they happen _after_ the module.exports above) is really
	important. As soon as the circular dependencies are sorted out to get their
	keystone instance from a closure or reference on {this} we can move these
	bindings into the Keystone constructor.
*/

// Expose modules and Classes
keystone.Admin = {
	Server: require('./admin/server'),
};
keystone.Email = require('./lib/email');
keystone.Field = require('./fields/types/Type');
keystone.Field.Types = require('./lib/fieldTypes');
keystone.Keystone = Keystone;
keystone.List = require('./lib/list')(keystone);
keystone.Storage = require('./lib/storage');
keystone.View = require('./lib/view');

keystone.content = require('./lib/content');
keystone.security = {
	csrf: require('./lib/security/csrf'),
};
keystone.utils = utils;

/**
 * returns all .js modules (recursively) in the path specified, relative
 * to the module root (where the keystone project is being consumed from).
 *
 * ####Example:
 *     var models = keystone.import('models');
 */

Keystone.prototype.import = function (dirname) {

	var initialPath = path.join(this.get('module root'), dirname);

	var doImport = function (fromPath) {

		var imported = {};

		fs.readdirSync(fromPath).forEach(function (name) {

			var fsPath = path.join(fromPath, name);
			var info = fs.statSync(fsPath);

			// recur
			if (info.isDirectory()) {
				imported[name] = doImport(fsPath);
			} else {
				// only import files that we can `require`
				var ext = path.extname(name);
				var base = path.basename(name, ext);
				if (require.extensions[ext]) {
					imported[base] = require(fsPath);
				}
			}

		});

		return imported;
	};

	return doImport(initialPath);
};

/**
 * Applies Application updates
 */

Keystone.prototype.applyUpdates = function (callback) {
	var self = this;
	self.callHook('pre:updates', function (err) {
		if (err) return callback(err);
		require('./lib/updates').apply(function (err) {
			if (err) return callback(err);
			self.callHook('post:updates', callback);
		});
	});
};

/**
 * Logs a configuration error to the console
 */

Keystone.prototype.console = {};
Keystone.prototype.console.err = function (type, msg) {
	if (keystone.get('logger')) {
		var dashes = '\n------------------------------------------------\n';
		console.log(dashes + 'KeystoneJS: ' + type + ':\n\n' + msg + dashes);
	}
};

/**
 * Keystone version
 */

keystone.version = require('./package.json').version;

// Expose Modules
keystone.session = require('./lib/session');
<commit_msg>adding db list<commit_after>var _ = require('lodash');
var express = require('express');
var fs = require('fs');
var grappling = require('grappling-hook');
var path = require('path');
var utils = require('keystone-utils');

/**
 * Don't use process.cwd() as it breaks module encapsulation
 * Instead, let's use module.parent if it's present, or the module itself if there is no parent (probably testing keystone directly if that's the case)
 * This way, the consuming app/module can be an embedded node_module and path resolutions will still work
 * (process.cwd() breaks module encapsulation if the consuming app/module is itself a node_module)
 */
var moduleRoot = (function (_rootPath) {
	var parts = _rootPath.split(path.sep);
	parts.pop(); // get rid of /node_modules from the end of the path
	return parts.join(path.sep);
})(module.parent ? module.parent.paths[0] : module.paths[0]);

/**
 * Keystone Class
 */
var Keystone = function () {
	grappling.mixin(this).allowHooks('pre:static', 'pre:bodyparser', 'pre:session', 'pre:logger', 'pre:admin', 'pre:routes', 'pre:render', 'updates', 'signin', 'signout');
	this.lists = {};
	this.fieldTypes = {};
	this.paths = {};
	this._options = {
		'name': 'Keystone',
		'brand': 'Keystone',
		'admin path': 'keystone',
		'compress': true,
		'headless': false,
		'logger': ':method :url :status :response-time ms',
		'auto update': false,
		'model prefix': null,
		'db opt': null,
		'module root': moduleRoot,
		'frame guard': 'sameorigin',
		'cache admin bundles': true,
	};
	this._redirects = {};

	// expose express
	this.express = express;

	// init environment defaults
	this.set('env', process.env.NODE_ENV || 'development');

	this.set('port', process.env.PORT || process.env.OPENSHIFT_NODEJS_PORT || '3000');
	this.set('host', process.env.HOST || process.env.IP || process.env.OPENSHIFT_NODEJS_IP || '0.0.0.0');
	this.set('listen', process.env.LISTEN);

	this.set('ssl', process.env.SSL);
	this.set('ssl port', process.env.SSL_PORT || '3001');
	this.set('ssl host', process.env.SSL_HOST || process.env.SSL_IP);
	this.set('ssl key', process.env.SSL_KEY);
	this.set('ssl cert', process.env.SSL_CERT);

	this.set('cookie secret', process.env.COOKIE_SECRET);
	this.set('cookie signin', (this.get('env') === 'development') ? true : false);

	this.set('embedly api key', process.env.EMBEDLY_API_KEY || process.env.EMBEDLY_APIKEY);
	this.set('mandrill api key', process.env.MANDRILL_API_KEY || process.env.MANDRILL_APIKEY);
	this.set('mandrill username', process.env.MANDRILL_USERNAME);
	this.set('google api key', process.env.GOOGLE_BROWSER_KEY);
	this.set('google server api key', process.env.GOOGLE_SERVER_KEY);
	this.set('ga property', process.env.GA_PROPERTY);
	this.set('ga domain', process.env.GA_DOMAIN);
	this.set('chartbeat property', process.env.CHARTBEAT_PROPERTY);
	this.set('chartbeat domain', process.env.CHARTBEAT_DOMAIN);
	this.set('allowed ip ranges', process.env.ALLOWED_IP_RANGES);

	if (process.env.S3_BUCKET && process.env.S3_KEY && process.env.S3_SECRET) {
		this.set('s3 config', {
			bucket: process.env.S3_BUCKET,
			key: process.env.S3_KEY,
			secret: process.env.S3_SECRET,
			region: process.env.S3_REGION
		});
	}

	if (process.env.AZURE_STORAGE_ACCOUNT && process.env.AZURE_STORAGE_ACCESS_KEY) {
		this.set('azurefile config', {
			account: process.env.AZURE_STORAGE_ACCOUNT,
			key: process.env.AZURE_STORAGE_ACCESS_KEY
		});
	}

	if (process.env.CLOUDINARY_URL) {
		// process.env.CLOUDINARY_URL is processed by the cloudinary package when this is set
		this.set('cloudinary config', true);
	}

	// init mongoose
	this.set('mongoose', require('mongoose'));
	this.mongoose.Promise = require('es6-promise').Promise;

	// Attach middleware packages, bound to this instance
	this.middleware = {
		api: require('./lib/middleware/api')(this),
		cors: require('./lib/middleware/cors')(this),
	};
};

_.extend(Keystone.prototype, require('./lib/core/options'));

Keystone.prototype.prefixModel = function (key) {
	var modelPrefix = this.get('model prefix');

	if (modelPrefix) {
		key = modelPrefix + '_' + key;
	}
	if (_.isObject(this.get('db opt'))) {
		return require('mongoose/lib/utils').toCollectionName(key, this.get('db opt'));
	} else {
		return require('mongoose/lib/utils').toCollectionName(key);
	}
};

/* Attach core functionality to Keystone.prototype */
Keystone.prototype.createItems = require('./lib/core/createItems');
Keystone.prototype.createRouter = require('./lib/core/createRouter');
Keystone.prototype.getOrphanedLists = require('./lib/core/getOrphanedLists');
Keystone.prototype.importer = require('./lib/core/importer');
Keystone.prototype.init = require('./lib/core/init');
Keystone.prototype.initDatabaseConfig = require('./lib/core/initDatabaseConfig');
Keystone.prototype.initExpressApp = require('./lib/core/initExpressApp');
Keystone.prototype.initExpressSession = require('./lib/core/initExpressSession');
Keystone.prototype.initNav = require('./lib/core/initNav');
Keystone.prototype.list = require('./lib/core/list');
Keystone.prototype.openDatabaseConnection = require('./lib/core/openDatabaseConnection');
Keystone.prototype.closeDatabaseConnection = require('./lib/core/closeDatabaseConnection');
Keystone.prototype.populateRelated = require('./lib/core/populateRelated');
Keystone.prototype.redirect = require('./lib/core/redirect');
Keystone.prototype.start = require('./lib/core/start');
Keystone.prototype.wrapHTMLError = require('./lib/core/wrapHTMLError');
Keystone.prototype.createKeystoneHash = require('./lib/core/createKeystoneHash');

/* Deprecation / Change warnings for 0.4 */
Keystone.prototype.routes = function () {
	throw new Error('keystone.routes(fn) has been removed, use keystone.set(\'routes\', fn)');
};

/**
 * The exports object is an instance of Keystone.
 */
var keystone = module.exports = new Keystone();

/*
 Note: until #1777 is complete, the order of execution here with the requires
 (specifically, they happen _after_ the module.exports above) is really
 important. As soon as the circular dependencies are sorted out to get their
 keystone instance from a closure or reference on {this} we can move these
 bindings into the Keystone constructor.
 */

// Expose modules and Classes
keystone.Admin = {
	Server: require('./admin/server'),
};
keystone.Email = require('./lib/email');
keystone.Field = require('./fields/types/Type');
keystone.Field.Types = require('./lib/fieldTypes');
keystone.Keystone = Keystone;
keystone.List = require('./lib/list')(keystone);
keystone.Storage = require('./lib/storage');
keystone.View = require('./lib/view');

keystone.content = require('./lib/content');
keystone.security = {
	csrf: require('./lib/security/csrf'),
};
keystone.utils = utils;

/**
 * returns all .js modules (recursively) in the path specified, relative
 * to the module root (where the keystone project is being consumed from).
 *
 * ####Example:
 *     var models = keystone.import('models');
 */

Keystone.prototype.import = function (dirname) {

	var initialPath = path.join(this.get('module root'), dirname);

	var doImport = function (fromPath) {

		var imported = {};

		fs.readdirSync(fromPath).forEach(function (name) {

			var fsPath = path.join(fromPath, name);
			var info = fs.statSync(fsPath);

			// recur
			if (info.isDirectory()) {
				imported[name] = doImport(fsPath);
			} else {
				// only import files that we can `require`
				var ext = path.extname(name);
				var base = path.basename(name, ext);
				if (require.extensions[ext]) {
					imported[base] = require(fsPath);
				}
			}

		});

		return imported;
	};

	return doImport(initialPath);
};

/**
 * Applies Application updates
 */

Keystone.prototype.applyUpdates = function (callback) {
	var self = this;
	self.callHook('pre:updates', function (err) {
		if (err) return callback(err);
		require('./lib/updates').apply(function (err) {
			if (err) return callback(err);
			self.callHook('post:updates', callback);
		});
	});
};

/**
 * Logs a configuration error to the console
 */

Keystone.prototype.console = {};
Keystone.prototype.console.err = function (type, msg) {
	if (keystone.get('logger')) {
		var dashes = '\n------------------------------------------------\n';
		console.log(dashes + 'KeystoneJS: ' + type + ':\n\n' + msg + dashes);
	}
};

/**
 * Keystone version
 */

keystone.version = require('./package.json').version;

// Expose Modules
keystone.session = require('./lib/session');
<|endoftext|>


<commit_before>var path = require('path');
var Promise = require('bluebird');
var npm = require('npm');
var fs = Promise.promisifyAll(require('fs'));

function clap () { return clap.load.apply(null, arguments); }

clap.load = Promise.method(function (val, opts) {
  if (arguments.length === 1) { opts = val; val = opts.val; }

  return clap.resolve(opts).map(function (plugin) {
    return {
      plugin: plugin,
      promise: Promise.method(function () { return opts.module.require(plugin)(val); })()
    };
  });
});

clap.resolve = Promise.method(function (opts) {
  var sources = (opts.paths || []).map(function (optPath) {
    return fs.readdirAsync(optPath)
      .catch(function () { return []; })
      .map(function (file) { return path.join(optPath, file); });
  });
  if (opts.keyword) {
    var mod = opts.module || require.main;
    sources.push(clap.lsGlobalPkgs().then(function (globalPkgs) {
      var pkgs = globalPkgs;
      if (mod) pkgs = pkgs.concat(Object
        .keys(mod.require('./package').dependencies || {})
        .map(function (dep) { return mod.require(dep+'/package'); }));
      return pkgs.reduce(function (pkgs, pkg) {
        if ((pkg.keywords || []).indexOf(opts.keyword) !== -1) pkgs.push(pkg.realPath || pkg.name);
        return pkgs;
      }, []);
    }));
  }
  return Promise.reduce(sources, function (results, plugins) {
    return results.concat(plugins);
  }, []);
});

clap.lsGlobalPkgs = Promise.method(function () {
  return clap._lsGlobalPkgs = clap._lsGlobalPkgs || clap.loadNpmGlobal()
    .then(function () { return Promise.promisify(npm.commands.ls, npm)([], true); })
    .spread(function (ls) {
      var globalPkgs = ls.dependencies || {};
      return Object.keys(globalPkgs).map(function (globalPkg) { return globalPkgs[globalPkg]; });
    });
});
clap.loadNpmGlobal = Promise.method(function () {
  return clap._loadNpmGlobal = clap._loadNpmGlobal ||
    Promise.promisify(npm.load, npm)({global: true, depth: 1, loglevel: 'silent'});
});

module.exports = clap;
<commit_msg>Ensures only one package is require'd if multiple packages have the same name<commit_after>var path = require('path');
var Promise = require('bluebird');
var npm = require('npm');
var fs = Promise.promisifyAll(require('fs'));

function clap () { return clap.load.apply(null, arguments); }

clap.load = Promise.method(function (val, opts) {
  if (arguments.length === 1) { opts = val; val = opts.val; }

  return clap.resolve(opts).map(function (plugin) {
    return {
      plugin: plugin,
      promise: Promise.method(function () { return opts.module.require(plugin)(val); })()
    };
  });
});

clap.resolve = Promise.method(function (opts) {
  var sources = (opts.paths || []).map(function (optPath) {
    return fs.readdirAsync(optPath)
      .catch(function () { return []; })
      .map(function (file) { return path.join(optPath, file); });
  });
  if (opts.keyword) {
    var mod = opts.module || require.main;
    sources.push(clap.lsGlobalPkgs().then(function (globalPkgs) {
      var pkgs = globalPkgs;
      if (mod) pkgs = pkgs.concat(Object
        .keys(mod.require('./package').dependencies || {})
        .map(function (dep) { return mod.require(dep+'/package'); }));

      var matchingPkgs = pkgs.reduce(function (matchingPkgs, pkg) {
        if ((pkg.keywords || []).indexOf(opts.keyword) !== -1) matchingPkgs[pkg.name] = pkg;
        return matchingPkgs;
      }, {});
      return Object.keys(matchingPkgs).map(function (pkgName) {
        var pkg = matchingPkgs[pkgName];
        return pkg.realPath || pkg.name;
      });
    }));
  }
  return Promise.reduce(sources, function (results, plugins) {
    return results.concat(plugins);
  }, []);
});

clap.lsGlobalPkgs = Promise.method(function () {
  return clap._lsGlobalPkgs = clap._lsGlobalPkgs || clap.loadNpmGlobal()
    .then(function () { return Promise.promisify(npm.commands.ls, npm)([], true); })
    .spread(function (ls) {
      var globalPkgs = ls.dependencies || {};
      return Object.keys(globalPkgs).map(function (globalPkg) { return globalPkgs[globalPkg]; });
    });
});
clap.loadNpmGlobal = Promise.method(function () {
  return clap._loadNpmGlobal = clap._loadNpmGlobal ||
    Promise.promisify(npm.load, npm)({global: true, depth: 1, loglevel: 'silent'});
});

module.exports = clap;
<|endoftext|>


<commit_before>const webpack = require('webpack');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const WriteFilePlugin = require('write-file-webpack-plugin');
const DrupalTemplatePlugin = require('./drupal-templates-webpack-plugin');

process.noDeprecation = true;

const path = require('path');

const config = {
    entry: {
        app: './src/app.js',
        pages: './pages/index.js',
    },
    devtool: '#source-map',
    output: {
        path: path.resolve(process.cwd(), 'assets'),
        publicPath: 'needs-to-be-set',
        filename: '[name].js',
    },
    devServer: {
        inline: true,
        quiet: false,
        noInfo: false,
        https: true,
        stats: {
            assets: false,
            colors: true,
            version: false,
            hash: false,
            timings: false,
            chunks: false,
            chunkModules: false,
        },
        proxy: {
            '*': {
                target: 'http://localhost:3000',
                secure: false,
            },
        },
    },
    module: {
        rules: [
            {
                test: /\.js$/,
                exclude: /(node_modules)/,
                loader: 'babel-loader',
                options: {
                    presets: ['env'],
                },
            },
            {
                test: /\.scss$/,
                loader: ExtractTextPlugin.extract([
                    { loader: 'css-loader', options: { sourceMap: true } },
                    { loader: 'postcss-loader', options: { sourceMap: true, plugins: () => [ require('autoprefixer') ] } },
                    { loader: 'sass-loader', options: { sourceMap: true } },
                ]),
            },
            {
                test: /\.css$/,
                use: ExtractTextPlugin.extract([
                    { loader: 'css-loader', options: { sourceMap: true } },
                    { loader: 'postcss-loader', options: { sourceMap: true, plugins: () => [ require('autoprefixer') ] } },
                ]),
            },
            {
                issuer: /\.scss$/,
                test: /.*\.(gif|png|jpe?g|svg)(\?v=\d+\.\d+\.\d+)?$/i,
                use: [
                    {
                        loader: 'url-loader',
                        options: {
                            limit: 1000,
                            name: '[path][name].[ext]',
                            context: 'src',
                        },
                    },
                ],
            },
            {
                issuer: {exclude: /\.scss$/},
                test: /.*\.(gif|png|jpe?g|svg)(\?v=\d+\.\d+\.\d+)?$/i,
                use: [
                    {
                        loader: 'file-loader',
                        options: {
                            name: '[path][name].[ext]',
                            context: 'src',
                        },
                    },
                ],
            },
            { test: /\.(tpl\.php|html\.twig)$/, loader: 'file-loader', options: { regExp: '.*/src/(.*)', name: '[1]' }, exclude: [/pages/] },
            { test: /(\.php|\.twig|\.twig\.html)$/, loader: 'file-loader', options: { name: 'pages/[name].[ext]' }, exclude: [/src/] },

            { test: /\.eot(\?v=\d+\.\d+\.\d+)?$/, loader: 'file-loader' },
            { test: /\.(woff|woff2)$/, loader: 'url-loader', options: { prefix: 'font/', limit: 5000 } },
            { test: /\.[ot]tf(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader', options: { limit: 10000, mimetype: 'application/octet-stream' } },
        ],
    },
    plugins: [
        new WriteFilePlugin({ log: false }),
        new DrupalTemplatePlugin({ ignore: /.*pages.*/ }),
        new ExtractTextPlugin('[name].css'),
    ],
};

if (typeof process.env.DOCKER_LOCAL !== 'undefined' && process.env.DOCKER_LOCAL === "1") {
    config.devServer.host = "0.0.0.0";
    config.devServer.port = 80;
    config.devServer.https = false;
    config.devServer.disableHostCheck = true;
    config.devServer.proxy['*'].target = 'http://fe-php:80';
}

module.exports = config;
<commit_msg>We need to set watch option polling time under Docker<commit_after>const webpack = require('webpack');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const WriteFilePlugin = require('write-file-webpack-plugin');
const DrupalTemplatePlugin = require('./drupal-templates-webpack-plugin');

process.noDeprecation = true;

const path = require('path');

const config = {
    entry: {
        app: './src/app.js',
        pages: './pages/index.js',
    },
    devtool: '#source-map',
    output: {
        path: path.resolve(process.cwd(), 'assets'),
        publicPath: 'needs-to-be-set',
        filename: '[name].js',
    },
    devServer: {
        inline: true,
        quiet: false,
        noInfo: false,
        https: true,
        stats: {
            assets: false,
            colors: true,
            version: false,
            hash: false,
            timings: false,
            chunks: false,
            chunkModules: false,
        },
        proxy: {
            '*': {
                target: 'http://localhost:3000',
                secure: false,
            },
        },
    },
    module: {
        rules: [
            {
                test: /\.js$/,
                exclude: /(node_modules)/,
                loader: 'babel-loader',
                options: {
                    presets: ['env'],
                },
            },
            {
                test: /\.scss$/,
                loader: ExtractTextPlugin.extract([
                    { loader: 'css-loader', options: { sourceMap: true } },
                    { loader: 'postcss-loader', options: { sourceMap: true, plugins: () => [ require('autoprefixer') ] } },
                    { loader: 'sass-loader', options: { sourceMap: true } },
                ]),
            },
            {
                test: /\.css$/,
                use: ExtractTextPlugin.extract([
                    { loader: 'css-loader', options: { sourceMap: true } },
                    { loader: 'postcss-loader', options: { sourceMap: true, plugins: () => [ require('autoprefixer') ] } },
                ]),
            },
            {
                issuer: /\.scss$/,
                test: /.*\.(gif|png|jpe?g|svg)(\?v=\d+\.\d+\.\d+)?$/i,
                use: [
                    {
                        loader: 'url-loader',
                        options: {
                            limit: 1000,
                            name: '[path][name].[ext]',
                            context: 'src',
                        },
                    },
                ],
            },
            {
                issuer: {exclude: /\.scss$/},
                test: /.*\.(gif|png|jpe?g|svg)(\?v=\d+\.\d+\.\d+)?$/i,
                use: [
                    {
                        loader: 'file-loader',
                        options: {
                            name: '[path][name].[ext]',
                            context: 'src',
                        },
                    },
                ],
            },
            { test: /\.(tpl\.php|html\.twig)$/, loader: 'file-loader', options: { regExp: '.*/src/(.*)', name: '[1]' }, exclude: [/pages/] },
            { test: /(\.php|\.twig|\.twig\.html)$/, loader: 'file-loader', options: { name: 'pages/[name].[ext]' }, exclude: [/src/] },

            { test: /\.eot(\?v=\d+\.\d+\.\d+)?$/, loader: 'file-loader' },
            { test: /\.(woff|woff2)$/, loader: 'url-loader', options: { prefix: 'font/', limit: 5000 } },
            { test: /\.[ot]tf(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader', options: { limit: 10000, mimetype: 'application/octet-stream' } },
        ],
    },
    plugins: [
        new WriteFilePlugin({ log: false }),
        new DrupalTemplatePlugin({ ignore: /.*pages.*/ }),
        new ExtractTextPlugin('[name].css'),
    ],
};

if (typeof process.env.DOCKER_LOCAL !== 'undefined' && process.env.DOCKER_LOCAL === "1") {
    config.devServer.host = "0.0.0.0";
    config.devServer.port = 80;
    config.devServer.https = false;
    config.devServer.disableHostCheck = true;
    config.devServer.proxy['*'].target = 'http://fe-php:80';
    config.watchOptions = config.watchOptions || {};
    config.watchOptions.poll = 1000;
}

module.exports = config;
<|endoftext|>