<commit_before>// @remove-on-eject-begin
/**
 * Copyright (c) 2015-present, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 */
// @remove-on-eject-end

process.env.NODE_ENV = 'development';

// Load environment variables from .env file. Suppress warnings using silent
// if this file is missing. dotenv will never modify any environment variables
// that have already been set.
// https://github.com/motdotla/dotenv
require('dotenv').config({silent: true});

var chalk = require('chalk');
var webpack = require('webpack');
var WebpackDevServer = require('webpack-dev-server');
var historyApiFallback = require('connect-history-api-fallback');
var httpProxyMiddleware = require('http-proxy-middleware');
var detect = require('detect-port');
var clearConsole = require('react-dev-utils/clearConsole');
var checkRequiredFiles = require('react-dev-utils/checkRequiredFiles');
var formatWebpackMessages = require('react-dev-utils/formatWebpackMessages');
var openBrowser = require('react-dev-utils/openBrowser');
var prompt = require('react-dev-utils/prompt');
var config = require('../config/webpack.config.dev');
var paths = require('../config/paths');

// Warn and crash if required files are missing
if (!checkRequiredFiles([paths.appHtml, paths.appIndexJs])) {
  process.exit(1);
}

// Tools like Cloud9 rely on this.
var DEFAULT_PORT = process.env.PORT || 3000;
var compiler;
var handleCompile;

// You can safely remove this after ejecting.
// We only use this block for testing of Create React App itself:
var isSmokeTest = process.argv.some(arg => arg.indexOf('--smoke-test') > -1);
if (isSmokeTest) {
  handleCompile = function (err, stats) {
    if (err || stats.hasErrors() || stats.hasWarnings()) {
      process.exit(1);
    } else {
      process.exit(0);
    }
  };
}

function setupCompiler(host, port, protocol) {
  // "Compiler" is a low-level interface to Webpack.
  // It lets us listen to some events and provide our own custom messages.
  compiler = webpack(config, handleCompile);

  // "invalid" event fires when you have changed a file, and Webpack is
  // recompiling a bundle. WebpackDevServer takes care to pause serving the
  // bundle, so if you refresh, it'll wait instead of serving the old one.
  // "invalid" is short for "bundle invalidated", it doesn't imply any errors.
  compiler.plugin('invalid', function() {
    clearConsole();
    console.log('Compiling...');
  });

  // "done" event fires when Webpack has finished recompiling the bundle.
  // Whether or not you have warnings or errors, you will get this event.
  compiler.plugin('done', function(stats) {
    clearConsole();

    // We have switched off the default Webpack output in WebpackDevServer
    // options so we are going to "massage" the warnings and errors and present
    // them in a readable focused way.
    var messages = formatWebpackMessages(stats.toJson({}, true));
    if (!messages.errors.length && !messages.warnings.length) {
      console.log(chalk.green('Compiled successfully!'));
      console.log();
      console.log('The app is running at:');
      console.log();
      console.log('  ' + chalk.cyan(protocol + '://' + host + ':' + port + '/'));
      console.log();
      console.log('Note that the development build is not optimized.');
      console.log('To create a production build, use ' + chalk.cyan('npm run build') + '.');
      console.log();
    }

    // If errors exist, only show errors.
    if (messages.errors.length) {
      console.log(chalk.red('Failed to compile.'));
      console.log();
      messages.errors.forEach(message => {
        console.log(message);
        console.log();
      });
      return;
    }

    // Show warnings if no errors were found.
    if (messages.warnings.length) {
      console.log(chalk.yellow('Compiled with warnings.'));
      console.log();
      messages.warnings.forEach(message => {
        console.log(message);
        console.log();
      });
      // Teach some ESLint tricks.
      console.log('You may use special comments to disable some warnings.');
      console.log('Use ' + chalk.yellow('// eslint-disable-next-line') + ' to ignore the next line.');
      console.log('Use ' + chalk.yellow('/* eslint-disable */') + ' to ignore all warnings in a file.');
    }
  });
}

// We need to provide a custom onError function for httpProxyMiddleware.
// It allows us to log custom error messages on the console.
function onProxyError(proxy) {
  return function(err, req, res){
    var host = req.headers && req.headers.host;
    console.log(
      chalk.red('Proxy error:') + ' Could not proxy request ' + chalk.cyan(req.url) +
      ' from ' + chalk.cyan(host) + ' to ' + chalk.cyan(proxy) + '.'
    );
    console.log(
      'See https://nodejs.org/api/errors.html#errors_common_system_errors for more information (' +
      chalk.cyan(err.code) + ').'
    );
    console.log();

    // And immediately send the proper error response to the client.
    // Otherwise, the request will eventually timeout with ERR_EMPTY_RESPONSE on the client side.
    if (res.writeHead && !res.headersSent) {
        res.writeHead(500);
    }
    res.end('Proxy error: Could not proxy request ' + req.url + ' from ' +
      host + ' to ' + proxy + ' (' + err.code + ').'
    );
  }
}

function addMiddleware(devServer) {
  // `proxy` lets you to specify a fallback server during development.
  // Every unrecognized request will be forwarded to it.
  var proxy = require(paths.appPackageJson).proxy;
  devServer.use(historyApiFallback({
    // Paths with dots should still use the history fallback.
    // See https://github.com/facebookincubator/create-react-app/issues/387.
    disableDotRule: true,
    // For single page apps, we generally want to fallback to /index.html.
    // However we also want to respect `proxy` for API calls.
    // So if `proxy` is specified, we need to decide which fallback to use.
    // We use a heuristic: if request `accept`s text/html, we pick /index.html.
    // Modern browsers include text/html into `accept` header when navigating.
    // However API calls like `fetch()` won’t generally accept text/html.
    // If this heuristic doesn’t work well for you, don’t use `proxy`.
    htmlAcceptHeaders: proxy ?
      ['text/html'] :
      ['text/html', '*/*']
  }));
  if (proxy) {
    if (typeof proxy !== 'string') {
      console.log(chalk.red('When specified, "proxy" in package.json must be a string.'));
      console.log(chalk.red('Instead, the type of "proxy" was "' + typeof proxy + '".'));
      console.log(chalk.red('Either remove "proxy" from package.json, or make it a string.'));
      process.exit(1);
    }

    // Otherwise, if proxy is specified, we will let it handle any request.
    // There are a few exceptions which we won't send to the proxy:
    // - /index.html (served as HTML5 history API fallback)
    // - /*.hot-update.json (WebpackDevServer uses this too for hot reloading)
    // - /sockjs-node/* (WebpackDevServer uses this for hot reloading)
    // Tip: use https://jex.im/regulex/ to visualize the regex
    var mayProxy = /^(?!\/(index\.html$|.*\.hot-update\.json$|sockjs-node\/)).*$/;
    devServer.use(mayProxy,
      // Pass the scope regex both to Express and to the middleware for proxying
      // of both HTTP and WebSockets to work without false positives.
      httpProxyMiddleware(pathname => mayProxy.test(pathname), {
        target: proxy,
        logLevel: 'silent',
        onError: onProxyError(proxy),
        secure: false,
        changeOrigin: true
      })
    );
  }
  // Finally, by now we have certainly resolved the URL.
  // It may be /index.html, so let the dev server try serving it again.
  devServer.use(devServer.middleware);
}

function runDevServer(host, port, protocol) {
  var devServer = new WebpackDevServer(compiler, {
    // Silence WebpackDevServer's own logs since they're generally not useful.
    // It will still show compile warnings and errors with this setting.
    clientLogLevel: 'none',
    // By default WebpackDevServer serves physical files from current directory
    // in addition to all the virtual build products that it serves from memory.
    // This is confusing because those files won’t automatically be available in
    // production build folder unless we copy them. However, copying the whole
    // project directory is dangerous because we may expose sensitive files.
    // Instead, we establish a convention that only files in `public` directory
    // get served. Our build script will copy `public` into the `build` folder.
    // In `index.html`, you can get URL of `public` folder with %PUBLIC_PATH%:
    // <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
    // In JavaScript code, you can access it with `process.env.PUBLIC_URL`.
    // Note that we only recommend to use `public` folder as an escape hatch
    // for files like `favicon.ico`, `manifest.json`, and libraries that are
    // for some reason broken when imported through Webpack. If you just want to
    // use an image, put it in `src` and `import` it from JavaScript instead.
    contentBase: paths.appPublic,
    // Enable hot reloading server. It will provide /sockjs-node/ endpoint
    // for the WebpackDevServer client so it can learn when the files were
    // updated. The WebpackDevServer client is included as an entry point
    // in the Webpack development configuration. Note that only changes
    // to CSS are currently hot reloaded. JS changes will refresh the browser.
    hot: true,
    // It is important to tell WebpackDevServer to use the same "root" path
    // as we specified in the config. In development, we always serve from /.
    publicPath: config.output.publicPath,
    // WebpackDevServer is noisy by default so we emit custom message instead
    // by listening to the compiler events with `compiler.plugin` calls above.
    quiet: true,
    // Reportedly, this avoids CPU overload on some systems.
    // https://github.com/facebookincubator/create-react-app/issues/293
    watchOptions: {
      ignored: /node_modules/
    },
    // Enable HTTPS if the HTTPS environment variable is set to 'true'
    https: protocol === "https",
    host: host
  });

  // Our custom middleware proxies requests to /index.html or a remote API.
  addMiddleware(devServer);

  // Launch WebpackDevServer.
  devServer.listen(port, (err, result) => {
    if (err) {
      return console.log(err);
    }

    clearConsole();
    console.log(chalk.cyan('Starting the development server...'));
    console.log();
    openBrowser(protocol + '://' + host + ':' + port + '/');
  });
}

function run(port) {
  var protocol = process.env.HTTPS === 'true' ? "https" : "http";
  var host = process.env.HOST || 'localhost';
  setupCompiler(host, port, protocol);
  runDevServer(host, port, protocol);
}

// We attempt to use the default port but if it is busy, we offer the user to
// run on a different port. `detect()` Promise resolves to the next free port.
detect(DEFAULT_PORT).then(port => {
  if (port === DEFAULT_PORT) {
    run(port);
    return;
  }

  clearConsole();
  var question =
    chalk.yellow('Something is already running on port ' + DEFAULT_PORT + '.') +
    '\n\nWould you like to run the app on another port instead?';

  prompt(question, true).then(shouldChangePort => {
    if (shouldChangePort) {
      run(port);
    }
  });
});
<commit_msg>Enable compression on webpack-dev-server (#966) (#968)<commit_after>// @remove-on-eject-begin
/**
 * Copyright (c) 2015-present, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 */
// @remove-on-eject-end

process.env.NODE_ENV = 'development';

// Load environment variables from .env file. Suppress warnings using silent
// if this file is missing. dotenv will never modify any environment variables
// that have already been set.
// https://github.com/motdotla/dotenv
require('dotenv').config({silent: true});

var chalk = require('chalk');
var webpack = require('webpack');
var WebpackDevServer = require('webpack-dev-server');
var historyApiFallback = require('connect-history-api-fallback');
var httpProxyMiddleware = require('http-proxy-middleware');
var detect = require('detect-port');
var clearConsole = require('react-dev-utils/clearConsole');
var checkRequiredFiles = require('react-dev-utils/checkRequiredFiles');
var formatWebpackMessages = require('react-dev-utils/formatWebpackMessages');
var openBrowser = require('react-dev-utils/openBrowser');
var prompt = require('react-dev-utils/prompt');
var config = require('../config/webpack.config.dev');
var paths = require('../config/paths');

// Warn and crash if required files are missing
if (!checkRequiredFiles([paths.appHtml, paths.appIndexJs])) {
  process.exit(1);
}

// Tools like Cloud9 rely on this.
var DEFAULT_PORT = process.env.PORT || 3000;
var compiler;
var handleCompile;

// You can safely remove this after ejecting.
// We only use this block for testing of Create React App itself:
var isSmokeTest = process.argv.some(arg => arg.indexOf('--smoke-test') > -1);
if (isSmokeTest) {
  handleCompile = function (err, stats) {
    if (err || stats.hasErrors() || stats.hasWarnings()) {
      process.exit(1);
    } else {
      process.exit(0);
    }
  };
}

function setupCompiler(host, port, protocol) {
  // "Compiler" is a low-level interface to Webpack.
  // It lets us listen to some events and provide our own custom messages.
  compiler = webpack(config, handleCompile);

  // "invalid" event fires when you have changed a file, and Webpack is
  // recompiling a bundle. WebpackDevServer takes care to pause serving the
  // bundle, so if you refresh, it'll wait instead of serving the old one.
  // "invalid" is short for "bundle invalidated", it doesn't imply any errors.
  compiler.plugin('invalid', function() {
    clearConsole();
    console.log('Compiling...');
  });

  // "done" event fires when Webpack has finished recompiling the bundle.
  // Whether or not you have warnings or errors, you will get this event.
  compiler.plugin('done', function(stats) {
    clearConsole();

    // We have switched off the default Webpack output in WebpackDevServer
    // options so we are going to "massage" the warnings and errors and present
    // them in a readable focused way.
    var messages = formatWebpackMessages(stats.toJson({}, true));
    if (!messages.errors.length && !messages.warnings.length) {
      console.log(chalk.green('Compiled successfully!'));
      console.log();
      console.log('The app is running at:');
      console.log();
      console.log('  ' + chalk.cyan(protocol + '://' + host + ':' + port + '/'));
      console.log();
      console.log('Note that the development build is not optimized.');
      console.log('To create a production build, use ' + chalk.cyan('npm run build') + '.');
      console.log();
    }

    // If errors exist, only show errors.
    if (messages.errors.length) {
      console.log(chalk.red('Failed to compile.'));
      console.log();
      messages.errors.forEach(message => {
        console.log(message);
        console.log();
      });
      return;
    }

    // Show warnings if no errors were found.
    if (messages.warnings.length) {
      console.log(chalk.yellow('Compiled with warnings.'));
      console.log();
      messages.warnings.forEach(message => {
        console.log(message);
        console.log();
      });
      // Teach some ESLint tricks.
      console.log('You may use special comments to disable some warnings.');
      console.log('Use ' + chalk.yellow('// eslint-disable-next-line') + ' to ignore the next line.');
      console.log('Use ' + chalk.yellow('/* eslint-disable */') + ' to ignore all warnings in a file.');
    }
  });
}

// We need to provide a custom onError function for httpProxyMiddleware.
// It allows us to log custom error messages on the console.
function onProxyError(proxy) {
  return function(err, req, res){
    var host = req.headers && req.headers.host;
    console.log(
      chalk.red('Proxy error:') + ' Could not proxy request ' + chalk.cyan(req.url) +
      ' from ' + chalk.cyan(host) + ' to ' + chalk.cyan(proxy) + '.'
    );
    console.log(
      'See https://nodejs.org/api/errors.html#errors_common_system_errors for more information (' +
      chalk.cyan(err.code) + ').'
    );
    console.log();

    // And immediately send the proper error response to the client.
    // Otherwise, the request will eventually timeout with ERR_EMPTY_RESPONSE on the client side.
    if (res.writeHead && !res.headersSent) {
        res.writeHead(500);
    }
    res.end('Proxy error: Could not proxy request ' + req.url + ' from ' +
      host + ' to ' + proxy + ' (' + err.code + ').'
    );
  }
}

function addMiddleware(devServer) {
  // `proxy` lets you to specify a fallback server during development.
  // Every unrecognized request will be forwarded to it.
  var proxy = require(paths.appPackageJson).proxy;
  devServer.use(historyApiFallback({
    // Paths with dots should still use the history fallback.
    // See https://github.com/facebookincubator/create-react-app/issues/387.
    disableDotRule: true,
    // For single page apps, we generally want to fallback to /index.html.
    // However we also want to respect `proxy` for API calls.
    // So if `proxy` is specified, we need to decide which fallback to use.
    // We use a heuristic: if request `accept`s text/html, we pick /index.html.
    // Modern browsers include text/html into `accept` header when navigating.
    // However API calls like `fetch()` won’t generally accept text/html.
    // If this heuristic doesn’t work well for you, don’t use `proxy`.
    htmlAcceptHeaders: proxy ?
      ['text/html'] :
      ['text/html', '*/*']
  }));
  if (proxy) {
    if (typeof proxy !== 'string') {
      console.log(chalk.red('When specified, "proxy" in package.json must be a string.'));
      console.log(chalk.red('Instead, the type of "proxy" was "' + typeof proxy + '".'));
      console.log(chalk.red('Either remove "proxy" from package.json, or make it a string.'));
      process.exit(1);
    }

    // Otherwise, if proxy is specified, we will let it handle any request.
    // There are a few exceptions which we won't send to the proxy:
    // - /index.html (served as HTML5 history API fallback)
    // - /*.hot-update.json (WebpackDevServer uses this too for hot reloading)
    // - /sockjs-node/* (WebpackDevServer uses this for hot reloading)
    // Tip: use https://jex.im/regulex/ to visualize the regex
    var mayProxy = /^(?!\/(index\.html$|.*\.hot-update\.json$|sockjs-node\/)).*$/;
    devServer.use(mayProxy,
      // Pass the scope regex both to Express and to the middleware for proxying
      // of both HTTP and WebSockets to work without false positives.
      httpProxyMiddleware(pathname => mayProxy.test(pathname), {
        target: proxy,
        logLevel: 'silent',
        onError: onProxyError(proxy),
        secure: false,
        changeOrigin: true
      })
    );
  }
  // Finally, by now we have certainly resolved the URL.
  // It may be /index.html, so let the dev server try serving it again.
  devServer.use(devServer.middleware);
}

function runDevServer(host, port, protocol) {
  var devServer = new WebpackDevServer(compiler, {
    // Enable gzip compression of generated files.
    compress: true,
    // Silence WebpackDevServer's own logs since they're generally not useful.
    // It will still show compile warnings and errors with this setting.
    clientLogLevel: 'none',
    // By default WebpackDevServer serves physical files from current directory
    // in addition to all the virtual build products that it serves from memory.
    // This is confusing because those files won’t automatically be available in
    // production build folder unless we copy them. However, copying the whole
    // project directory is dangerous because we may expose sensitive files.
    // Instead, we establish a convention that only files in `public` directory
    // get served. Our build script will copy `public` into the `build` folder.
    // In `index.html`, you can get URL of `public` folder with %PUBLIC_PATH%:
    // <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
    // In JavaScript code, you can access it with `process.env.PUBLIC_URL`.
    // Note that we only recommend to use `public` folder as an escape hatch
    // for files like `favicon.ico`, `manifest.json`, and libraries that are
    // for some reason broken when imported through Webpack. If you just want to
    // use an image, put it in `src` and `import` it from JavaScript instead.
    contentBase: paths.appPublic,
    // Enable hot reloading server. It will provide /sockjs-node/ endpoint
    // for the WebpackDevServer client so it can learn when the files were
    // updated. The WebpackDevServer client is included as an entry point
    // in the Webpack development configuration. Note that only changes
    // to CSS are currently hot reloaded. JS changes will refresh the browser.
    hot: true,
    // It is important to tell WebpackDevServer to use the same "root" path
    // as we specified in the config. In development, we always serve from /.
    publicPath: config.output.publicPath,
    // WebpackDevServer is noisy by default so we emit custom message instead
    // by listening to the compiler events with `compiler.plugin` calls above.
    quiet: true,
    // Reportedly, this avoids CPU overload on some systems.
    // https://github.com/facebookincubator/create-react-app/issues/293
    watchOptions: {
      ignored: /node_modules/
    },
    // Enable HTTPS if the HTTPS environment variable is set to 'true'
    https: protocol === "https",
    host: host
  });

  // Our custom middleware proxies requests to /index.html or a remote API.
  addMiddleware(devServer);

  // Launch WebpackDevServer.
  devServer.listen(port, (err, result) => {
    if (err) {
      return console.log(err);
    }

    clearConsole();
    console.log(chalk.cyan('Starting the development server...'));
    console.log();
    openBrowser(protocol + '://' + host + ':' + port + '/');
  });
}

function run(port) {
  var protocol = process.env.HTTPS === 'true' ? "https" : "http";
  var host = process.env.HOST || 'localhost';
  setupCompiler(host, port, protocol);
  runDevServer(host, port, protocol);
}

// We attempt to use the default port but if it is busy, we offer the user to
// run on a different port. `detect()` Promise resolves to the next free port.
detect(DEFAULT_PORT).then(port => {
  if (port === DEFAULT_PORT) {
    run(port);
    return;
  }

  clearConsole();
  var question =
    chalk.yellow('Something is already running on port ' + DEFAULT_PORT + '.') +
    '\n\nWould you like to run the app on another port instead?';

  prompt(question, true).then(shouldChangePort => {
    if (shouldChangePort) {
      run(port);
    }
  });
});
<|endoftext|>


<commit_before>/* global __phantom_writeFile */
(function(global) {
    var UNDEFINED,
        exportObject;

    if (typeof module !== "undefined" && module.exports) {
        exportObject = exports;
    } else {
        exportObject = global.jasmineReporters = global.jasmineReporters || {};
    }

    function trim(str) { return str.replace(/^\s+/, "" ).replace(/\s+$/, "" ); }
    function elapsed(start, end) { return (end - start)/1000; }
    function isFailed(obj) { return obj.status === "failed"; }
    function isSkipped(obj) { return obj.status === "pending"; }
    function isDisabled(obj) { return obj.status === "disabled"; }
    function pad(n) { return n < 10 ? '0'+n : n; }
    function extend(dupe, obj) { // performs a shallow copy of all props of `obj` onto `dupe`
        for (var prop in obj) {
            if (obj.hasOwnProperty(prop)) {
                dupe[prop] = obj[prop];
            }
        }
        return dupe;
    }
    function ISODateString(d) {
        return d.getFullYear() + '-' +
            pad(d.getMonth()+1) + '-' +
            pad(d.getDate()) + 'T' +
            pad(d.getHours()) + ':' +
            pad(d.getMinutes()) + ':' +
            pad(d.getSeconds());
    }
    function escapeInvalidXmlChars(str) {
        return str.replace(/\&/g, "&")
            .replace(/</g, "<")
            .replace(/\>/g, ">")
            .replace(/\"/g, """)
            .replace(/\'/g, "'");
    }
    function getQualifiedFilename(path, filename, separator) {
        if (path && path.substr(-1) !== separator && filename.substr(0) !== separator) {
            path += separator;
        }
        return path + filename;
    }
    function log(str) {
        var con = global.console || console;
        if (con && con.log) {
            con.log(str);
        }
    }

    /**
     * Generates JUnit XML for the given spec run. There are various options
     * to control where the results are written, and the default values are
     * set to create as few .xml files as possible. It is possible to save a
     * single XML file, or an XML file for each top-level `describe`, or an
     * XML file for each `describe` regardless of nesting.
     *
     * Usage:
     *
     * jasmine.getEnv().addReporter(new jasmineReporters.JUnitXmlReporter(options));
     *
     * @param {object} [options]
     * @param {string} [savePath] directory to save the files (default: '')
     * @param {boolean} [consolidateAll] whether to save all test results in a
     *   single file (default: true)
     *   NOTE: if true, {filePrefix} is treated as the full filename (excluding
     *     extension)
     * @param {boolean} [consolidate] whether to save nested describes within the
     *   same file as their parent (default: true)
     *   NOTE: true does nothing if consolidateAll is also true.
     *   NOTE: false also sets consolidateAll to false.
     * @param {boolean} [useDotNotation] whether to separate suite names with
     *   dots instead of spaces, ie "Class.init" not "Class init" (default: true)
     * @param {string} [filePrefix] is the string value that is prepended to the
     *   xml output file (default: junitresults-)
     *   NOTE: if consolidateAll is true, the default is simply "junitresults" and
     *     this becomes the actual filename, ie "junitresults.xml"
     */
    exportObject.JUnitXmlReporter = function(options) {
        var self = this;
        self.started = false;
        self.finished = false;
        // sanitize arguments
        options = options || {};
        self.savePath = options.savePath || '';
        self.consolidate = options.consolidate === UNDEFINED ? true : options.consolidate;
        self.consolidateAll = self.consolidate !== false && (options.consolidateAll === UNDEFINED ? true : options.consolidateAll);
        self.useDotNotation = options.useDotNotation === UNDEFINED ? true : options.useDotNotation;
        self.filePrefix = options.filePrefix || (self.consolidateAll ? 'junitresults' : 'junitresults-');

        var suites = [],
            currentSuite = null,
            totalSpecsExecuted = 0,
            totalSpecsDefined,
            // when use use fit, jasmine never calls suiteStarted / suiteDone, so make a fake one to use
            fakeFocusedSuite = {
                id: 'focused',
                description: 'focused specs',
                fullName: 'focused specs'
            };

        var __suites = {}, __specs = {};
        function getSuite(suite) {
            __suites[suite.id] = extend(__suites[suite.id] || {}, suite);
            return __suites[suite.id];
        }
        function getSpec(spec) {
            __specs[spec.id] = extend(__specs[spec.id] || {}, spec);
            return __specs[spec.id];
        }

        self.jasmineStarted = function(summary) {
            totalSpecsDefined = summary && summary.totalSpecsDefined || NaN;
            exportObject.startTime = new Date();
            self.started = true;
        };
        self.suiteStarted = function(suite) {
            suite = getSuite(suite);
            suite._startTime = new Date();
            suite._specs = [];
            suite._suites = [];
            suite._failures = 0;
            suite._skipped = 0;
            suite._disabled = 0;
            suite._parent = currentSuite;
            if (!currentSuite) {
                suites.push(suite);
            } else {
                currentSuite._suites.push(suite);
            }
            currentSuite = suite;
        };
        self.specStarted = function(spec) {
            if (!currentSuite) {
                // focused spec (fit) -- suiteStarted was never called
                self.suiteStarted(fakeFocusedSuite);
            }
            spec = getSpec(spec);
            spec._startTime = new Date();
            spec._suite = currentSuite;
            currentSuite._specs.push(spec);
        };
        self.specDone = function(spec) {
            spec = getSpec(spec);
            spec._endTime = new Date();
            if (isSkipped(spec)) { spec._suite._skipped++; }
            if (isDisabled(spec)) { spec._suite._disabled++; }
            if (isFailed(spec)) { spec._suite._failures += spec.failedExpectations.length; }
            totalSpecsExecuted++;
        };
        self.suiteDone = function(suite) {
            suite = getSuite(suite);
            if (suite._parent === UNDEFINED) {
                // disabled suite (xdescribe) -- suiteStarted was never called
                self.suiteStarted(suite);
            }
            suite._endTime = new Date();
            currentSuite = suite._parent;
        };
        self.jasmineDone = function() {
            if (currentSuite) {
                // focused spec (fit) -- suiteDone was never called
                self.suiteDone(fakeFocusedSuite);
            }
            var output = '';
            for (var i = 0; i < suites.length; i++) {
                output += self.getOrWriteNestedOutput(suites[i]);
            }
            // if we have anything to write here, write out the consolidated file
            if (output) {
                wrapOutputAndWriteFile(self.filePrefix, output);
            }
            //log("Specs skipped but not reported (entire suite skipped or targeted to specific specs)", totalSpecsDefined - totalSpecsExecuted + totalSpecsDisabled);

            self.finished = true;
            // this is so phantomjs-testrunner.js can tell if we're done executing
            exportObject.endTime = new Date();
        };

        self.getOrWriteNestedOutput = function(suite) {
            var output = suiteAsXml(suite);
            for (var i = 0; i < suite._suites.length; i++) {
                output += self.getOrWriteNestedOutput(suite._suites[i]);
            }
            if (self.consolidateAll || self.consolidate && suite._parent) {
                return output;
            } else {
                // if we aren't supposed to consolidate output, just write it now
                wrapOutputAndWriteFile(generateFilename(suite), output);
                return '';
            }
        };

        self.writeFile = function(filename, text) {
            var errors = [];
            var path = self.savePath;

            function phantomWrite(path, filename, text) {
                // turn filename into a qualified path
                filename = getQualifiedFilename(path, filename, window.fs_path_separator);
                // write via a method injected by phantomjs-testrunner.js
                __phantom_writeFile(filename, text);
            }

            function nodeWrite(path, filename, text) {
                var fs = require("fs");
                var nodejs_path = require("path");
                require("mkdirp").sync(path); // make sure the path exists
                var filepath = nodejs_path.join(path, filename);
                var xmlfile = fs.openSync(filepath, "w");
                fs.writeSync(xmlfile, text, 0);
                fs.closeSync(xmlfile);
                return;
            }
            // Attempt writing with each possible environment.
            // Track errors in case no write succeeds
            try {
                phantomWrite(path, filename, text);
                return;
            } catch (e) { errors.push('  PhantomJs attempt: ' + e.message); }
            try {
                nodeWrite(path, filename, text);
                return;
            } catch (f) { errors.push('  NodeJS attempt: ' + f.message); }

            // If made it here, no write succeeded.  Let user know.
            log("Warning: writing junit report failed for '" + path + "', '" +
                filename + "'. Reasons:\n" +
                errors.join("\n")
            );
        };

        /******** Helper functions with closure access for simplicity ********/
        function generateFilename(suite) {
            return self.filePrefix + getFullyQualifiedSuiteName(suite, true) + '.xml';
        }

        function getFullyQualifiedSuiteName(suite, isFilename) {
            var fullName;
            if (self.useDotNotation || isFilename) {
                fullName = suite.description;
                for (var parent = suite._parent; parent; parent = parent._parent) {
                    fullName = parent.description + '.' + fullName;
                }
            } else {
                fullName = suite.fullName;
            }

            // Either remove or escape invalid XML characters
            if (isFilename) {
                var fileName = "",
                    rFileChars = /[\w\.]/,
                    chr;
                while (fullName.length) {
                    chr = fullName[0];
                    fullName = fullName.substr(1);
                    if (rFileChars.test(chr)) {
                        fileName += chr;
                    }
                }
                return fileName;
            } else {
                return escapeInvalidXmlChars(fullName);
            }
        }

        function suiteAsXml(suite) {
            var xml = '\n <testsuite name="' + getFullyQualifiedSuiteName(suite) + '"';
            xml += ' timestamp="' + ISODateString(suite._startTime) + '"';
            xml += ' hostname="localhost"'; // many CI systems like Jenkins don't care about this, but junit spec says it is required
            xml += ' time="' + elapsed(suite._startTime, suite._endTime) + '"';
            xml += ' errors="0"';
            xml += ' tests="' + suite._specs.length + '"';
            xml += ' skipped="' + suite._skipped + '"';
            xml += ' disabled="' + suite._disabled + '"';
            // Because of JUnit's flat structure, only include directly failed tests (not failures for nested suites)
            xml += ' failures="' + suite._failures + '"';
            xml += '>';

            for (var i = 0; i < suite._specs.length; i++) {
                xml += specAsXml(suite._specs[i]);
            }
            xml += '\n </testsuite>';
            return xml;
        }
        function specAsXml(spec) {
            var xml = '\n  <testcase classname="' + getFullyQualifiedSuiteName(spec._suite) + '"';
            xml += ' name="' + escapeInvalidXmlChars(spec.description) + '"';
            xml += ' time="' + elapsed(spec._startTime, spec._endTime) + '"';

            var testCaseBody = '';
            if (isSkipped(spec) || isDisabled(spec)) {
                testCaseBody = '<skipped />';
            } else if (isFailed(spec)) {
                for (var i = 0, failure; i < spec.failedExpectations.length; i++) {
                    failure = spec.failedExpectations[i];
                    testCaseBody += '\n   <failure type="' + (failure.matcherName || "exception") + '"';
                    testCaseBody += ' message="' + trim(escapeInvalidXmlChars(failure.message))+ '"';
                    testCaseBody += '>';
                    testCaseBody += '<![CDATA[' + trim(failure.stack || failure.message) + ']]>';
                    testCaseBody += '\n   </failure>';
                }
            }

            if (testCaseBody) {
                xml += '>' + testCaseBody + '\n  </testcase>';
            } else {
                xml += ' />'
            }
            return xml;
        }

        // To remove complexity and be more DRY about the silly preamble and <testsuites> element
        var prefix = '<?xml version="1.0" encoding="UTF-8" ?>';
        prefix += '\n<testsuites>';
        var suffix = '\n</testsuites>';
        function wrapOutputAndWriteFile(filename, text) {
            if (filename.substr(-4) !== '.xml') { filename += '.xml'; }
            self.writeFile(filename, (prefix + text + suffix));
        }
    };
})(this);
<commit_msg>Uniform indent for testcase child elements<commit_after>/* global __phantom_writeFile */
(function(global) {
    var UNDEFINED,
        exportObject;

    if (typeof module !== "undefined" && module.exports) {
        exportObject = exports;
    } else {
        exportObject = global.jasmineReporters = global.jasmineReporters || {};
    }

    function trim(str) { return str.replace(/^\s+/, "" ).replace(/\s+$/, "" ); }
    function elapsed(start, end) { return (end - start)/1000; }
    function isFailed(obj) { return obj.status === "failed"; }
    function isSkipped(obj) { return obj.status === "pending"; }
    function isDisabled(obj) { return obj.status === "disabled"; }
    function pad(n) { return n < 10 ? '0'+n : n; }
    function extend(dupe, obj) { // performs a shallow copy of all props of `obj` onto `dupe`
        for (var prop in obj) {
            if (obj.hasOwnProperty(prop)) {
                dupe[prop] = obj[prop];
            }
        }
        return dupe;
    }
    function ISODateString(d) {
        return d.getFullYear() + '-' +
            pad(d.getMonth()+1) + '-' +
            pad(d.getDate()) + 'T' +
            pad(d.getHours()) + ':' +
            pad(d.getMinutes()) + ':' +
            pad(d.getSeconds());
    }
    function escapeInvalidXmlChars(str) {
        return str.replace(/\&/g, "&")
            .replace(/</g, "<")
            .replace(/\>/g, ">")
            .replace(/\"/g, """)
            .replace(/\'/g, "'");
    }
    function getQualifiedFilename(path, filename, separator) {
        if (path && path.substr(-1) !== separator && filename.substr(0) !== separator) {
            path += separator;
        }
        return path + filename;
    }
    function log(str) {
        var con = global.console || console;
        if (con && con.log) {
            con.log(str);
        }
    }

    /**
     * Generates JUnit XML for the given spec run. There are various options
     * to control where the results are written, and the default values are
     * set to create as few .xml files as possible. It is possible to save a
     * single XML file, or an XML file for each top-level `describe`, or an
     * XML file for each `describe` regardless of nesting.
     *
     * Usage:
     *
     * jasmine.getEnv().addReporter(new jasmineReporters.JUnitXmlReporter(options));
     *
     * @param {object} [options]
     * @param {string} [savePath] directory to save the files (default: '')
     * @param {boolean} [consolidateAll] whether to save all test results in a
     *   single file (default: true)
     *   NOTE: if true, {filePrefix} is treated as the full filename (excluding
     *     extension)
     * @param {boolean} [consolidate] whether to save nested describes within the
     *   same file as their parent (default: true)
     *   NOTE: true does nothing if consolidateAll is also true.
     *   NOTE: false also sets consolidateAll to false.
     * @param {boolean} [useDotNotation] whether to separate suite names with
     *   dots instead of spaces, ie "Class.init" not "Class init" (default: true)
     * @param {string} [filePrefix] is the string value that is prepended to the
     *   xml output file (default: junitresults-)
     *   NOTE: if consolidateAll is true, the default is simply "junitresults" and
     *     this becomes the actual filename, ie "junitresults.xml"
     */
    exportObject.JUnitXmlReporter = function(options) {
        var self = this;
        self.started = false;
        self.finished = false;
        // sanitize arguments
        options = options || {};
        self.savePath = options.savePath || '';
        self.consolidate = options.consolidate === UNDEFINED ? true : options.consolidate;
        self.consolidateAll = self.consolidate !== false && (options.consolidateAll === UNDEFINED ? true : options.consolidateAll);
        self.useDotNotation = options.useDotNotation === UNDEFINED ? true : options.useDotNotation;
        self.filePrefix = options.filePrefix || (self.consolidateAll ? 'junitresults' : 'junitresults-');

        var suites = [],
            currentSuite = null,
            totalSpecsExecuted = 0,
            totalSpecsDefined,
            // when use use fit, jasmine never calls suiteStarted / suiteDone, so make a fake one to use
            fakeFocusedSuite = {
                id: 'focused',
                description: 'focused specs',
                fullName: 'focused specs'
            };

        var __suites = {}, __specs = {};
        function getSuite(suite) {
            __suites[suite.id] = extend(__suites[suite.id] || {}, suite);
            return __suites[suite.id];
        }
        function getSpec(spec) {
            __specs[spec.id] = extend(__specs[spec.id] || {}, spec);
            return __specs[spec.id];
        }

        self.jasmineStarted = function(summary) {
            totalSpecsDefined = summary && summary.totalSpecsDefined || NaN;
            exportObject.startTime = new Date();
            self.started = true;
        };
        self.suiteStarted = function(suite) {
            suite = getSuite(suite);
            suite._startTime = new Date();
            suite._specs = [];
            suite._suites = [];
            suite._failures = 0;
            suite._skipped = 0;
            suite._disabled = 0;
            suite._parent = currentSuite;
            if (!currentSuite) {
                suites.push(suite);
            } else {
                currentSuite._suites.push(suite);
            }
            currentSuite = suite;
        };
        self.specStarted = function(spec) {
            if (!currentSuite) {
                // focused spec (fit) -- suiteStarted was never called
                self.suiteStarted(fakeFocusedSuite);
            }
            spec = getSpec(spec);
            spec._startTime = new Date();
            spec._suite = currentSuite;
            currentSuite._specs.push(spec);
        };
        self.specDone = function(spec) {
            spec = getSpec(spec);
            spec._endTime = new Date();
            if (isSkipped(spec)) { spec._suite._skipped++; }
            if (isDisabled(spec)) { spec._suite._disabled++; }
            if (isFailed(spec)) { spec._suite._failures += spec.failedExpectations.length; }
            totalSpecsExecuted++;
        };
        self.suiteDone = function(suite) {
            suite = getSuite(suite);
            if (suite._parent === UNDEFINED) {
                // disabled suite (xdescribe) -- suiteStarted was never called
                self.suiteStarted(suite);
            }
            suite._endTime = new Date();
            currentSuite = suite._parent;
        };
        self.jasmineDone = function() {
            if (currentSuite) {
                // focused spec (fit) -- suiteDone was never called
                self.suiteDone(fakeFocusedSuite);
            }
            var output = '';
            for (var i = 0; i < suites.length; i++) {
                output += self.getOrWriteNestedOutput(suites[i]);
            }
            // if we have anything to write here, write out the consolidated file
            if (output) {
                wrapOutputAndWriteFile(self.filePrefix, output);
            }
            //log("Specs skipped but not reported (entire suite skipped or targeted to specific specs)", totalSpecsDefined - totalSpecsExecuted + totalSpecsDisabled);

            self.finished = true;
            // this is so phantomjs-testrunner.js can tell if we're done executing
            exportObject.endTime = new Date();
        };

        self.getOrWriteNestedOutput = function(suite) {
            var output = suiteAsXml(suite);
            for (var i = 0; i < suite._suites.length; i++) {
                output += self.getOrWriteNestedOutput(suite._suites[i]);
            }
            if (self.consolidateAll || self.consolidate && suite._parent) {
                return output;
            } else {
                // if we aren't supposed to consolidate output, just write it now
                wrapOutputAndWriteFile(generateFilename(suite), output);
                return '';
            }
        };

        self.writeFile = function(filename, text) {
            var errors = [];
            var path = self.savePath;

            function phantomWrite(path, filename, text) {
                // turn filename into a qualified path
                filename = getQualifiedFilename(path, filename, window.fs_path_separator);
                // write via a method injected by phantomjs-testrunner.js
                __phantom_writeFile(filename, text);
            }

            function nodeWrite(path, filename, text) {
                var fs = require("fs");
                var nodejs_path = require("path");
                require("mkdirp").sync(path); // make sure the path exists
                var filepath = nodejs_path.join(path, filename);
                var xmlfile = fs.openSync(filepath, "w");
                fs.writeSync(xmlfile, text, 0);
                fs.closeSync(xmlfile);
                return;
            }
            // Attempt writing with each possible environment.
            // Track errors in case no write succeeds
            try {
                phantomWrite(path, filename, text);
                return;
            } catch (e) { errors.push('  PhantomJs attempt: ' + e.message); }
            try {
                nodeWrite(path, filename, text);
                return;
            } catch (f) { errors.push('  NodeJS attempt: ' + f.message); }

            // If made it here, no write succeeded.  Let user know.
            log("Warning: writing junit report failed for '" + path + "', '" +
                filename + "'. Reasons:\n" +
                errors.join("\n")
            );
        };

        /******** Helper functions with closure access for simplicity ********/
        function generateFilename(suite) {
            return self.filePrefix + getFullyQualifiedSuiteName(suite, true) + '.xml';
        }

        function getFullyQualifiedSuiteName(suite, isFilename) {
            var fullName;
            if (self.useDotNotation || isFilename) {
                fullName = suite.description;
                for (var parent = suite._parent; parent; parent = parent._parent) {
                    fullName = parent.description + '.' + fullName;
                }
            } else {
                fullName = suite.fullName;
            }

            // Either remove or escape invalid XML characters
            if (isFilename) {
                var fileName = "",
                    rFileChars = /[\w\.]/,
                    chr;
                while (fullName.length) {
                    chr = fullName[0];
                    fullName = fullName.substr(1);
                    if (rFileChars.test(chr)) {
                        fileName += chr;
                    }
                }
                return fileName;
            } else {
                return escapeInvalidXmlChars(fullName);
            }
        }

        function suiteAsXml(suite) {
            var xml = '\n <testsuite name="' + getFullyQualifiedSuiteName(suite) + '"';
            xml += ' timestamp="' + ISODateString(suite._startTime) + '"';
            xml += ' hostname="localhost"'; // many CI systems like Jenkins don't care about this, but junit spec says it is required
            xml += ' time="' + elapsed(suite._startTime, suite._endTime) + '"';
            xml += ' errors="0"';
            xml += ' tests="' + suite._specs.length + '"';
            xml += ' skipped="' + suite._skipped + '"';
            xml += ' disabled="' + suite._disabled + '"';
            // Because of JUnit's flat structure, only include directly failed tests (not failures for nested suites)
            xml += ' failures="' + suite._failures + '"';
            xml += '>';

            for (var i = 0; i < suite._specs.length; i++) {
                xml += specAsXml(suite._specs[i]);
            }
            xml += '\n </testsuite>';
            return xml;
        }
        function specAsXml(spec) {
            var xml = '\n  <testcase classname="' + getFullyQualifiedSuiteName(spec._suite) + '"';
            xml += ' name="' + escapeInvalidXmlChars(spec.description) + '"';
            xml += ' time="' + elapsed(spec._startTime, spec._endTime) + '"';

            var testCaseBody = '';
            if (isSkipped(spec) || isDisabled(spec)) {
                testCaseBody = '\n   <skipped />';
            } else if (isFailed(spec)) {
                for (var i = 0, failure; i < spec.failedExpectations.length; i++) {
                    failure = spec.failedExpectations[i];
                    testCaseBody += '\n   <failure type="' + (failure.matcherName || "exception") + '"';
                    testCaseBody += ' message="' + trim(escapeInvalidXmlChars(failure.message))+ '"';
                    testCaseBody += '>';
                    testCaseBody += '<![CDATA[' + trim(failure.stack || failure.message) + ']]>';
                    testCaseBody += '\n   </failure>';
                }
            }

            if (testCaseBody) {
                xml += '>' + testCaseBody + '\n  </testcase>';
            } else {
                xml += ' />'
            }
            return xml;
        }

        // To remove complexity and be more DRY about the silly preamble and <testsuites> element
        var prefix = '<?xml version="1.0" encoding="UTF-8" ?>';
        prefix += '\n<testsuites>';
        var suffix = '\n</testsuites>';
        function wrapOutputAndWriteFile(filename, text) {
            if (filename.substr(-4) !== '.xml') { filename += '.xml'; }
            self.writeFile(filename, (prefix + text + suffix));
        }
    };
})(this);
<|endoftext|>


<commit_before>/**
 *  Copyright (c) 2014, Facebook, Inc.
 *  All rights reserved.
 *
 *  This source code is licensed under the BSD-style license found in the
 *  LICENSE file in the root directory of this source tree. An additional grant
 *  of patent rights can be found in the PATENTS file in the same directory.
 */

'use strict';

var fs = require('fs');
var path = require('path');
var sane = require('sane');
var assert = require('assert');
var Server = require('./server');
var EventEmitter = require('events').EventEmitter;

module.exports = flo;

/**
 * Top-level API for flo. Defaults params and instantiates `Flo`.
 *
 * @param {string} dir
 * @param {object} options
 * @param {function} callback
 * @return {Flo}
 * @public
 */

function flo(dir, options, callback) {
  if (typeof options === 'function') {
    callback = options;
    options = null;
  }

  dir = path.resolve(dir);

  options = options || {};
  options = {
    port: options.port || 8888,
    host: options.host || 'localhost',
    verbose: options.verbose || false,
    glob: options.glob || [],
    useWatchman: options.useWatchman || false,
    useFilePolling: options.useFilePolling || false,
    pollingInterval: options.pollingInterval,
    watchDotFiles: options.watchDotFiles || false
  };

  callback = callback || noBuildCallback(dir);

  return new Flo(dir, options, callback);
}

/**
 * Time before we emit the ready event.
 */

var DELAY = 200;

/**
 * Starts the server and the watcher and handles the piping between both and the
 * resolver callback.
 *
 * @param {string} dir
 * @param {object} options
 * @param {function} callback
 * @class Flo
 * @private
 */

function Flo(dir, options, callback) {
  this.log = logger(options.verbose, 'Flo');
  this.dir = dir;
  this.realpathdir = fs.realpathSync(dir);
  this.resolver = callback;
  this.server = new Server({
    port: options.port,
    host: options.host,
    log: logger(options.verbose, 'Server')
  });

  this.watcher = new sane(dir, {
    glob: options.glob,
    poll: options.useFilePolling,
    interval: options.pollingInterval,
    watchman: options.useWatchman,
    dot: options.watchDotFiles
  });
  this.watcher.on('change', this.onFileChange.bind(this));
  this.watcher.on('ready', this.emit.bind(this, 'ready'));
  this.watcher.on('error', this.emit.bind(this, 'error'));
}

Flo.prototype.__proto__ = EventEmitter.prototype;

/**
 * Handles file changes.
 *
 * @param {string} filepath
 * @private
 */

Flo.prototype.onFileChange = function(filepath) {
  this.log('File changed', filepath);
  var server = this.server;
  this.resolver(filepath, function(resource) {
    resource = normalizeResource(resource);
    server.broadcast(resource);
  });
};

/**
 * Closes the server and the watcher.
 *
 * @public
 */

Flo.prototype.close = function() {
  this.log('Shutting down flo');
  this.watcher.close();
  this.server.close();
};

/**
 * Creates a logger for a given module.
 *
 * @param {boolean} verbose
 * @param {string} moduleName
 * @private
 */

function logger(verbose, moduleName) {
  var slice = [].slice;
  return function() {
    var args = slice.call(arguments);
    args[0] = '[' + moduleName + '] ' + args[0];
    if (verbose) {
      console.log.apply(console, args);
    }
  }
}

/**
 * Check if an object is of type RegExp.
 *
 * @param {*} o
 * @return {boolean}
 * @private
 */

function isRegExp(o) {
  return o && typeof o === 'object' &&
    Object.prototype.toString.call(o) === '[object RegExp]';
}

/**
 * Given a resource, enforce type checks, default params, and prepare for
 * serialization.
 *
 * @param {*} o
 * @return {boolean}
 * @private
 */

function normalizeResource(resource) {
  if (resource.reload) {
    return resource;
  }

  assert(resource.resourceURL, 'expecting resourceURL');
  assert(resource.contents != null, 'expecting contents');

  var ret = {};

  ret.match = resource.match || 'indexOf';
  ret.contents = resource.contents.toString();
  ret.resourceURL = resource.resourceURL;

  if ('function' === typeof resource.update) {
      ret.update = resource.update.toString();
  }

  if (path.sep === '\\') {
    ret.resourceURL = ret.resourceURL.replace(/\\/g, '/');
  }

  assert.ok(
    isRegExp(ret.match) ||
      ['indexOf', 'equal'].indexOf(ret.match) > -1,
      'resource.match must be of type function, or regexp, ' +
        'or a string either "indexOf" or "equal'
  );

  if (isRegExp(ret.match)) {
    var r = ret.match;
    ret.match = {
      type: 'regexp',
      source: r.source,
      global: r.global,
      multiline: r.multiline,
      ignoreCase: r.ignoreCase
    };
  }

  return ret;
}

/**
 * Default resolver callback that will simply read the file and pass back the
 * filename relative to the watched dir as the url.
 *
 * @param {string} dir
 * @return {function}
 * @private
 */

function noBuildCallback(dir) {
  return function(filepath, callback) {
    fs.readFile(path.join(dir, filepath), function(err, data) {
      // Todo better error handling.
      if (err) {
        throw err;
      }
      callback({
        resourceURL: filepath,
        contents: data.toString()
      });
    });
  };
}
<commit_msg>Watching multiple folders<commit_after>/**
 *  Copyright (c) 2014, Facebook, Inc.
 *  All rights reserved.
 *
 *  This source code is licensed under the BSD-style license found in the
 *  LICENSE file in the root directory of this source tree. An additional grant
 *  of patent rights can be found in the PATENTS file in the same directory.
 */

'use strict';

var fs = require('fs');
var path = require('path');
var sane = require('sane');
var assert = require('assert');
var Server = require('./server');
var EventEmitter = require('events').EventEmitter;

module.exports = flo;

/**
 * Top-level API for flo. Defaults params and instantiates `Flo`.
 *
 * @param {string} dir
 * @param {object} options
 * @param {function} callback
 * @return {Flo}
 * @public
 */

function flo(dir, options, callback) {
  if (typeof options === 'function') {
    callback = options;
    options = null;
  }

  if (typeof dir === 'string') {
    dir = [dir];
  }

  options = options || {};
  options = {
    port: options.port || 8888,
    host: options.host || 'localhost',
    verbose: options.verbose || false,
    glob: options.glob || [],
    useWatchman: options.useWatchman || false,
    useFilePolling: options.useFilePolling || false,
    pollingInterval: options.pollingInterval,
    watchDotFiles: options.watchDotFiles || false
  };

  return new Flo(dir, options, callback);
}

/**
 * Time before we emit the ready event.
 */

var DELAY = 200;

/**
 * Starts the server and the watcher and handles the piping between both and the
 * resolver callback.
 *
 * @param {string} dir
 * @param {object} options
 * @param {function} callback
 * @class Flo
 * @private
 */

function Flo(dir, options, callback) {
  this.log = logger(options.verbose, 'Flo');
  this.dir = dir;
  this.options = options;
  this.resolver = callback;
  this.server = new Server({
    port: options.port,
    host: options.host,
    log: logger(options.verbose, 'Server')
  });

  this.watchers=[];

  this.fileEvent = this.onFileChange.bind(this);

  this.watch();

}

Flo.prototype.__proto__ = EventEmitter.prototype;

/**
 * Handles file changes.
 *
 * @param {string} filepath
 * @private
 */

Flo.prototype.onFileChange = function(filepath,root) {
    filepath = root+'/'+filepath;
    this.log('File changed', filepath);
    var server = this.server;
    this.resolver(filepath, function(resource) {
        resource = normalizeResource(resource);
        server.broadcast(resource);
    });
};

/**
 * Start watching
 *
 * @private
 */
Flo.prototype.watch = function() {
  this.dir.forEach(function(){
    this.watchers[folder] = new sane( path.resolve(folder), {
      glob: this.options.glob,
      poll: this.options.useFilePolling,
      interval: this.options.pollingInterval,
      watchman: this.options.useWatchman,
      dot: this.options.watchDotFiles
    });
    this.watchers[folder].on('change', this.fileEvent);
    this.watchers[folder].once('ready', this.emit.bind(this, 'ready'));
    this.watchers[folder].on('error', this.emit.bind(this, 'error'));
    this.log("start watching ",folder);
  }.bind(this));
};

/**
 * Stop watching
 *
 * @private
 */

Flo.prototype.stopWatching = function(cb) {
    var self = this;
     this.dir.forEach(function(folder){
        this.watchers[folder].close();
        self.log("stop watching ",folder);
    }.bind(this));
     if(cb){
        cb();
    }
};

/**
 * Closes the server and the watcher.
 *
 * @public
 */

Flo.prototype.close = function() {
  this.log('Shutting down flo');
  this.stopWatching();
  this.server.close();
};

/**
 * Creates a logger for a given module.
 *
 * @param {boolean} verbose
 * @param {string} moduleName
 * @private
 */

function logger(verbose, moduleName) {
  var slice = [].slice;
  return function() {
    var args = slice.call(arguments);
    args[0] = '[' + moduleName + '] ' + args[0];
    if (verbose) {
      console.log.apply(console, args);
    }
  }
}

/**
 * Check if an object is of type RegExp.
 *
 * @param {*} o
 * @return {boolean}
 * @private
 */

function isRegExp(o) {
  return o && typeof o === 'object' &&
    Object.prototype.toString.call(o) === '[object RegExp]';
}

/**
 * Given a resource, enforce type checks, default params, and prepare for
 * serialization.
 *
 * @param {*} o
 * @return {boolean}
 * @private
 */

function normalizeResource(resource) {
  if (resource.reload) {
    return resource;
  }

  assert(resource.resourceURL, 'expecting resourceURL');
  assert(resource.contents != null, 'expecting contents');

  var ret = {};

  ret.match = resource.match || 'indexOf';
  ret.contents = resource.contents.toString();
  ret.resourceURL = resource.resourceURL;

  if ('function' === typeof resource.update) {
      ret.update = resource.update.toString();
  }

  if (path.sep === '\\') {
    ret.resourceURL = ret.resourceURL.replace(/\\/g, '/');
  }

  assert.ok(
    isRegExp(ret.match) ||
      ['indexOf', 'equal'].indexOf(ret.match) > -1,
      'resource.match must be of type function, or regexp, ' +
        'or a string either "indexOf" or "equal'
  );

  if (isRegExp(ret.match)) {
    var r = ret.match;
    ret.match = {
      type: 'regexp',
      source: r.source,
      global: r.global,
      multiline: r.multiline,
      ignoreCase: r.ignoreCase
    };
  }

  return ret;
}

/**
 * Default resolver callback that will simply read the file and pass back the
 * filename relative to the watched dir as the url.
 *
 * @param {string} dir
 * @return {function}
 * @private
 */

function noBuildCallback(dir) {
  return function(filepath, callback) {
    fs.readFile(path.join(dir, filepath), function(err, data) {
      // Todo better error handling.
      if (err) {
        throw err;
      }
      callback({
        resourceURL: filepath,
        contents: data.toString()
      });
    });
  };
}
<|endoftext|>


<commit_before>var gmail;

function refresh(f) {
  'use strict';
  if ((/in/.test(document.readyState)) || (Gmail === undefined)) {
    setTimeout('refresh(' + f + ')', 10);
  } else {
    f();
  }
}

function init(compose, type) {
  'use strict';
  console.log('api.dom.compose object:', compose, 'type is:', type);

  var checker = new WarningChecker();
  var observer = new MutationObserver(function() {
    var body = compose.dom('body');
    checker.addWarning(body, 'sorry', 'jns-warning');
  });

  var target = compose.$el.get(0);
  var config = {characterData: true, subtree: true};
  observer.observe(target, config);
}

function removeWarning(str) {
  'use strict';
  return str.replace(/jns-warning/gi, '');
}

function cleanup(url, body, data, xhr) {
  'use strict';
  var bodyParams = xhr.xhrParams.body_params;

  var oldCmml = xhr.xhrParams.url.cmml;

  var existingBody = bodyParams.body;
  var newBody = removeWarning(existingBody);

  if (newBody.length > oldCmml) {
    xhr.xhrParams.url.cmml = newBody.length;
  } else {
    newBody += '
';
    while (newBody.length < oldCmml) {
      newBody += ' ';
    }

    newBody += '
';
    xhr.xhrParams.url.cmml = newBody.length;
  }

  bodyParams.body = newBody;
}

var main = function() {
  'use strict';
  gmail = new Gmail();
  console.log('Hello,', gmail.get.user_email());
  gmail.observe.on('compose', init);
  gmail.observe.before('send_message', cleanup);
};

refresh(main);
<commit_msg>Change callback functions to have clearer names<commit_after>var gmail;

function refresh(f) {
  'use strict';
  if ((/in/.test(document.readyState)) || (Gmail === undefined)) {
    setTimeout('refresh(' + f + ')', 10);
  } else {
    f();
  }
}

function checkForWarnings(compose, type) {
  'use strict';
  console.log('api.dom.compose object:', compose, 'type is:', type);

  var checker = new WarningChecker();
  var observer = new MutationObserver(function() {
    var body = compose.dom('body');
    checker.addWarning(body, 'sorry', 'jns-warning');
  });

  var target = compose.$el.get(0);
  var config = {characterData: true, subtree: true};
  observer.observe(target, config);
}

function removeWarning(str) {
  'use strict';
  return str.replace(/jns-warning/gi, '');
}

function cleanupWarnings(url, body, data, xhr) {
  'use strict';
  var bodyParams = xhr.xhrParams.body_params;

  var oldCmml = xhr.xhrParams.url.cmml;

  var existingBody = bodyParams.body;
  var newBody = removeWarning(existingBody);

  if (newBody.length > oldCmml) {
    xhr.xhrParams.url.cmml = newBody.length;
  } else {
    newBody += '
';
    while (newBody.length < oldCmml) {
      newBody += ' ';
    }

    newBody += '
';
    xhr.xhrParams.url.cmml = newBody.length;
  }

  bodyParams.body = newBody;
}

var main = function() {
  'use strict';
  gmail = new Gmail();
  console.log('Hello,', gmail.get.user_email());
  gmail.observe.on('compose', checkForWarnings);
  gmail.observe.before('send_message', cleanupWarnings);
};

refresh(main);
<|endoftext|>


<commit_before>/*
Language: Ruby
Author: Anton Kovalyov <anton@kovalyov.net>
Contributors: Peter Leonov <gojpeg@yandex.ru>, Vasily Polovnyov <vast@whiteants.net>, Loren Segal <lsegal@soen.ca>, Pascal Hurni <phi@ruby-reactive.org>, Cedric Sohrauer <sohrauer@googlemail.com>
Category: common
*/

function(hljs) {
  var RUBY_METHOD_RE = '[a-zA-Z_]\\w*[!?=]?|[-+~]\\@|<<|>>|=~|===?|<=>|[<>]=?|\\*\\*|[-/+%^&*~`|]|\\[\\]=?';
  var RUBY_KEYWORDS = {
    keyword:
      'and then defined module in return redo if BEGIN retry end for self when ' +
      'next until do begin unless END rescue else break undef not super class case ' +
      'require yield alias while ensure elsif or include attr_reader attr_writer attr_accessor',
    literal:
      'true false nil'
  };
  var YARDOCTAG = {
    className: 'doctag',
    begin: '@[A-Za-z]+'
  };
  var IRB_OBJECT = {
    begin: '#<', end: '>'
  };
  var COMMENT_MODES = [
    hljs.COMMENT(
      '#',
      '$',
      {
        contains: [YARDOCTAG]
      }
    ),
    hljs.COMMENT(
      '^\\=begin',
      '^\\=end',
      {
        contains: [YARDOCTAG],
        relevance: 10
      }
    ),
    hljs.COMMENT('^__END__', '\\n$')
  ];
  var SUBST = {
    className: 'subst',
    begin: '#\\{', end: '}',
    keywords: RUBY_KEYWORDS
  };
  var STRING = {
    className: 'string',
    contains: [hljs.BACKSLASH_ESCAPE, SUBST],
    variants: [
      {begin: /'/, end: /'/},
      {begin: /"/, end: /"/},
      {begin: /`/, end: /`/},
      {begin: '%[qQwWx]?\\(', end: '\\)'},
      {begin: '%[qQwWx]?\\[', end: '\\]'},
      {begin: '%[qQwWx]?{', end: '}'},
      {begin: '%[qQwWx]?<', end: '>'},
      {begin: '%[qQwWx]?/', end: '/'},
      {begin: '%[qQwWx]?%', end: '%'},
      {begin: '%[qQwWx]?-', end: '-'},
      {begin: '%[qQwWx]?\\|', end: '\\|'},
      {
        // \B in the beginning suppresses recognition of ?-sequences where ?
        // is the last character of a preceding identifier, as in: `func?4`
        begin: /\B\?(\\\d{1,3}|\\x[A-Fa-f0-9]{1,2}|\\u[A-Fa-f0-9]{4}|\\?\S)\b/
      },
      {
        begin: /<<(-?)\w+$/, end: /^\s*\w+$/,
      }
    ]
  };
  var PARAMS = {
    className: 'params',
    begin: '\\(', end: '\\)', endsParent: true,
    keywords: RUBY_KEYWORDS
  };

  var RUBY_DEFAULT_CONTAINS = [
    STRING,
    IRB_OBJECT,
    {
      className: 'class',
      beginKeywords: 'class module', end: '$|;',
      illegal: /=/,
      contains: [
        hljs.inherit(hljs.TITLE_MODE, {begin: '[A-Za-z_]\\w*(::\\w+)*(\\?|\\!)?'}),
        {
          begin: '<\\s*',
          contains: [{
            begin: '(' + hljs.IDENT_RE + '::)?' + hljs.IDENT_RE
          }]
        }
      ].concat(COMMENT_MODES)
    },
    {
      className: 'function',
      beginKeywords: 'def', end: '$|;',
      contains: [
        hljs.inherit(hljs.TITLE_MODE, {begin: RUBY_METHOD_RE}),
        PARAMS
      ].concat(COMMENT_MODES)
    },
    {
      // swallow namespace qualifiers before symbols
      begin: hljs.IDENT_RE + '::'
    },
    {
      className: 'symbol',
      begin: hljs.UNDERSCORE_IDENT_RE + '(\\!|\\?)?:',
      relevance: 0
    },
    {
      className: 'symbol',
      begin: ':(?!\\s)',
      contains: [STRING, {begin: RUBY_METHOD_RE}],
      relevance: 0
    },
    {
      className: 'number',
      begin: '(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b',
      relevance: 0
    },
    {
      begin: '(\\$\\W)|((\\$|\\@\\@?)(\\w+))' // variables
    },
    {
      className: 'params',
      begin: /\|/, end: /\|/,
      keywords: RUBY_KEYWORDS
    },
    { // regexp container
      begin: '(' + hljs.RE_STARTERS_RE + '|unless)\\s*',
      contains: [
        IRB_OBJECT,
        {
          className: 'regexp',
          contains: [hljs.BACKSLASH_ESCAPE, SUBST],
          illegal: /\n/,
          variants: [
            {begin: '/', end: '/[a-z]*'},
            {begin: '%r{', end: '}[a-z]*'},
            {begin: '%r\\(', end: '\\)[a-z]*'},
            {begin: '%r!', end: '![a-z]*'},
            {begin: '%r\\[', end: '\\][a-z]*'}
          ]
        }
      ].concat(COMMENT_MODES),
      relevance: 0
    }
  ].concat(COMMENT_MODES);

  SUBST.contains = RUBY_DEFAULT_CONTAINS;
  PARAMS.contains = RUBY_DEFAULT_CONTAINS;

  var SIMPLE_PROMPT = "[>?]>";
  var DEFAULT_PROMPT = "[\\w#]+\\(\\w+\\):\\d+:\\d+>";
  var RVM_PROMPT = "(\\w+-)?\\d+\\.\\d+\\.\\d(p\\d+)?[^>]+>";

  var IRB_DEFAULT = [
    {
      begin: /^\s*=>/,
      starts: {
        end: '$', contains: RUBY_DEFAULT_CONTAINS
      }
    },
    {
      className: 'meta',
      begin: '^('+SIMPLE_PROMPT+"|"+DEFAULT_PROMPT+'|'+RVM_PROMPT+')',
      starts: {
        end: '$', contains: RUBY_DEFAULT_CONTAINS
      }
    }
  ];

  return {
    aliases: ['rb', 'gemspec', 'podspec', 'thor', 'irb'],
    keywords: RUBY_KEYWORDS,
    illegal: /\/\*/,
    contains: COMMENT_MODES.concat(IRB_DEFAULT).concat(RUBY_DEFAULT_CONTAINS)
  };
}
<commit_msg>Add `unless` to Ruby regex starters<commit_after>/*
Language: Ruby
Author: Anton Kovalyov <anton@kovalyov.net>
Contributors: Peter Leonov <gojpeg@yandex.ru>, Vasily Polovnyov <vast@whiteants.net>, Loren Segal <lsegal@soen.ca>, Pascal Hurni <phi@ruby-reactive.org>, Cedric Sohrauer <sohrauer@googlemail.com>
Category: common
*/

function(hljs) {
  var RUBY_METHOD_RE = '[a-zA-Z_]\\w*[!?=]?|[-+~]\\@|<<|>>|=~|===?|<=>|[<>]=?|\\*\\*|[-/+%^&*~`|]|\\[\\]=?';
  var RUBY_KEYWORDS = {
    keyword:
      'and then defined module in return redo if BEGIN retry end for self when ' +
      'next until do begin unless END rescue else break undef not super class case ' +
      'require yield alias while ensure elsif or include attr_reader attr_writer attr_accessor',
    literal:
      'true false nil'
  };
  var YARDOCTAG = {
    className: 'doctag',
    begin: '@[A-Za-z]+'
  };
  var IRB_OBJECT = {
    begin: '#<', end: '>'
  };
  var COMMENT_MODES = [
    hljs.COMMENT(
      '#',
      '$',
      {
        contains: [YARDOCTAG]
      }
    ),
    hljs.COMMENT(
      '^\\=begin',
      '^\\=end',
      {
        contains: [YARDOCTAG],
        relevance: 10
      }
    ),
    hljs.COMMENT('^__END__', '\\n$')
  ];
  var SUBST = {
    className: 'subst',
    begin: '#\\{', end: '}',
    keywords: RUBY_KEYWORDS
  };
  var STRING = {
    className: 'string',
    contains: [hljs.BACKSLASH_ESCAPE, SUBST],
    variants: [
      {begin: /'/, end: /'/},
      {begin: /"/, end: /"/},
      {begin: /`/, end: /`/},
      {begin: '%[qQwWx]?\\(', end: '\\)'},
      {begin: '%[qQwWx]?\\[', end: '\\]'},
      {begin: '%[qQwWx]?{', end: '}'},
      {begin: '%[qQwWx]?<', end: '>'},
      {begin: '%[qQwWx]?/', end: '/'},
      {begin: '%[qQwWx]?%', end: '%'},
      {begin: '%[qQwWx]?-', end: '-'},
      {begin: '%[qQwWx]?\\|', end: '\\|'},
      {
        // \B in the beginning suppresses recognition of ?-sequences where ?
        // is the last character of a preceding identifier, as in: `func?4`
        begin: /\B\?(\\\d{1,3}|\\x[A-Fa-f0-9]{1,2}|\\u[A-Fa-f0-9]{4}|\\?\S)\b/
      },
      {
        begin: /<<(-?)\w+$/, end: /^\s*\w+$/,
      }
    ]
  };
  var PARAMS = {
    className: 'params',
    begin: '\\(', end: '\\)', endsParent: true,
    keywords: RUBY_KEYWORDS
  };

  var RUBY_DEFAULT_CONTAINS = [
    STRING,
    IRB_OBJECT,
    {
      className: 'class',
      beginKeywords: 'class module', end: '$|;',
      illegal: /=/,
      contains: [
        hljs.inherit(hljs.TITLE_MODE, {begin: '[A-Za-z_]\\w*(::\\w+)*(\\?|\\!)?'}),
        {
          begin: '<\\s*',
          contains: [{
            begin: '(' + hljs.IDENT_RE + '::)?' + hljs.IDENT_RE
          }]
        }
      ].concat(COMMENT_MODES)
    },
    {
      className: 'function',
      beginKeywords: 'def', end: '$|;',
      contains: [
        hljs.inherit(hljs.TITLE_MODE, {begin: RUBY_METHOD_RE}),
        PARAMS
      ].concat(COMMENT_MODES)
    },
    {
      // swallow namespace qualifiers before symbols
      begin: hljs.IDENT_RE + '::'
    },
    {
      className: 'symbol',
      begin: hljs.UNDERSCORE_IDENT_RE + '(\\!|\\?)?:',
      relevance: 0
    },
    {
      className: 'symbol',
      begin: ':(?!\\s)',
      contains: [STRING, {begin: RUBY_METHOD_RE}],
      relevance: 0
    },
    {
      className: 'number',
      begin: '(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b',
      relevance: 0
    },
    {
      begin: '(\\$\\W)|((\\$|\\@\\@?)(\\w+))' // variables
    },
    {
      className: 'params',
      begin: /\|/, end: /\|/,
      keywords: RUBY_KEYWORDS
    },
    { // regexp container
      begin: '(' + hljs.RE_STARTERS_RE + '|unless)\\s*',
      keywords: 'unless',
      contains: [
        IRB_OBJECT,
        {
          className: 'regexp',
          contains: [hljs.BACKSLASH_ESCAPE, SUBST],
          illegal: /\n/,
          variants: [
            {begin: '/', end: '/[a-z]*'},
            {begin: '%r{', end: '}[a-z]*'},
            {begin: '%r\\(', end: '\\)[a-z]*'},
            {begin: '%r!', end: '![a-z]*'},
            {begin: '%r\\[', end: '\\][a-z]*'}
          ]
        }
      ].concat(COMMENT_MODES),
      relevance: 0
    }
  ].concat(COMMENT_MODES);

  SUBST.contains = RUBY_DEFAULT_CONTAINS;
  PARAMS.contains = RUBY_DEFAULT_CONTAINS;

  var SIMPLE_PROMPT = "[>?]>";
  var DEFAULT_PROMPT = "[\\w#]+\\(\\w+\\):\\d+:\\d+>";
  var RVM_PROMPT = "(\\w+-)?\\d+\\.\\d+\\.\\d(p\\d+)?[^>]+>";

  var IRB_DEFAULT = [
    {
      begin: /^\s*=>/,
      starts: {
        end: '$', contains: RUBY_DEFAULT_CONTAINS
      }
    },
    {
      className: 'meta',
      begin: '^('+SIMPLE_PROMPT+"|"+DEFAULT_PROMPT+'|'+RVM_PROMPT+')',
      starts: {
        end: '$', contains: RUBY_DEFAULT_CONTAINS
      }
    }
  ];

  return {
    aliases: ['rb', 'gemspec', 'podspec', 'thor', 'irb'],
    keywords: RUBY_KEYWORDS,
    illegal: /\/\*/,
    contains: COMMENT_MODES.concat(IRB_DEFAULT).concat(RUBY_DEFAULT_CONTAINS)
  };
}
<|endoftext|>


<commit_before>import PropTypes from 'prop-types';
import React from 'react';

/**
 * The partial component
 *
 * @disable-docs
 */
const Partial = ( page ) => (

					{ page._body }

);

Partial.propTypes = {
	/**
	 * _body: (partials)(4)
	 */
	_body: PropTypes.node.isRequired,
};

Partial.defaultProps = {};

export default Partial;
<commit_msg>remove layout formatting from partial. We need it to be clean for complex components that involve multiple markdown files e.g. TopicTakeaway<commit_after>import PropTypes from 'prop-types';
import React from 'react';

/**
 * The partial component
 *
 * @disable-docs
 */
const Partial = ( page ) => (

				{ page._body }

);

Partial.propTypes = {
	/**
	 * _body: (partials)(4)
	 */
	_body: PropTypes.node.isRequired,
};

Partial.defaultProps = {};

export default Partial;
<|endoftext|>


<commit_before>import { curryN, not, pipe } from 'ramda';

import lensSatisfies from './lensSatisfies';

/**
 * Returns `true` if data structure focused by by the given lens doesn't satisfy the predicate.
 * Note that the predicate is expected to return boolean value.
 *
 * @func lensNotSatisfy
 * @memberOf RA
 * @since {@link https://char0n.github.io/ramda-adjunct/1.13.0|1.13.0}
 * @category Relation
 * @sig  Boolean b => (a -> b) -> Lens s a -> s -> b
  @see {@link RA.lensSatisfies|lensNotSatisfies}
 * @param {Function} predicate The predicate function
 * @param {Function} lens Van Laarhoven lens
 * @param {*} data The data structure
 * @return {Boolean} `false` if the focused data structure satisfies the predicate, `true` otherwise
 *
 * @example
 *
 * RA.lensNotSatisfies(R.equals(true), R.lensIndex(0), [false, true, 1]); // => true
 * RA.lensNotSatisfies(R.equals(true), R.lensIndex(1), [false, true, 1]); // => false
 * RA.lensNotSatisfies(R.equals(true), R.lensIndex(2), [false, true, 1]); // => true
 * RA.lensNotSatisfies(R.identity, R.lensProp('x'), { x: 1 }); // => true
 */
const lensNotSatisfies = curryN(3, pipe(lensSatisfies, not));

export default lensNotSatisfies;
<commit_msg>docs(lensNotSatisfy): fix typo in docstring<commit_after>import { curryN, not, pipe } from 'ramda';

import lensSatisfies from './lensSatisfies';

/**
 * Returns `true` if data structure focused by by the given lens doesn't satisfy the predicate.
 * Note that the predicate is expected to return boolean value.
 *
 * @func lensNotSatisfy
 * @memberOf RA
 * @since {@link https://char0n.github.io/ramda-adjunct/1.13.0|1.13.0}
 * @category Relation
 * @sig  Boolean b => (a -> b) -> Lens s a -> s -> b
 * @see {@link RA.lensSatisfies|lensNotSatisfies}
 * @param {Function} predicate The predicate function
 * @param {Function} lens Van Laarhoven lens
 * @param {*} data The data structure
 * @return {Boolean} `false` if the focused data structure satisfies the predicate, `true` otherwise
 *
 * @example
 *
 * RA.lensNotSatisfies(R.equals(true), R.lensIndex(0), [false, true, 1]); // => true
 * RA.lensNotSatisfies(R.equals(true), R.lensIndex(1), [false, true, 1]); // => false
 * RA.lensNotSatisfies(R.equals(true), R.lensIndex(2), [false, true, 1]); // => true
 * RA.lensNotSatisfies(R.identity, R.lensProp('x'), { x: 1 }); // => true
 */
const lensNotSatisfies = curryN(3, pipe(lensSatisfies, not));

export default lensNotSatisfies;
<|endoftext|>


<commit_before>
module.exports = get

var fs = require("graceful-fs")
  , path = require("path")
  , mkdir = require("mkdirp")
  , chownr = require("chownr")

function get (uri, timeout, nofollow, staleOk, cb) {
  if (typeof cb !== "function") cb = staleOk, staleOk = false
  if (typeof cb !== "function") cb = nofollow, nofollow = false
  if (typeof cb !== "function") cb = timeout, timeout = -1
  if (typeof cb !== "function") cb = version, version = null

  timeout = Math.min(timeout, this.conf.get('cache-max') || 0)
  timeout = Math.max(timeout, this.conf.get('cache-min') || -Infinity)

  if (!this.conf.get('registry')) timeout = Infinity

  if ( process.env.COMP_CWORD !== undefined
    && process.env.COMP_LINE !== undefined
    && process.env.COMP_POINT !== undefined
    ) timeout = Math.max(timeout, 60000)

  // /-/all is special.
  // It uses timestamp-based caching and partial updates,
  // because it is a monster.
  if (uri === "/-/all") {
    return requestAll.call(this, cb)
  }

  var cacheUri = uri
  // on windows ":" is not an allowed character in a foldername
  cacheUri = cacheUri.replace(/:/g, '_').replace(/\?write=true$/, '')
  var cache = path.join(this.conf.get('cache'), cacheUri, ".cache.json")

  // If the GET is part of a write operation (PUT or DELETE), then
  // skip past the cache entirely, but still save the results.
  if (uri.match(/\?write=true$/))
    return get_.call(this, uri, timeout, cache, null, null, nofollow, staleOk, cb)

  fs.stat(cache, function (er, stat) {
    if (!er) fs.readFile(cache, function (er, data) {
      try { data = JSON.parse(data) }
      catch (ex) { data = null }
      get_.call(this, uri, timeout, cache, stat, data, nofollow, staleOk, cb)
    }.bind(this))
    else get_.call(this, uri, timeout, cache, null, null, nofollow, staleOk, cb)
  }.bind(this))
}

function requestAll (cb) {
  var cache = path.join(this.conf.get('cache'), "/-/all", ".cache.json")

  mkdir(path.join(this.conf.get('cache'), "-", "all"), function (er) {
    fs.readFile(cache, function (er, data) {
      if (er) return requestAll_.call(this, 0, {}, cb)
      try {
        data = JSON.parse(data)
      } catch (ex) {
        fs.writeFile(cache, "{}", function (er) {
          if (er) return cb(new Error("Broken cache."))
          return requestAll_.call(this, 0, {}, cb)
        }.bind(this))
      }
      var t = +data._updated || 0
      requestAll_.call(this, t, data, cb)
    }.bind(this))
  }.bind(this))
}

function requestAll_ (c, data, cb) {
  // use the cache and update in the background if it's not too old
  if (Date.now() - c < 60000) {
    cb(null, data)
    cb = function () {}
  }

  var uri = "/-/all/since?stale=update_after&startkey=" + c

  if (c === 0) {
    this.log.warn("", "Building the local index for the first time, please be patient")
    uri = "/-/all"
  }

  var cache = path.join(this.conf.get('cache'), "-/all", ".cache.json")
  this.request('GET', uri, function (er, updates, _, res) {
    if (er) return cb(er, data)
    var headers = res.headers
      , updated = updates._updated || Date.parse(headers.date)
    Object.keys(updates).forEach(function (p) {
      data[p] = updates[p]
    })
    data._updated = updated
    fs.writeFile( cache, JSON.stringify(data)
                , function (er) {
      delete data._updated
      return cb(er, data)
    })
  })
}

function get_ (uri, timeout, cache, stat, data, nofollow, staleOk, cb) {
  var etag
  if (data && data._etag) etag = data._etag
  if (timeout && timeout > 0 && stat && data) {
    if ((Date.now() - stat.mtime.getTime())/1000 < timeout) {
      this.log.verbose("registry.get", uri, "not expired, no request")
      delete data._etag
      return cb(null, data, JSON.stringify(data), {statusCode:304})
    }
    if (staleOk) {
      this.log.verbose("registry.get", uri, "staleOk, background update")
      delete data._etag
      process.nextTick(cb.bind( null, null, data, JSON.stringify(data)
                              , {statusCode: 304} ))
      cb = function () {}
    }
  }

  this.request('GET', uri, null, etag, nofollow, function (er, remoteData, raw, response) {
    // if we get an error talking to the registry, but we have it
    // from the cache, then just pretend we got it.
    if (er && cache && data && !data.error) {
      er = null
      response = {statusCode: 304}
    }

    if (response) {
      this.log.silly("registry.get", "cb", [response.statusCode, response.headers])
      if (response.statusCode === 304 && etag) {
        remoteData = data
        this.log.verbose("etag", uri+" from cache")
      }
    }

    data = remoteData
    if (!data) {
      er = er || new Error("failed to fetch from registry: " + uri)
    }

    if (er) return cb(er, data, raw, response)

    // just give the write the old college try.  if it fails, whatever.
    function saved () {
      delete data._etag
      cb(er, data, raw, response)
    }

    saveToCache.call(this, cache, data, saved)
  }.bind(this))
}

function saveToCache (cache, data, saved) {
  if (this._cacheStat) {
    var cs = this._cacheStat
    return saveToCache_.call(this, cache, data, cs.uid, cs.gid, saved)
  }
  fs.stat(this.conf.get('cache'), function (er, st) {
    if (er) {
      return fs.stat(process.env.HOME || "", function (er, st) {
        // if this fails, oh well.
        if (er) return saved()
        this._cacheStat = st
        return saveToCache.call(this, cache, data, saved)
      }.bind(this))
    }
    this._cacheStat = st || { uid: null, gid: null }
    return saveToCache.call(this, cache, data, saved)
  }.bind(this))
}

function saveToCache_ (cache, data, uid, gid, saved) {
  mkdir(path.dirname(cache), function (er, made) {
    if (er) return saved()
    fs.writeFile(cache, JSON.stringify(data), function (er) {
      if (er || uid === null || gid === null) {
        return saved()
      }
      chownr(made || cache, uid, gid, saved)
    })
  })
}
<commit_msg>Name the cache file with registry info<commit_after>
module.exports = get

var fs = require("graceful-fs")
  , url = require("url")
  , path = require("path")
  , mkdir = require("mkdirp")
  , chownr = require("chownr")

function get (uri, timeout, nofollow, staleOk, cb) {
  if (typeof cb !== "function") cb = staleOk, staleOk = false
  if (typeof cb !== "function") cb = nofollow, nofollow = false
  if (typeof cb !== "function") cb = timeout, timeout = -1
  if (typeof cb !== "function") cb = version, version = null

  timeout = Math.min(timeout, this.conf.get('cache-max') || 0)
  timeout = Math.max(timeout, this.conf.get('cache-min') || -Infinity)

  if (!this.conf.get('registry')) timeout = Infinity

  if ( process.env.COMP_CWORD !== undefined
    && process.env.COMP_LINE !== undefined
    && process.env.COMP_POINT !== undefined
    ) timeout = Math.max(timeout, 60000)

  // /-/all is special.
  // It uses timestamp-based caching and partial updates,
  // because it is a monster.
  if (uri === "/-/all") {
    return requestAll.call(this, cb)
  }

  var cacheUri = uri
  // on windows ":" is not an allowed character in a foldername
  cacheUri = cacheUri.replace(/:/g, '_').replace(/\?write=true$/, '')
  var cache = path.join(this.conf.get('cache'), cacheUri, getCacheFile.call(this))

  // If the GET is part of a write operation (PUT or DELETE), then
  // skip past the cache entirely, but still save the results.
  if (uri.match(/\?write=true$/))
    return get_.call(this, uri, timeout, cache, null, null, nofollow, staleOk, cb)

  fs.stat(cache, function (er, stat) {
    if (!er) fs.readFile(cache, function (er, data) {
      try { data = JSON.parse(data) }
      catch (ex) { data = null }
      get_.call(this, uri, timeout, cache, stat, data, nofollow, staleOk, cb)
    }.bind(this))
    else get_.call(this, uri, timeout, cache, null, null, nofollow, staleOk, cb)
  }.bind(this))
}

function requestAll (cb) {
  var cache = path.join(this.conf.get('cache'), "/-/all", getCacheFile.call(this))
  mkdir(path.join(this.conf.get('cache'), "-", "all"), function (er) {
    fs.readFile(cache, function (er, data) {
      if (er) return requestAll_.call(this, 0, {}, cb)
      try {
        data = JSON.parse(data)
      } catch (ex) {
        fs.writeFile(cache, "{}", function (er) {
          if (er) return cb(new Error("Broken cache."))
          return requestAll_.call(this, 0, {}, cb)
        }.bind(this))
      }
      var t = +data._updated || 0
      requestAll_.call(this, t, data, cb)
    }.bind(this))
  }.bind(this))
}

function requestAll_ (c, data, cb) {
  // use the cache and update in the background if it's not too old
  if (Date.now() - c < 60000) {
    cb(null, data)
    cb = function () {}
  }

  var uri = "/-/all/since?stale=update_after&startkey=" + c

  if (c === 0) {
    this.log.warn("", "Building the local index for the first time, please be patient")
    uri = "/-/all"
  }

  var cache = path.join(this.conf.get('cache'), "-/all", getCacheFile.call(this))
  this.request('GET', uri, function (er, updates, _, res) {
    if (er) return cb(er, data)
    var headers = res.headers
      , updated = updates._updated || Date.parse(headers.date)
    Object.keys(updates).forEach(function (p) {
      data[p] = updates[p]
    })
    data._updated = updated
    fs.writeFile( cache, JSON.stringify(data)
                , function (er) {
      delete data._updated
      return cb(er, data)
    })
  })
}

function get_ (uri, timeout, cache, stat, data, nofollow, staleOk, cb) {
  var etag
  if (data && data._etag) etag = data._etag
  if (timeout && timeout > 0 && stat && data) {
    if ((Date.now() - stat.mtime.getTime())/1000 < timeout) {
      this.log.verbose("registry.get", uri, "not expired, no request")
      delete data._etag
      return cb(null, data, JSON.stringify(data), {statusCode:304})
    }
    if (staleOk) {
      this.log.verbose("registry.get", uri, "staleOk, background update")
      delete data._etag
      process.nextTick(cb.bind( null, null, data, JSON.stringify(data)
                              , {statusCode: 304} ))
      cb = function () {}
    }
  }

  this.request('GET', uri, null, etag, nofollow, function (er, remoteData, raw, response) {
    // if we get an error talking to the registry, but we have it
    // from the cache, then just pretend we got it.
    if (er && cache && data && !data.error) {
      er = null
      response = {statusCode: 304}
    }

    if (response) {
      this.log.silly("registry.get", "cb", [response.statusCode, response.headers])
      if (response.statusCode === 304 && etag) {
        remoteData = data
        this.log.verbose("etag", uri+" from cache")
      }
    }

    data = remoteData
    if (!data) {
      er = er || new Error("failed to fetch from registry: " + uri)
    }

    if (er) return cb(er, data, raw, response)

    // just give the write the old college try.  if it fails, whatever.
    function saved () {
      delete data._etag
      cb(er, data, raw, response)
    }

    saveToCache.call(this, cache, data, saved)
  }.bind(this))
}

function getCacheFile() {
  var registry = this.conf.get('registry') || ''
  registry = url.parse(registry).host;
  return !registry || registry === "registry.npmjs.org" ?
    ".cache.json" : "." + registry + ".cache.json"
}

function saveToCache (cache, data, saved) {
  if (this._cacheStat) {
    var cs = this._cacheStat
    return saveToCache_.call(this, cache, data, cs.uid, cs.gid, saved)
  }
  fs.stat(this.conf.get('cache'), function (er, st) {
    if (er) {
      return fs.stat(process.env.HOME || "", function (er, st) {
        // if this fails, oh well.
        if (er) return saved()
        this._cacheStat = st
        return saveToCache.call(this, cache, data, saved)
      }.bind(this))
    }
    this._cacheStat = st || { uid: null, gid: null }
    return saveToCache.call(this, cache, data, saved)
  }.bind(this))
}

function saveToCache_ (cache, data, uid, gid, saved) {
  mkdir(path.dirname(cache), function (er, made) {
    if (er) return saved()
    fs.writeFile(cache, JSON.stringify(data), function (er) {
      if (er || uid === null || gid === null) {
        return saved()
      }
      chownr(made || cache, uid, gid, saved)
    })
  })
}
<|endoftext|>


<commit_before>/*
 * Copyright 2013-2015, All Rights Reserved.
 *
 * Code licensed under the BSD License:
 * https://github.com/node-gh/gh/blob/master/LICENSE.md
 *
 * @author Eduardo Lundgren <edu@rdo.io>
 */

'use strict';

var logger = require('./logger'),
    exec = require('./exec'),
    git_command = process.env.GH_GIT_COMMAND || 'git';

exports.checkout = function(branch, newBranch) {
    var args = ['checkout', branch];

    if (newBranch) {
        args.push('-B', newBranch);
    }

    return exec.spawnSyncStream(git_command, args);
};

exports.clone = function(url, folder) {
    var args = ['clone', url];

    if (folder) {
        args.push(folder);
    }

    return exec.spawnSyncStream(git_command, args);
};

exports.merge = function(branch, rebase, abort) {
    var type = rebase ? 'rebase' : 'merge',
        res;

    try {
        res = exec.spawnSyncStream(git_command, [type, branch]);
    } catch(err) {
        if (!abort && err.code && err.code !== 0) {
            throw err;
        }

        exec.spawnSyncStream(git_command, [type, '--abort']);
    }
};

exports.push = function(remote, branch) {
    var args = ['push', remote];

    if (branch) {
        args.push(branch);
    }

    return exec.spawnSyncStream(git_command, args);
};

exports.fetch = function(repoUrl, headBranch, pullBranch) {
    var args = ['fetch', repoUrl, headBranch + ':' + pullBranch];

    return exec.spawnSyncStream(git_command, args);
};

exports.countUserAdjacentCommits = function() {
    var git,
        params,
        commits = 0,
        user = exports.getConfig('user.name'),
        author;

    do {
        params = ['log', '-1', '--skip=' + commits, '--pretty=%an'];
        git = exec.spawnSync(git_command, params);

        if (git.status !== 0) {
            logger.error(git.stderr);
        }

        author = git.stdout;

        commits += 1;
    } while (author === user);

    commits -= 1;

    return commits;
};

exports.deleteBranch = function(branch) {
    var git = exec.spawnSync(git_command, ['branch', '-d', branch]);

    if (git.status !== 0) {
        logger.warn(git.stderr);
    }

    return git.stdout;
};

exports.findRoot = function() {
    return exec.spawnSync(git_command, ['rev-parse', '--show-toplevel']).stdout;
};

exports.getCommitMessage = function(branch, number) {
    var git,
        params = ['log'];

    if (!number) {
        number = 1;
    }

    params.push('-' + number, '--first-parent', '--no-merges', '--pretty=%s');

    if (branch) {
        params.push(branch);
    }

    params.push('--');

    git = exec.spawnSync(git_command, params);

    if (git.status !== 0) {
        logger.warn(git.stderr);
        throw new Error('Can\'t retrieve commit message.');
    }

    return git.stdout;
};

exports.getConfig = function(key) {
    var git = exec.spawnSync(git_command, ['config', '--get', key]);

    if (git.status !== 0) {
        throw new Error('No git config found for ' + key + '\n');
    }

    return git.stdout;
};

exports.getCurrentBranch = function() {
    var git = exec.spawnSync(git_command, ['symbolic-ref', 'HEAD']);

    if (git.status !== 0) {
        return;
    }

    return git.stdout.substring(git.stdout.lastIndexOf('/') + 1);
};

exports.getLastCommitMessage = function(opt_branch) {
    return exports.getCommitMessage(opt_branch, 1);
};

exports.getLastCommitSHA = function() {
    var git = exec.spawnSync(git_command, ['rev-parse', '--short', 'HEAD']);

    if (git.status !== 0) {
        throw new Error('Can\'t retrieve last commit.');
    }

    return git.stdout;
};

exports.getRemoteUrl = function(remote) {
    try {
        return exports.getConfig('remote.' + remote + '.url');
    }
    catch(e) {
        return;
    }
};

exports.getRepoFromRemoteURL = function(url) {
    var parsed = exports.parseRemoteUrl(url);

    return parsed && parsed[1];
};

exports.getUserFromRemoteUrl = function(url) {
    var parsed = exports.parseRemoteUrl(url);

    return parsed && parsed[0];
};

exports.getRepo = function(remote) {
    return exports.getRepoFromRemoteURL(exports.getRemoteUrl(remote));
};

exports.getUser = function(remote) {
    return exports.getUserFromRemoteUrl(exports.getRemoteUrl(remote));
};

exports.parseRemoteUrl = function(url) {
    var parsed = /[\/:]([\w-]+)\/(.*?)(?:\.git)?$/.exec(url);

    if (parsed) {
        parsed.shift();
    }

    return parsed;
};
<commit_msg>Source formatting.<commit_after>/*
 * Copyright 2013-2015, All Rights Reserved.
 *
 * Code licensed under the BSD License:
 * https://github.com/node-gh/gh/blob/master/LICENSE.md
 *
 * @author Eduardo Lundgren <edu@rdo.io>
 */

'use strict';

var logger = require('./logger'),
    exec = require('./exec'),
    git_command = process.env.GH_GIT_COMMAND || 'git';

exports.checkout = function(branch, newBranch) {
    var args = ['checkout', branch];

    if (newBranch) {
        args.push('-B', newBranch);
    }

    return exec.spawnSyncStream(git_command, args);
};

exports.clone = function(url, folder) {
    var args = ['clone', url];

    if (folder) {
        args.push(folder);
    }

    return exec.spawnSyncStream(git_command, args);
};

exports.merge = function(branch, rebase, abort) {
    var type = rebase ? 'rebase' : 'merge',
        res;

    try {
        res = exec.spawnSyncStream(git_command, [type, branch]);
    } catch(err) {
        if (!abort && err.code && err.code !== 0) {
            throw err;
        }

        exec.spawnSyncStream(git_command, [type, '--abort']);
    }
};

exports.push = function(remote, branch) {
    var args = ['push', remote];

    if (branch) {
        args.push(branch);
    }

    return exec.spawnSyncStream(git_command, args);
};

exports.fetch = function(repoUrl, headBranch, pullBranch) {
    var args = ['fetch', repoUrl, headBranch + ':' + pullBranch];

    return exec.spawnSyncStream(git_command, args);
};

exports.countUserAdjacentCommits = function() {
    var git,
        params,
        commits = 0,
        user = exports.getConfig('user.name'),
        author;

    do {
        params = ['log', '-1', '--skip=' + commits, '--pretty=%an'];
        git = exec.spawnSync(git_command, params);

        if (git.status !== 0) {
            logger.error(git.stderr);
        }

        author = git.stdout;

        commits += 1;
    } while (author === user);

    commits -= 1;

    return commits;
};

exports.deleteBranch = function(branch) {
    var git = exec.spawnSync(git_command, ['branch', '-d', branch]);

    if (git.status !== 0) {
        logger.warn(git.stderr);
    }

    return git.stdout;
};

exports.findRoot = function() {
    return exec.spawnSync(git_command, ['rev-parse', '--show-toplevel']).stdout;
};

exports.getCommitMessage = function(branch, number) {
    var git,
        params = ['log'];

    if (!number) {
        number = 1;
    }

    params.push('-' + number, '--first-parent', '--no-merges', '--pretty=%s');

    if (branch) {
        params.push(branch);
    }

    params.push('--');

    git = exec.spawnSync(git_command, params);

    if (git.status !== 0) {
        logger.warn(git.stderr);
        throw new Error('Can\'t retrieve commit message.');
    }

    return git.stdout;
};

exports.getConfig = function(key) {
    var git = exec.spawnSync(git_command, ['config', '--get', key]);

    if (git.status !== 0) {
        throw new Error('No git config found for ' + key + '\n');
    }

    return git.stdout;
};

exports.getCurrentBranch = function() {
    var git = exec.spawnSync(git_command, ['symbolic-ref', 'HEAD']);

    if (git.status !== 0) {
        return;
    }

    return git.stdout.substring(git.stdout.lastIndexOf('/') + 1);
};

exports.getLastCommitMessage = function(branch) {
    return exports.getCommitMessage(branch, 1);
};

exports.getLastCommitSHA = function() {
    var git = exec.spawnSync(git_command, ['rev-parse', '--short', 'HEAD']);

    if (git.status !== 0) {
        throw new Error('Can\'t retrieve last commit.');
    }

    return git.stdout;
};

exports.getRemoteUrl = function(remote) {
    try {
        return exports.getConfig('remote.' + remote + '.url');
    }
    catch(e) {
        return;
    }
};

exports.getRepoFromRemoteURL = function(url) {
    var parsed = exports.parseRemoteUrl(url);

    return parsed && parsed[1];
};

exports.getUserFromRemoteUrl = function(url) {
    var parsed = exports.parseRemoteUrl(url);

    return parsed && parsed[0];
};

exports.getRepo = function(remote) {
    return exports.getRepoFromRemoteURL(exports.getRemoteUrl(remote));
};

exports.getUser = function(remote) {
    return exports.getUserFromRemoteUrl(exports.getRemoteUrl(remote));
};

exports.parseRemoteUrl = function(url) {
    var parsed = /[\/:]([\w-]+)\/(.*?)(?:\.git)?$/.exec(url);

    if (parsed) {
        parsed.shift();
    }

    return parsed;
};
<|endoftext|>