<commit_before>var exec = require("child_process").exec;
var defer = require("when").defer;
var extend = require("underscore").extend;
var createProfile = require("./profile");
var console = require("./utils").console;
var normalizeBinary = require("./utils").normalizeBinary;
var getID = require("jetpack-id");
var TEST_RESULTS_REGEX = /\d+ of \d+ tests passed/i

/**
 * Takes a manifest object (from package.json) and options,
 * and runs Firefox.
 *
 * @param {Object} manifest
 * @param {Object} options
 *   - `binary` path to Firefox binary to use
 *   - `profile` path to profile or profile name to use
 *   - `binaryArgs` binary arguments to pass into Firefox, split up by spaces
 *   - `verbose` whether or not Firefox should print all of stdout
 * @return {Promise}
 */

function runFirefox (manifest, options) {
  var master = defer();
  var profileDeferred = defer();
  var runDeferred = defer();
  options = options || {};
  var binary = null;
  var args = ['-no-remote'];

  // Create profile if none passed in
  if (!options.profile) {
    createProfile(options).then(profileDeferred.resolve);
  }
  else {
    profileDeferred.resolve(options.profile);
  }

  function handleProfile (profile) {
    // Firefox takes -P if given a profile name and
    // -profile if given a path (starting with "/" or "./").
    if (!/[\\\/]/.test(profile))
      args = args.concat(['-P', profile]);
    else
      args = args.concat(['-profile', '"' + profile + '"']);

    if (options.binaryArgs)
      args = args.concat(options.binaryArgs.split(" "));

    var cmd = '"' + binary + '" ' + args.join(" ");

    if (options.verbose)  {
      console.log("Executing Firefox binary: " + binary);
      console.log("Executing Firefox with args: " + args);
    }

    var env = extend({}, process.env, {
      "XPCOM_DEBUG_BREAK": "stack",
      "NS_TRACE_MALLOC_DISABLE_STACKS": "1"
    });

    // Use `process.std[out|err].write` to write to screen
    // instead of console.log since console.logs are silenced during testing
    var task = exec(cmd, { env: env }, function(err, stdout, stderr) {
      if (/No such file/.test(err)) {
        console.error("No Firefox binary found at " + binary);
        if (!options.binary) {
          console.error("Specify a Firefox binary to use with the `-b` flag.");
        }
      }

      process.removeListener("exit", killFirefox);

      if (options.verbose) {
        if (err) {
          process.stdout.write("err: " + err + '\n');
        }
        process.stderr.write(stderr);
      }

      runDeferred.resolve(task);
    });

    task.stdout.on("data", function(data) {
      var write = false;

      if (options.verbose ||
          TEST_RESULTS_REGEX.test(data) ||
          logFromAddon(manifest, data)) {
        write = true;
      }

      if (write) {
        process.stdout.write(data);
      }
    });

    function killFirefox () {
      task.kill();
    }

    // Kill child process when main process is killed
    process.once("exit", killFirefox);
    master.resolve(runDeferred.promise);
  }

  normalizeBinary(options.binary).then(function(path) {
    binary = path;
    profileDeferred.promise.then(handleProfile);
  });
  return master.promise;
}
module.exports = runFirefox;

function logFromAddon (manifest, line) {
  // Use `manifest.name` instead of ID, since that's what the SDK uses to log
  return (new RegExp("^console\\.[a-z]+: " + manifest.name + ":")).test(line);

}<commit_msg>Remove the master promise variable for readability<commit_after>var exec = require("child_process").exec;
var defer = require("when").defer;
var extend = require("underscore").extend;
var createProfile = require("./profile");
var console = require("./utils").console;
var normalizeBinary = require("./utils").normalizeBinary;
var getID = require("jetpack-id");
var TEST_RESULTS_REGEX = /\d+ of \d+ tests passed/i

/**
 * Takes a manifest object (from package.json) and options,
 * and runs Firefox.
 *
 * @param {Object} manifest
 * @param {Object} options
 *   - `binary` path to Firefox binary to use
 *   - `profile` path to profile or profile name to use
 *   - `binaryArgs` binary arguments to pass into Firefox, split up by spaces
 *   - `verbose` whether or not Firefox should print all of stdout
 * @return {Promise}
 */

function runFirefox (manifest, options) {
  var profileDeferred = defer();
  var runDeferred = defer();
  options = options || {};
  var binary = null;
  var args = ['-no-remote'];

  // Create profile if none passed in
  if (!options.profile) {
    createProfile(options).then(profileDeferred.resolve);
  }
  else {
    profileDeferred.resolve(options.profile);
  }

  function handleProfile (profile) {
    // Firefox takes -P if given a profile name and
    // -profile if given a path (starting with "/" or "./").
    if (!/[\\\/]/.test(profile))
      args = args.concat(['-P', profile]);
    else
      args = args.concat(['-profile', '"' + profile + '"']);

    if (options.binaryArgs)
      args = args.concat(options.binaryArgs.split(" "));

    var cmd = '"' + binary + '" ' + args.join(" ");

    if (options.verbose)  {
      console.log("Executing Firefox binary: " + binary);
      console.log("Executing Firefox with args: " + args);
    }

    var env = extend({}, process.env, {
      "XPCOM_DEBUG_BREAK": "stack",
      "NS_TRACE_MALLOC_DISABLE_STACKS": "1"
    });

    // Use `process.std[out|err].write` to write to screen
    // instead of console.log since console.logs are silenced during testing
    var task = exec(cmd, { env: env }, function(err, stdout, stderr) {
      if (/No such file/.test(err)) {
        console.error("No Firefox binary found at " + binary);
        if (!options.binary) {
          console.error("Specify a Firefox binary to use with the `-b` flag.");
        }
      }

      process.removeListener("exit", killFirefox);

      if (options.verbose) {
        if (err) {
          process.stdout.write("err: " + err + '\n');
        }
        process.stderr.write(stderr);
      }

      runDeferred.resolve(task);
    });

    task.stdout.on("data", function(data) {
      var write = false;

      if (options.verbose ||
          TEST_RESULTS_REGEX.test(data) ||
          logFromAddon(manifest, data)) {
        write = true;
      }

      if (write) {
        process.stdout.write(data);
      }
    });

    function killFirefox () {
      task.kill();
    }

    // Kill child process when main process is killed
    process.once("exit", killFirefox);
    return runDeferred.promise;
  }
  return normalizeBinary(options.binary).then(function(path) {
    binary = path;
    return profileDeferred.promise;
  }).then(handleProfile);
}
module.exports = runFirefox;

function logFromAddon (manifest, line) {
  // Use `manifest.name` instead of ID, since that's what the SDK uses to log
  return (new RegExp("^console\\.[a-z]+: " + manifest.name + ":")).test(line);

}
{'fraction_non_alphanumeric': 0.14849624060150377, 'fraction_numerical': 0.0002891844997108155, 'mean_word_length': 2.815223386651958, 'pattern_counts': {'":': 6, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '176507', 'n_tokens_mistral': 2148, 'n_tokens_neox': 2059, 'n_words': 579}