<commit_before>'use strict';

var path              = require('path'),
    fs                = require('fs'),
    through           = require('through2'),
    sass              = require('node-sass'),
    gutil             = require('gulp-util'),
    slash             = require('gulp-slash'),
    rework            = require('rework'),
    visit             = require('rework-visit'),
    convert           = require('convert-source-map'),
    SourceMapConsumer = require('source-map').SourceMapConsumer,
    mime              = require('mime');

/**
 * Search for the relative file reference from the startPath up to the process
 * working directory, avoiding any other directories with a package.json or bower.json.
 * @param {string} startPath The location of the uri declaration and the place to start the search from
 * @param {string} uri The content of the url() statement, expected to be a relative file path
 * @returns {string} dataURI of the file where found or undefined otherwise
 */
function encodeRelativeURL(startPath, uri) {

  /**
   * Test whether the given directory is the root of its own package
   * @param {string} absolutePath An absolute path
   * @returns {boolean} True where a package.json or bower.json exists, else False
   */
  function notPackage(absolutePath) {
    return ['package.json', 'bower.json'].every(function fileNotFound(file) {
        return !(fs.existsSync(path.resolve(absolutePath, file)));
      });
  }

  // ignore data uris and ensure we are at a valid start path
  var absoluteStart = !(/^data\:/.test(uri)) && path.resolve(startPath);
  if (absoluteStart) {

    // find path to the root, stopping at cwd, package.json or bower.json
    var pathToRoot = [ ];
    do {
      pathToRoot.push(absoluteStart);
      var isWorking = (absoluteStart !== process.cwd()) && notPackage(absoluteStart);
      absoluteStart = path.resolve(absoluteStart, '..');
    } while (isWorking);

    // start a queue with the path to the root
    var queue = pathToRoot.concat();

    // process the queue until empty
    //  the queue pattern ensures that we favour paths closest the the start path
    while (queue.length) {

      // shift the first item off the queue, consider it the base for our relative uri
      var basePath = queue.shift();
      var fullPath = path.resolve(basePath, uri);

      // file exists so convert to a dataURI and end
      if (fs.existsSync(fullPath)) {
        var type     = mime.lookup(fullPath);
        var contents = fs.readFileSync(fullPath);
        var base64   = new Buffer(contents).toString('base64');
        return 'url(data:' + type + ';base64,' + base64 + ')';
      }
      // enqueue subdirectories that are not packages and are not in the root path
      else {
        fs.readdirSync(basePath)
          .filter(function notHidden(filename) {
            return (filename.charAt(0) !== '.');
          })
          .map(function toAbsolute(filename) {
            return path.join(basePath, filename);
          })
          .filter(function directoriesOnly(absolutePath) {
            return fs.statSync(absolutePath).isDirectory();
          })
          .filter(function notInRootPath(absolutePath) {
            return (pathToRoot.indexOf(absolutePath) < 0);
          })
          .filter(notPackage)
          .forEach(function enqueue(absolutePath) {
            queue.push(absolutePath);
          });
      }
    }
  }
}

/**
 * Use node-sass to compile the files of the input stream.
 * Outputs a stream of compiled files and their source-maps, alternately.
 * @see https://github.com/sass/node-sass#outputstyle
 * @param {Array.<string>} [libraryPaths] Any number of library path strings
 * @returns {stream.Through} A through stream that performs the operation of a gulp stream
 */
module.exports = function (bannerWidth, libraryPaths) {
  var output  = [ ];
  var libList = (libraryPaths || [ ]).filter(function isString(value) {
    return (typeof value === 'string');
  });
  return through.obj(function (file, encoding, done) {
    var stream = this;

    // setup parameters
    var sourcePath = file.path.replace(path.basename(file.path), '');
    var sourceName = path.basename(file.path, path.extname(file.path));
    var mapName    = sourceName + '.css.map';
    var sourceMapConsumer;

    /**
     * Push file contents to the output stream.
     * @param {string} ext The extention for the file, including dot
     * @param {string|object?} contents The contents for the file or fields to assign to it
     * @return {vinyl.File} The file that has been pushed to the stream
     */
    function pushResult(ext, contents) {
      var pending = new gutil.File({
        cwd:      file.cwd,
        base:     file.base,
        path:     sourcePath + sourceName + ext,
        contents: (typeof contents === 'string') ? new Buffer(contents) : null
      });
      if (typeof contents === 'object') {
        for (var key in contents) {
          pending[key] = contents[key];
        }
      }
      stream.push(pending);
      return pending;
    }

    /**
     * Plugin for css rework that follows SASS transpilation
     * @param {object} stylesheet AST for the CSS output from SASS
     */
    function reworkPlugin(stylesheet) {

      // visit each node (selector) in the stylesheet recursively using the official utility method
      visit(stylesheet, function (declarations, node) {

        // each node may have multiple declarations
        declarations.forEach(function (declaration) {

          // reverse the original source-map to find the original sass file
          var cssStart  = declaration.position.start;
          var sassStart = sourceMapConsumer.originalPositionFor({
            line:   cssStart.line,
            column: cssStart.column
          });
          if (!sassStart.source) {
            throw new Error('failed to decode node-sass source map'); // this can occur with regressions in libsass
          }
          var sassDir = path.dirname(sassStart.source);

          // allow multiple url() values in the declaration
          //  the uri will be every second value (i % 2)
          declaration.value = declaration.value
            .split(/url\s*\(\s*['"]?([^'"?#]*)[^)]*\)/g)  // split by url statements
            .map(function (token, i) {
              return (i % 2) ? (encodeRelativeURL(sassDir, token) || ('url(' + token + ')')) : token;
            }).join('');
        });
      });
    }

    /**
     * Handler for successful transpilation using node-sass.
     * This functions gets called with an object containing a CSS file and its source-map,
     * which is modified and passed through CSS rework, before being pushed to the results.
     * @param {string} css Compiled css
     * @param {string} map The source-map for the compiled css
     */
    function successHandler(css, map) {

      // adjust source-map
      var sourceMap = convert.fromJSON(map).toObject();
      sourceMap.sources.forEach(function (value, i, array) {
        array[i] = path.resolve(value.replace(/^\//, '').replace(/\b\/+\b/g, '/'));  // ensure single slash absolute
      });

      // prepare the adjusted sass source-map for later look-ups
      sourceMapConsumer = new SourceMapConsumer(sourceMap);

      // embed sourcemap in css
      var cssWithMap = css.replace(
        /\/\*#\s*sourceMappingURL=[^*]*\*\//m,
        '/*# sourceMappingURL=data:application/json;base64,' + convert.fromObject(sourceMap).toBase64() + ' */'
      );

      // rework css
      var reworked = rework(cssWithMap, '')
        .use(reworkPlugin)
        .toString({
          sourcemap        : true,
          sourcemapAsObject: true
        });

      // adjust overall sourcemap
      delete reworked.map.file;
      delete reworked.map.sourcesContent;
      reworked.map.sources.forEach(function (value, i, array) {
        array[i] = '/' + slash(path.relative(process.cwd(), value));   // ensure root relative
      });

      // write stream output
      pushResult('.css', reworked.code + '\n/*# sourceMappingURL=' + mapName  + ' */');
      pushResult('.css.map', JSON.stringify(reworked.map, null, 2));
      done();
    }

    /**
     * Handler for error in node-sass.
     * @param {string} error The error text from node-sass
     */
    function errorHandler(error) {
      var analysis = /(.*)\:(\d+)\:\s*error\:\s*(.*)/.exec(error);
      var resolved = path.resolve(analysis[1]);
      var filename = [ '.scss', '.css']
        .map(function (ext) {
          return resolved + ext;
        })
        .filter(function (fullname) {
          return fs.existsSync(fullname);
        })
        .pop();
      var message  = analysis ?
        ((filename || resolved) + ':' + analysis[2] + ':0: ' + analysis[3] + '\n') :
        ('TODO parse this error\n' + error + '\n');
      if (output.indexOf(message) < 0) {
        output.push(message);
      }
      done();
    }

    /**
     * Perform the sass render with the given sourceMap, error, and success
     * parameters.
     * @param {string|boolean} map The source map filename or false for none
     * @param {function ({string})} error Handler for error
     * @param {function ({string}, {string})} success Handler for success
     */
    function render(map, error, success) {
      sass.render({
        file        : file.path,
        data        : file.contents.toString(),
        success     : success,
        error       : error,
        includePaths: libList,
        outputStyle : 'compressed',
        stats       : { },
        sourceMap   : map
      });
    }

    // run first without source-map as this can cause process exit where errors exist
    render(false, errorHandler, function () {
      render(mapName, errorHandler, successHandler);
    });

  }, function (done) {

    // display the output buffer with padding before and after and between each item
    if (output.length) {
      var width = Number(bannerWidth) || 0;
      var hr    = new Array(width + 1);   // this is a good trick to repeat a character N times
      var start = (width > 0) ? (hr.join('\u25BC') + '\n') : '';
      var stop  = (width > 0) ? (hr.join('\u25B2') + '\n') : '';
      process.stdout.write(start + '\n' + output.join('\n') + '\n' + stop);
    }
    done();
  });
};<commit_msg>jshint fixes for node-sass.js.<commit_after>'use strict';

var path              = require('path'),
    fs                = require('fs'),
    through           = require('through2'),
    sass              = require('node-sass'),
    gutil             = require('gulp-util'),
    slash             = require('gulp-slash'),
    rework            = require('rework'),
    visit             = require('rework-visit'),
    convert           = require('convert-source-map'),
    SourceMapConsumer = require('source-map').SourceMapConsumer,
    mime              = require('mime');

/**
 * Search for the relative file reference from the startPath up to the process
 * working directory, avoiding any other directories with a package.json or bower.json.
 * @param {string} startPath The location of the uri declaration and the place to start the search from
 * @param {string} uri The content of the url() statement, expected to be a relative file path
 * @returns {string} dataURI of the file where found or undefined otherwise
 */
function encodeRelativeURL(startPath, uri) {

  /**
   * Test whether the given directory is the root of its own package
   * @param {string} absolutePath An absolute path
   * @returns {boolean} True where a package.json or bower.json exists, else False
   */
  function notPackage(absolutePath) {
    return ['package.json', 'bower.json'].every(function fileNotFound(file) {
        return !(fs.existsSync(path.resolve(absolutePath, file)));
      });
  }

  // ignore data uris and ensure we are at a valid start path
  var absoluteStart = !(/^data\:/.test(uri)) && path.resolve(startPath);
  if (absoluteStart) {

    // find path to the root, stopping at cwd, package.json or bower.json
    var pathToRoot = [ ];
    do {
      pathToRoot.push(absoluteStart);
      var isWorking = (absoluteStart !== process.cwd()) && notPackage(absoluteStart);
      absoluteStart = path.resolve(absoluteStart, '..');
    } while (isWorking);

    // start a queue with the path to the root
    var queue = pathToRoot.concat();

    // process the queue until empty
    //  the queue pattern ensures that we favour paths closest the the start path
    while (queue.length) {

      // shift the first item off the queue, consider it the base for our relative uri
      var basePath = queue.shift();
      var fullPath = path.resolve(basePath, uri);

      // file exists so convert to a dataURI and end
      if (fs.existsSync(fullPath)) {
        var type     = mime.lookup(fullPath);
        var contents = fs.readFileSync(fullPath);
        var base64   = new Buffer(contents).toString('base64');
        return 'url(data:' + type + ';base64,' + base64 + ')';
      }
      // enqueue subdirectories that are not packages and are not in the root path
      else {
        fs.readdirSync(basePath)
          .filter(function notHidden(filename) {
            return (filename.charAt(0) !== '.');
          })
          .map(function toAbsolute(filename) {
            return path.join(basePath, filename);
          })
          .filter(function directoriesOnly(absolutePath) {
            return fs.statSync(absolutePath).isDirectory();
          })
          .filter(function notInRootPath(absolutePath) {
            return (pathToRoot.indexOf(absolutePath) < 0);
          })
          .filter(notPackage)
          .forEach(function enqueue(absolutePath) {
            queue.push(absolutePath);
          });
      }
    }
  }
}

/**
 * Use node-sass to compile the files of the input stream.
 * Outputs a stream of compiled files and their source-maps, alternately.
 * @see https://github.com/sass/node-sass#outputstyle
 * @param {Array.<string>} [libraryPaths] Any number of library path strings
 * @returns {stream.Through} A through stream that performs the operation of a gulp stream
 */
module.exports = function (bannerWidth, libraryPaths) {
  var output  = [ ];
  var libList = (libraryPaths || [ ]).filter(function isString(value) {
    return (typeof value === 'string');
  });
  return through.obj(function (file, encoding, done) {
    var stream = this;

    // setup parameters
    var sourcePath = file.path.replace(path.basename(file.path), '');
    var sourceName = path.basename(file.path, path.extname(file.path));
    var mapName    = sourceName + '.css.map';
    var sourceMapConsumer;

    /**
     * Push file contents to the output stream.
     * @param {string} ext The extension for the file, including dot
     * @param {string|object?} contents The contents for the file or fields to assign to it
     * @return {vinyl.File} The file that has been pushed to the stream
     */
    function pushResult(ext, contents) {
      var pending = new gutil.File({
        cwd:      file.cwd,
        base:     file.base,
        path:     sourcePath + sourceName + ext,
        contents: (typeof contents === 'string') ? new Buffer(contents) : null
      });
      if (typeof contents === 'object') {
        for (var key in contents) {
          pending[key] = contents[key];
        }
      }
      stream.push(pending);
      return pending;
    }

    /**
     * Plugin for css rework that follows SASS transpilation
     * @param {object} stylesheet AST for the CSS output from SASS
     */
    function reworkPlugin(stylesheet) {

      // visit each node (selector) in the stylesheet recursively using the official utility method
      visit(stylesheet, function (declarations) {

        // each node may have multiple declarations
        declarations.forEach(function (declaration) {

          // reverse the original source-map to find the original sass file
          var cssStart  = declaration.position.start;
          var sassStart = sourceMapConsumer.originalPositionFor({
            line:   cssStart.line,
            column: cssStart.column
          });
          if (!sassStart.source) {
            throw new Error('failed to decode node-sass source map'); // this can occur with regressions in libsass
          }
          var sassDir = path.dirname(sassStart.source);

          // allow multiple url() values in the declaration
          //  the uri will be every second value (i % 2)
          declaration.value = declaration.value
            .split(/url\s*\(\s*['"]?([^'"?#]*)[^)]*\)/g)  // split by url statements
            .map(function (token, i) {
              return (i % 2) ? (encodeRelativeURL(sassDir, token) || ('url(' + token + ')')) : token;
            }).join('');
        });
      });
    }

    /**
     * Handler for successful transpilation using node-sass.
     * This functions gets called with an object containing a CSS file and its source-map,
     * which is modified and passed through CSS rework, before being pushed to the results.
     * @param {string} css Compiled css
     * @param {string} map The source-map for the compiled css
     */
    function successHandler(css, map) {

      // adjust source-map
      var sourceMap = convert.fromJSON(map).toObject();
      sourceMap.sources.forEach(function (value, i, array) {
        array[i] = path.resolve(value.replace(/^\//, '').replace(/\b\/+\b/g, '/'));  // ensure single slash absolute
      });

      // prepare the adjusted sass source-map for later look-ups
      sourceMapConsumer = new SourceMapConsumer(sourceMap);

      // embed sourcemap in css
      var cssWithMap = css.replace(
        /\/\*#\s*sourceMappingURL=[^*]*\*\//m,
        '/*# sourceMappingURL=data:application/json;base64,' + convert.fromObject(sourceMap).toBase64() + ' */'
      );

      // rework css
      var reworked = rework(cssWithMap, '')
        .use(reworkPlugin)
        .toString({
          sourcemap        : true,
          sourcemapAsObject: true
        });

      // adjust overall sourcemap
      delete reworked.map.file;
      delete reworked.map.sourcesContent;
      reworked.map.sources.forEach(function (value, i, array) {
        array[i] = '/' + slash(path.relative(process.cwd(), value));   // ensure root relative
      });

      // write stream output
      pushResult('.css', reworked.code + '\n/*# sourceMappingURL=' + mapName  + ' */');
      pushResult('.css.map', JSON.stringify(reworked.map, null, 2));
      done();
    }

    /**
     * Handler for error in node-sass.
     * @param {string} error The error text from node-sass
     */
    function errorHandler(error) {
      var analysis = /(.*)\:(\d+)\:\s*error\:\s*(.*)/.exec(error);
      var resolved = path.resolve(analysis[1]);
      var filename = [ '.scss', '.css']
        .map(function (ext) {
          return resolved + ext;
        })
        .filter(function (fullname) {
          return fs.existsSync(fullname);
        })
        .pop();
      var message  = analysis ?
        ((filename || resolved) + ':' + analysis[2] + ':0: ' + analysis[3] + '\n') :
        ('TODO parse this error\n' + error + '\n');
      if (output.indexOf(message) < 0) {
        output.push(message);
      }
      done();
    }

    /**
     * Perform the sass render with the given sourceMap, error, and success
     * parameters.
     * @param {string|boolean} map The source map filename or false for none
     * @param {function ({string})} error Handler for error
     * @param {function ({string}, {string})} success Handler for success
     */
    function render(map, error, success) {
      sass.render({
        file        : file.path,
        data        : file.contents.toString(),
        success     : success,
        error       : error,
        includePaths: libList,
        outputStyle : 'compressed',
        stats       : { },
        sourceMap   : map
      });
    }

    // run first without source-map as this can cause process exit where errors exist
    render(false, errorHandler, function () {
      render(mapName, errorHandler, successHandler);
    });

  }, function (done) {

    // display the output buffer with padding before and after and between each item
    if (output.length) {
      var width = Number(bannerWidth) || 0;
      var hr    = new Array(width + 1);   // this is a good trick to repeat a character N times
      var start = (width > 0) ? (hr.join('\u25BC') + '\n') : '';
      var stop  = (width > 0) ? (hr.join('\u25B2') + '\n') : '';
      process.stdout.write(start + '\n' + output.join('\n') + '\n' + stop);
    }
    done();
  });
};<|endoftext|>


<commit_before>jest.dontMock('../HostUtil');

const HostUtil = require('../HostUtil');

describe('HostUtil', function () {

  describe('#stringToHostname', function () {

    it('should strip out invalid characters from the middle', function () {
      var result = HostUtil.stringToHostname('fd%gsf---gs7-f$gs--d7fddg-123');

      expect(result).toEqual('fdgsf---gs7-fgs--d7fddg-123');
    });

    it('should strip out invalid characters from the start', function () {
      var result = HostUtil.stringToHostname('-@4abc123');

      expect(result).toEqual('4abc123');
    });

    it('should strip out invalid characters from the end', function () {
      var result = HostUtil.stringToHostname('4abc123.');

      expect(result).toEqual('4abc123');
    });

    it('should strip invalid characters from the start and end', function () {
      var result = HostUtil.stringToHostname('##fdgsf---gs7-fgs--d7fddg123456789012345678901234567890123456789-');

      expect(result).toEqual('fdgsf---gs7-fgs--d7fddg123456789012345678901234567890123456789');
    });

    it('should return valid hostnames', function () {
      var result = HostUtil.stringToHostname('0-0');

      expect(result).toEqual('0-0');
    });

    it('should allow dashes within the hostname', function () {
      var result = HostUtil.stringToHostname('89fdgsf---gs7-fgs--d7fddg-123');

      expect(result).toEqual('89fdgsf---gs7-fgs--d7fddg-123');
    });

    it('should strip invalid characters and trim to 63 characters and remove invalid end characters', function () {
      var result = HostUtil.stringToHostname('fd%gsf---gs7-f$gs--d7fddg123456789012345678901234567890123456789-123');

      expect(result).toEqual('fdgsf---gs7-fgs--d7fddg1234567890123456789012345678901234567891');
    });

    it('should strip invalid start characters and trim to 63 characters and remove invalid end characters', function () {
      var result = HostUtil.stringToHostname('%%fdgsf---gs7-fgs--d7fddg123456789012345678901234567890123456789---123');

      expect(result).toEqual('fdgsf---gs7-fgs--d7fddg1234567890123456789012345678901234567891');
    });

    it('should return valid strings', function () {
      var result = HostUtil.stringToHostname('a--------------------------------------------------------------b');

      expect(result).toEqual('a-------------------------------------------------------------b');
    });

    it('should lowercase the string', function () {
      var result = HostUtil.stringToHostname('XYZ');

      expect(result).toEqual('xyz');
    });

  });

});
<commit_msg>Use const instead of var for expected test results<commit_after>jest.dontMock('../HostUtil');

const HostUtil = require('../HostUtil');

describe('HostUtil', function () {

  describe('#stringToHostname', function () {

    it('should strip out invalid characters from the middle', function () {
      const result = HostUtil.stringToHostname('fd%gsf---gs7-f$gs--d7fddg-123');

      expect(result).toEqual('fdgsf---gs7-fgs--d7fddg-123');
    });

    it('should strip out invalid characters from the start', function () {
      const result = HostUtil.stringToHostname('-@4abc123');

      expect(result).toEqual('4abc123');
    });

    it('should strip out invalid characters from the end', function () {
      const result = HostUtil.stringToHostname('4abc123.');

      expect(result).toEqual('4abc123');
    });

    it('should strip invalid characters from the start and end', function () {
      const result = HostUtil.stringToHostname('##fdgsf---gs7-fgs--d7fddg123456789012345678901234567890123456789-');

      expect(result).toEqual('fdgsf---gs7-fgs--d7fddg123456789012345678901234567890123456789');
    });

    it('should return valid hostnames', function () {
      const result = HostUtil.stringToHostname('0-0');

      expect(result).toEqual('0-0');
    });

    it('should allow dashes within the hostname', function () {
      const result = HostUtil.stringToHostname('89fdgsf---gs7-fgs--d7fddg-123');

      expect(result).toEqual('89fdgsf---gs7-fgs--d7fddg-123');
    });

    it('should strip invalid characters and trim to 63 characters and remove invalid end characters', function () {
      const result = HostUtil.stringToHostname('fd%gsf---gs7-f$gs--d7fddg123456789012345678901234567890123456789-123');

      expect(result).toEqual('fdgsf---gs7-fgs--d7fddg1234567890123456789012345678901234567891');
    });

    it('should strip invalid start characters and trim to 63 characters and remove invalid end characters', function () {
      const result = HostUtil.stringToHostname('%%fdgsf---gs7-fgs--d7fddg123456789012345678901234567890123456789---123');

      expect(result).toEqual('fdgsf---gs7-fgs--d7fddg1234567890123456789012345678901234567891');
    });

    it('should return valid strings', function () {
      const result = HostUtil.stringToHostname('a--------------------------------------------------------------b');

      expect(result).toEqual('a-------------------------------------------------------------b');
    });

    it('should lowercase the string', function () {
      const result = HostUtil.stringToHostname('XYZ');

      expect(result).toEqual('xyz');
    });

  });

});
<|endoftext|>


<commit_before>var dep = new Deps.Dependency;
var popped = ('state' in window.history && window.history.state !== null);
var initialUrl = location.href;

function onclick (e) {
  var el = e.currentTarget
    , href
    , path
    , hash;

  if (el.nodeName === 'A') {
    href = el.href;
    path = el.pathname + el.search + el.hash;

    if (e.isDefaultPrevented())
      return;

    if (!IronLocation.isSameOrigin(href) || e.ctrlKey || el.target == '_blank')
      return;

    e.preventDefault();

    IronLocation.set(path);
  }
}

function onpopstate (e) {
  var initialPop = !popped && location.href == initialUrl;
  popped = true;

  if (!initialPop)
    dep.changed();
}

IronLocation = {};

IronLocation.origin = function () {
  return location.protocol + '//' + location.host;
};

IronLocation.isSameOrigin = function (href) {
  var origin = IronLocation.origin();
  return href.indexOf(href) === 0;
};

IronLocation.get = function () {
  dep.depend();
  return location;
};

IronLocation.path = function () {
  dep.depend();
  return location.pathname + location.search + location.hash;
};

IronLocation.set = function (url, options) {
  options = options || {};

  if (/^http/.test(url))
    href = url;
  else {
    if (url.charAt(0) !== '/')
      url = '/' + url;
    href = IronLocation.origin() + url;
  }

  if (!IronLocation.isSameOrigin(href))
    window.location = href;
  else if (options.where === 'server')
    window.location = href;
  else if (options.replaceState)
    IronLocation.replaceState(options.state, options.title, url);
  else
    IronLocation.pushState(options.state, options.title, url);

  if (options.skipReactive !== true)
    dep.changed();
};

IronLocation.pushState = function (state, title, url) {
  if (history.pushState)
    history.pushState(state, title, url);
  else
    window.location = url;
};

IronLocation.replaceState = function (state, title, url) {
  if (history.replaceState)
    history.replaceState(state, title, url);
  else
    window.location = url;
};

IronLocation.start = function () {
  if (this.isStarted)
    return;

  $(window).bind('popstate', onpopstate);
  $(document).delegate('a', 'click', onclick);
  this.isStarted = true;
};

IronLocation.stop = function () {
  $(window).unbind('popstate', onpopstate);
  $(window).undelegate('a', 'click', onclick);
  this.isStarted = false;
};

IronLocation.start();
<commit_msg>Fix: external links not working due to regression in isSameOrigin<commit_after>var dep = new Deps.Dependency;
var popped = ('state' in window.history && window.history.state !== null);
var initialUrl = location.href;

function onclick (e) {
  var el = e.currentTarget
    , href
    , path
    , hash;

  if (el.nodeName === 'A') {
    href = el.href;
    path = el.pathname + el.search + el.hash;

    if (e.isDefaultPrevented())
      return;

    if (!IronLocation.isSameOrigin(href) || e.ctrlKey || el.target == '_blank')
      return;

    e.preventDefault();

    IronLocation.set(path);
  }
}

function onpopstate (e) {
  var initialPop = !popped && location.href == initialUrl;
  popped = true;

  if (!initialPop)
    dep.changed();
}

IronLocation = {};

IronLocation.origin = function () {
  return location.protocol + '//' + location.host;
};

IronLocation.isSameOrigin = function (href) {
  var origin = IronLocation.origin();
  return href.indexOf(origin) === 0;
};

IronLocation.get = function () {
  dep.depend();
  return location;
};

IronLocation.path = function () {
  dep.depend();
  return location.pathname + location.search + location.hash;
};

IronLocation.set = function (url, options) {
  options = options || {};

  if (/^http/.test(url))
    href = url;
  else {
    if (url.charAt(0) !== '/')
      url = '/' + url;
    href = IronLocation.origin() + url;
  }

  if (!IronLocation.isSameOrigin(href))
    window.location = href;
  else if (options.where === 'server')
    window.location = href;
  else if (options.replaceState)
    IronLocation.replaceState(options.state, options.title, url);
  else
    IronLocation.pushState(options.state, options.title, url);

  if (options.skipReactive !== true)
    dep.changed();
};

IronLocation.pushState = function (state, title, url) {
  if (history.pushState)
    history.pushState(state, title, url);
  else
    window.location = url;
};

IronLocation.replaceState = function (state, title, url) {
  if (history.replaceState)
    history.replaceState(state, title, url);
  else
    window.location = url;
};

IronLocation.start = function () {
  if (this.isStarted)
    return;

  $(window).bind('popstate', onpopstate);
  $(document).delegate('a', 'click', onclick);
  this.isStarted = true;
};

IronLocation.stop = function () {
  $(window).unbind('popstate', onpopstate);
  $(window).undelegate('a', 'click', onclick);
  this.isStarted = false;
};

IronLocation.start();
<|endoftext|>


<commit_before>
var o_edit_top_form = {
  name  : 'o_edit_top_form',
  //  url   : 'server/post',
  fields: [
    { field: 'asunto', type: 'text', required: true },

    { field: 'field_enum', type: 'enum', required: true,
                options: { items: ['Adams, John', 'Johnson, Peter', 'Lewis, Frank', 'Cruz, Steve', 'Donnun, Nick'] } },
    { field: 'cartel', type: 'textarea'}
  ],
}

var o_edit_itemgrid = {
  name: 'o_itemgrid',
  show: {
    toolbar: true,
    toolbarDelete: true,
    toolbarSave: false
  },
//        url: '/'+recid,

  toolbar: {
    items: [
      { id: 'add', type: 'button', caption: 'Otro item', icon: 'w2ui-icon-plus' }
    ],
    onClick: function (event) {
      if (event.target == 'add') {
        w2ui.o_itemgrid.add({ recid: w2ui.o_itemgrid.records.length + 1 });
      }
    }
  },

  columns: [
    { field: 'text', caption: 'nombre', size: '120px', sortable: true, resizable: true,
      editable: { type: 'text' }
    },
    { field: 'desc', caption: 'descripción', size: '50%', sortable: true, resizable: true,
      editable: { type: 'text' }
    },
    { field: 'presentacion', caption: 'presentación', size: '100px', sortable: true, resizable: true,
      editable: { type: 'combo', items: unidades, openOnFocus: true }
    },
    { field: 'precio', caption: 'precio', size: '80px', sortable: true, resizable: true, render: 'money',
      editable: { type: 'money' }
    },
  ],
  records: [
  ]
}

var o_edit_bottom_toolbar = {
  name: 'savebar',
  items: [
    { id: 'spcer', type: 'spacer' },
    { id: 'save', type: 'button', caption: 'guardar', img: 'icon-page'}
  ],
  onClick: function (event) {
    if (event.target == 'save') w2ui.form.save();
  }
}

function asunto(recid) {
  if (recid=="nueva") {
    return 'crear oferta nueva';
  } else {
    return 'editar oferta ' + recid;
  }
}

function o_edit_popup(recid) {
  w2popup.open({
    title   : asunto(recid),
    width   : 900,
    height  : 600,
    body    : '

',
    onOpen  : function (event) {
      event.onComplete = function () {
        $('#w2ui-popup #poplayout').w2layout(ad_layout);
        w2ui.ad_layout.content('top', "

");
        $('#o_edit_top_form').w2form(o_edit_top_form);
        w2ui.ad_layout.content('main', $().w2grid(o_edit_itemgrid));
        w2ui.ad_layout.content('bottom', $().w2toolbar( o_edit_bottom_toolbar));
      }
    },
    onToggle: function (event) {
      event.onComplete = function () {
        w2ui.layout.resize();
      }
    },
    onClose: function(event) {
      w2ui.o_edit_top_form.destroy();
      w2ui.o_itemgrid.destroy();
      w2ui.savebar.destroy();
      w2ui.ad_layout.destroy();
    }
  });
}

<commit_msg>campo para listas, encabezado de itemgrid<commit_after>
var o_edit_top_form = {
  name  : 'o_edit_top_form',
  //  url   : 'server/post',
  fields: [
    { field: 'asunto', type: 'text', required: true },

    { field: 'destinatarios', type: 'enum', required: true,
      options: { items: ['Adams, John', 'Johnson, Peter', 'Lewis, Frank', 'Cruz, Steve', 'Donnun, Nick'] }},

    { field: 'listas', type: 'enum',
      options: { items: ['todos', 'la roma', 'sur', 'veganos', 'tianguis el 100'],
                 openOnFocus: true, }},

    { field: 'cartel', type: 'textarea'}
  ],
}

var o_edit_itemgrid = {
  name  : 'o_itemgrid',
  header: 'items en venta',
  show  : {
    header       : true,
    toolbar      : true,
    toolbarDelete: true,
    toolbarSave  : false
  },
//        url: '/'+recid,

  toolbar: {
    items: [
      { id: 'add', type: 'button', caption: 'Otro item', icon: 'w2ui-icon-plus' }
    ],
    onClick: function (event) {
      if (event.target == 'add') {
        w2ui.o_itemgrid.add({ recid: w2ui.o_itemgrid.records.length + 1 });
      }
    }
  },

  columns: [
    { field: 'text', caption: 'nombre', size: '120px', sortable: true, resizable: true,
      editable: { type: 'text' }
    },
    { field: 'desc', caption: 'descripción', size: '50%', sortable: true, resizable: true,
      editable: { type: 'text' }
    },
    { field: 'presentacion', caption: 'presentación', size: '100px', sortable: true, resizable: true,
      editable: { type: 'combo', items: unidades, openOnFocus: true }
    },
    { field: 'precio', caption: 'precio', size: '80px', sortable: true, resizable: true, render: 'money',
      editable: { type: 'money' }
    },
  ],
  records: [
  ]
}

var o_edit_bottom_toolbar = {
  name: 'savebar',
  items: [
    { id: 'spcer', type: 'spacer' },
    { id: 'save', type: 'button', caption: 'guardar', img: 'icon-page'}
  ],
  onClick: function (event) {
    if (event.target == 'save') w2ui.form.save();
  }
}

function asunto(recid) {
  if (recid=="nueva") {
    return 'crear oferta nueva';
  } else {
    return 'editar oferta ' + recid;
  }
}

function o_edit_popup(recid) {
  w2popup.open({
    title   : asunto(recid),
    width   : 900,
    height  : 600,
    body    : '

',
    onOpen  : function (event) {
      event.onComplete = function () {
        $('#w2ui-popup #poplayout').w2layout(ad_layout);
        w2ui.ad_layout.content('top', "

");
        $('#o_edit_top_form').w2form(o_edit_top_form);
        w2ui.ad_layout.content('main', $().w2grid(o_edit_itemgrid));
        w2ui.ad_layout.content('bottom', $().w2toolbar( o_edit_bottom_toolbar));
      }
    },
    onToggle: function (event) {
      event.onComplete = function () {
        w2ui.layout.resize();
      }
    },
    onClose: function(event) {
      w2ui.o_edit_top_form.destroy();
      w2ui.o_itemgrid.destroy();
      w2ui.savebar.destroy();
      w2ui.ad_layout.destroy();
    }
  });
}

<|endoftext|>


<commit_before>const Command = require('../command');

class BackupCommand extends Command {
    async run(argv) {
        const semver = require('semver');

        const backupTask = require('../tasks/backup');
        const {loadVersions} = require('../utils/version');
        const {CliError, SystemError} = require('../errors');

        const instance = this.system.getInstance();
        const isRunning = await instance.isRunning();

        if (!isRunning) {
            const shouldStart = await this.ui.confirm('Ghost instance is not currently running. Would you like to start it?', true);

            if (!shouldStart) {
                throw new SystemError('Ghost instance is not currently running');
            }

            instance.checkEnvironment();
            await this.ui.run(() => instance.start(), 'Starting Ghost');
        }

        // Get the latest version in our current major
        const {latestMajor, latest} = await loadVersions();
        const activeMajor = semver.major(instance.version);
        const latestMinor = latestMajor[`v${activeMajor}`];

        const isBehindByMajor = semver.diff(instance.version, latest) === 'major';

        if (instance.version !== latestMinor && isBehindByMajor && !argv.force) {
            const currentMajor = semver.major(instance.version);

            throw new CliError({
                message: `We strongly recommend upgrading to the latest v${currentMajor} before backing up & upgrading across majors in order to ensure compatibility with future major versions of Ghost.`,
                help: `Run \`ghost update v${currentMajor}\` to get the latest version or alternatively run \`ghost backup --force\` to make an extra backup now.`
            });
        }

        let backupFile;

        await this.ui.run(async () => {
            backupFile = await backupTask(this.ui, instance);
        }, 'Backing up site');

        this.ui.log(`Backup saved to ${backupFile}`, 'green');
    }
}

BackupCommand.description = 'Backup content & files';
BackupCommand.options = {
    force: {
        description: 'Force backup if not on the latest version',
        type: 'boolean'
    }
};

module.exports = BackupCommand;
<commit_msg>fix(backup): added guard against unpublished versions<commit_after>const Command = require('../command');

class BackupCommand extends Command {
    async run(argv) {
        const semver = require('semver');

        const backupTask = require('../tasks/backup');
        const {loadVersions} = require('../utils/version');
        const {CliError, SystemError} = require('../errors');

        const instance = this.system.getInstance();
        const isRunning = await instance.isRunning();

        if (!isRunning) {
            const shouldStart = await this.ui.confirm('Ghost instance is not currently running. Would you like to start it?', true);

            if (!shouldStart) {
                throw new SystemError('Ghost instance is not currently running');
            }

            instance.checkEnvironment();
            await this.ui.run(() => instance.start(), 'Starting Ghost');
        }

        // Get the latest version in our current major
        const {latestMajor, latest} = await loadVersions();
        const activeMajor = semver.major(instance.version);
        const latestMinor = latestMajor[`v${activeMajor}`];

        const isBehindByMajor = semver.diff(instance.version, latest) === 'major';

        if (latestMinor && instance.version !== latestMinor && isBehindByMajor && !argv.force) {
            const currentMajor = semver.major(instance.version);

            throw new CliError({
                message: `We strongly recommend upgrading to the latest v${currentMajor} before backing up & upgrading across majors in order to ensure compatibility with future major versions of Ghost.`,
                help: `Run \`ghost update v${currentMajor}\` to get the latest version or alternatively run \`ghost backup --force\` to make an extra backup now.`
            });
        }

        let backupFile;

        await this.ui.run(async () => {
            backupFile = await backupTask(this.ui, instance);
        }, 'Backing up site');

        this.ui.log(`Backup saved to ${backupFile}`, 'green');
    }
}

BackupCommand.description = 'Backup content & files';
BackupCommand.options = {
    force: {
        description: 'Force backup if not on the latest version',
        type: 'boolean'
    }
};

module.exports = BackupCommand;
<|endoftext|>


<commit_before>module.exports = {
  name: 'deploy',
  description: 'Deploys an ember-cli app',
  works: 'insideProject',

  availableOptions: [
    { name: 'environment', type: String, default: 'development', aliases: ['e',{'dev' : 'development'}, {'prod' : 'production'}] },
    { name: 'deploy-config-file', type: String, default: 'config/deploy.js' }
  ],

  run: function(commandOptions, rawArgs) {
    process.env.DEPLOY_ENVIRONMENT = commandOptions.environment;

    var PipelineTask = require('../tasks/pipeline');
    var pipeline = new PipelineTask({
      project: this.project,
      ui: this.ui,
      deployEnvironment: commandOptions.environment,
      deployConfigPath: commandOptions.deployConfigFile,
      hooks: [
        'configure',
        'willDeploy',
        'willBuild', 'build', 'didBuild',
        'willUpload', 'upload', 'didUpload',
        'willActivate', 'activate', 'didActivate',
        'didDeploy'
      ]
    });

    return pipeline.run();
  }
};
<commit_msg>Add command line arg to specify intention to force activation<commit_after>module.exports = {
  name: 'deploy',
  description: 'Deploys an ember-cli app',
  works: 'insideProject',

  availableOptions: [
    { name: 'environment', type: String, default: 'development', aliases: ['e',{'dev' : 'development'}, {'prod' : 'production'}] },
    { name: 'deploy-config-file', type: String, default: 'config/deploy.js' },
    { name: 'activate', type: Boolean, default: false }
  ],

  run: function(commandOptions, rawArgs) {
    process.env.DEPLOY_ENVIRONMENT = commandOptions.environment;

    var commandLineArgs = {
      activateRevision: commandOptions.activate
    };

    var PipelineTask = require('../tasks/pipeline');
    var pipeline = new PipelineTask({
      project: this.project,
      ui: this.ui,
      deployEnvironment: commandOptions.environment,
      deployConfigPath: commandOptions.deployConfigFile,
      commandLineArgs: commandLineArgs,
      hooks: [
        'configure',
        'willDeploy',
        'willBuild', 'build', 'didBuild',
        'willUpload', 'upload', 'didUpload',
        'willActivate', 'activate', 'didActivate',
        'didDeploy'
      ]
    });

    return pipeline.run();
  }
};
<|endoftext|>


<commit_before>/**
 * Module dependencies
 */

var path = require('path'),
    semver = require('semver'),
    install = require('./install'),
    tree = require('../tree');
    utils = require('../utils'),
    logger = require('../logger'),
    argParse = require('../args').parse,
    _ = require('underscore/underscore')._;

/**
 * Usage information and docs
 */

exports.summary = 'Updates a package to the latest compatible version';

exports.usage = '' +
'kanso update [PACKAGES ...]\n' +
'\n' +
'Parameters:\n' +
'  PACKAGES    Names of specific packages to update\n' +
'\n' +
'Options:\n' +
'  --repository   Source repository URL (otherwise uses values in kansorc)\n' +
'  --package-dir  Package directory (defaults to "./packages")';

/**
 * Run function called when "kanso update" command is used
 *
 * @param {Object} settings - the values from .kansorc files
 * @param {Array} args - command-line arguments
 */

exports.run = function (settings, args) {
    var a = argParse(args, {
        'repository': {match: '--repository', value: true},
        'target_dir': {match: '--package-dir', value: true}
    });

    var opt = a.options;
    var deps = a.positional;

    opt.target_dir = opt.target_dir || utils.abspath('packages');
    opt.repositories = settings.repositories;
    if (a.options.repository) {
        opt.repositories = [a.options.repository];
        // don't allow package dir .kansorc file to overwrite repositories
        opt.fixed_repositories = true;
    }
    exports.update(deps, opt, function (err) {
        if (err) {
            return logger.error(err);
        }
        logger.end();
    });
};

/**
 * Update the current project directory's dependencies.
 *
 * @param {Array} deps - an optional sub-set of package names to update
 * @param {Object} opt - the options object
 * @param {Function} callback
 */

exports.update = function (deps, opt, callback) {
    install.initDir('.', opt, function (err, opt, cfg) {
        if (err) {
            return callback(err);
        }
        exports.getOutdated(cfg, opt, function (err, packages) {
            if (err) {
                return callback(err);
            }
            if (deps.length) {
                packages = packages.filter(function (dep) {
                    return (_.indexOf(deps, dep.name) !== -1);
                });
            }
            exports.installChanges(packages, opt, callback);
        });
    });
};

/**
 * Builds a remote and a local copy of the version tree. This is used to compare
 * the installed packages against those that are available in the repositories.
 *
 * @param {Object} cfg - values from kanso.json for the root package
 * @param {Object} opt - the options object
 * @param {Function} callback
 */

exports.buildTrees = function (cfg, opt, callback) {
    var local_sources = [
        install.dirSource(opt.target_dir)
    ];
    var pkg = {
        config: cfg,
        source: 'root'
    };
    logger.info('Building local version tree...');
    tree.build(pkg, local_sources, function (err, local_packages) {
        if (err) {
            return callback(err);
        }
        var all_sources = [
            // check remote source first to make sure we get highest version
            install.repoSource(opt.repositories),
            install.dirSource(opt.target_dir)
        ];
        logger.info('Building remote version tree...');
        tree.build(pkg, all_sources, function (err, remote_packages) {
            // TODO: modify local tree with filtered list of packages to update
            // (provided on the command line) so that we can work out the
            // changes that are dependencies of this filtered package list.
            // Currently, doing "kanso update db" wouldn't update, for example
            // the modules package if it was required by the new version of 'db'
            callback(err, local_packages, remote_packages);
        });
    });
};

/**
 * Gets the remote and local version trees, compares the version numbers for
 * each package, and returns a list of packages which have changed.
 *
 * Each objects in the returned list of changed packages have the following
 * properties:
 *
 * - name - the name of the package
 * - version - the new version to be installed
 * - old - the old version to be installed (null if it doesn't currently exist)
 *
 * @param {Object} cfg - the values from kanso.json for the root package
 * @param {Object} opt - the options object
 * @param {Function} callback
 */

exports.getOutdated = function (cfg, opt, callback) {
    exports.buildTrees(cfg, opt, function (err, local, remote) {
        if (err) {
            return callback(err);
        }
        var all_names = _.uniq(_.keys(local).concat(_.keys(remote)));

        var changed = all_names.map(function (name) {
            var lversion = local[name] ? local[name].current_version: null;
            var rversion = remote[name].current_version;

            if (!local[name] && remote[name] || lversion !== rversion) {
                return {name: name, version: rversion, old: lversion};
            }
        });
        callback(null, _.compact(changed));
    });
};

/**
 * Accepts an array of changed packages and reports the change to the console
 * then installs from the repositories.
 *
 * @param {Array} packages - array of changed packages
 * @param {Object} opt - the options object
 * @param {Function} callback
 */

exports.installChanges = function (packages, opt, callback) {
    async.forEachLimit(packages, 5, function (dep, cb) {
        if (!dep.old) {
            logger.info('new package', dep.name + '@' + dep.version);
        }
        else if (semver.lt(dep.old, dep.version)) {
            logger.info(
                'update package',
                dep.name + '@' + dep.old + ' => ' + dep.name + '@' + dep.version
            );
        }
        else if (semver.gt(dep.old, dep.version)) {
            logger.info(
                'downgrade package',
                dep.name + '@' + dep.old + ' => ' + dep.name + '@' + dep.version
            );
        }
        install.installRepo(dep.name, dep.version, opt, cb);
    }, callback);
};
<commit_msg>don't error on local package missing from repository during kanso update<commit_after>/**
 * Module dependencies
 */

var path = require('path'),
    semver = require('semver'),
    install = require('./install'),
    tree = require('../tree');
    utils = require('../utils'),
    logger = require('../logger'),
    argParse = require('../args').parse,
    _ = require('underscore/underscore')._;

/**
 * Usage information and docs
 */

exports.summary = 'Updates a package to the latest compatible version';

exports.usage = '' +
'kanso update [PACKAGES ...]\n' +
'\n' +
'Parameters:\n' +
'  PACKAGES    Names of specific packages to update\n' +
'\n' +
'Options:\n' +
'  --repository   Source repository URL (otherwise uses values in kansorc)\n' +
'  --package-dir  Package directory (defaults to "./packages")';

/**
 * Run function called when "kanso update" command is used
 *
 * @param {Object} settings - the values from .kansorc files
 * @param {Array} args - command-line arguments
 */

exports.run = function (settings, args) {
    var a = argParse(args, {
        'repository': {match: '--repository', value: true},
        'target_dir': {match: '--package-dir', value: true}
    });

    var opt = a.options;
    var deps = a.positional;

    opt.target_dir = opt.target_dir || utils.abspath('packages');
    opt.repositories = settings.repositories;
    if (a.options.repository) {
        opt.repositories = [a.options.repository];
        // don't allow package dir .kansorc file to overwrite repositories
        opt.fixed_repositories = true;
    }
    exports.update(deps, opt, function (err) {
        if (err) {
            return logger.error(err);
        }
        logger.end();
    });
};

/**
 * Update the current project directory's dependencies.
 *
 * @param {Array} deps - an optional sub-set of package names to update
 * @param {Object} opt - the options object
 * @param {Function} callback
 */

exports.update = function (deps, opt, callback) {
    install.initDir('.', opt, function (err, opt, cfg) {
        if (err) {
            return callback(err);
        }
        exports.getOutdated(cfg, opt, function (err, packages) {
            if (err) {
                return callback(err);
            }
            if (deps.length) {
                packages = packages.filter(function (dep) {
                    return (_.indexOf(deps, dep.name) !== -1);
                });
            }
            exports.installChanges(packages, opt, callback);
        });
    });
};

/**
 * Builds a remote and a local copy of the version tree. This is used to compare
 * the installed packages against those that are available in the repositories.
 *
 * @param {Object} cfg - values from kanso.json for the root package
 * @param {Object} opt - the options object
 * @param {Function} callback
 */

exports.buildTrees = function (cfg, opt, callback) {
    var local_sources = [
        install.dirSource(opt.target_dir)
    ];
    var pkg = {
        config: cfg,
        source: 'root'
    };
    logger.info('Building local version tree...');
    tree.build(pkg, local_sources, function (err, local_packages) {
        if (err) {
            return callback(err);
        }
        var all_sources = [
            // check remote source first to make sure we get highest version
            install.repoSource(opt.repositories),
            install.dirSource(opt.target_dir)
        ];
        logger.info('Building remote version tree...');
        tree.build(pkg, all_sources, function (err, remote_packages) {
            // TODO: modify local tree with filtered list of packages to update
            // (provided on the command line) so that we can work out the
            // changes that are dependencies of this filtered package list.
            // Currently, doing "kanso update db" wouldn't update, for example
            // the modules package if it was required by the new version of 'db'
            callback(err, local_packages, remote_packages);
        });
    });
};

/**
 * Gets the remote and local version trees, compares the version numbers for
 * each package, and returns a list of packages which have changed.
 *
 * Each objects in the returned list of changed packages have the following
 * properties:
 *
 * - name - the name of the package
 * - version - the new version to be installed
 * - old - the old version to be installed (null if it doesn't currently exist)
 *
 * @param {Object} cfg - the values from kanso.json for the root package
 * @param {Object} opt - the options object
 * @param {Function} callback
 */

exports.getOutdated = function (cfg, opt, callback) {
    exports.buildTrees(cfg, opt, function (err, local, remote) {
        if (err) {
            return callback(err);
        }
        var all_names = _.uniq(_.keys(local).concat(_.keys(remote)));

        var changed = all_names.map(function (name) {
            var lversion = local[name] ? local[name].current_version: null;
            var rversion = remote[name] ? remote[name].current_version: null;

            if (!local[name] && remote[name] || lversion !== rversion) {
                return {name: name, version: rversion, old: lversion};
            }
        });
        callback(null, _.compact(changed));
    });
};

/**
 * Accepts an array of changed packages and reports the change to the console
 * then installs from the repositories.
 *
 * @param {Array} packages - array of changed packages
 * @param {Object} opt - the options object
 * @param {Function} callback
 */

exports.installChanges = function (packages, opt, callback) {
    async.forEachLimit(packages, 5, function (dep, cb) {
        if (!dep.old) {
            logger.info('new package', dep.name + '@' + dep.version);
        }
        else if (semver.lt(dep.old, dep.version)) {
            logger.info(
                'update package',
                dep.name + '@' + dep.old + ' => ' + dep.name + '@' + dep.version
            );
        }
        else if (semver.gt(dep.old, dep.version)) {
            logger.info(
                'downgrade package',
                dep.name + '@' + dep.old + ' => ' + dep.name + '@' + dep.version
            );
        }
        install.installRepo(dep.name, dep.version, opt, cb);
    }, callback);
};
<|endoftext|>


<commit_before>var fs = require("fs");
var term = require("ringo/term");
var shell = require("ringo/shell");
var {Parser} = require("ringo/args");
var semver = require("../utils/semver");
var packages = require("../utils/packages");
var registry = require("../utils/registry");
var {Resolver, Resolved} = require("../utils/resolver");
var {indent} = require("../utils/strings");
var log = require("ringo/logging").getLogger(module.id);
var {proceed} = require("../utils/shell");

//argument parser
var parser = new Parser();
parser.addOption("g", "global", null, "Update globally installed packages");

exports.description = "Updates installed packages";

exports.help = function help() {
    term.writeln("\n" + exports.description, "\n");
    term.writeln("Usage:");
    term.writeln("  rp update [options] [<name> [<name> ...]]");
    term.writeln("\nOptions:");
    term.writeln(parser.help());
    term.writeln();
};

exports.update = function(args) {
    var opts = {};
    try {
        parser.parse(args, opts);
    } catch (e) {
        term.writeln(term.RED, e.message, term.RESET);
        term.writeln("Available options:");
        term.writeln(parser.help());
        return;
    }

    var dir = packages[(opts.global === true) ? "getGlobalDir" : "getLocalDir"]();
    var packagesDir = packages.getPackagesDir(dir);
    if (!fs.exists(packagesDir)) {
        log.debug(packagesDir, "does not exist");
        term.writeln("No packages found (wrong directory?)");
        return false;
    }
    log.debug("Updating packages in", packagesDir);
    var resolver = new Resolver(registry);
    var descriptor = packages.getDescriptor(dir);
    if (descriptor !== null && descriptor.hasOwnProperty("dependencies")) {
        term.writeln("Resolving dependencies of", descriptor.name, "...");
        for each (let [name, range] in Iterator(descriptor.dependencies)) {
            resolver.resolve(name, range);
        }
    } else {
        term.writeln("Resolving packages installed in", packagesDir, "...");
        for each (let name in getInstalled(packagesDir)) {
            // term.writeln(indent("found", 1), name, "...");
            resolver.resolve(name);
        }
    }
    var resolved = resolver.getDescriptors();
    if (args.length > 0) {
        log.debug("Reducing packages to:", args.join(", "));
        resolved = resolved.filter(function(descriptor) {
            return args.indexOf(descriptor.name) > -1;
        });
    }
    var toInstall = filterUpdateable(packagesDir, resolved);
    if (toInstall.length > 0) {
        installPackages(packagesDir, toInstall);
    }
};

var getInstalled = function(packagesDir) {
    return fs.list(packagesDir).filter(function(name) {
        if (name.charAt(0) === ".") {
            log.debug("ignoring", name);
            return false;
        }
        let dir = fs.join(packagesDir, name);
        if (fs.isFile(dir)) {
            log.debug("ignoring", dir, "- it's a file");
            return false;
        }
        let descriptor = packages.getDescriptor(dir);
        if (!descriptor) {
            log.debug("ignoring", dir, "- doesn't containg a package descriptor");
            return false;
        } else if (descriptor.name !== name) {
            log.debug("ignoring", dir, "- it contains", descriptor.name,
                    descriptor.version);
            return false;
        }
        return true;
    });
};

var filterUpdateable = function(packagesDir, descriptors) {
    return descriptors.filter(function(descriptor) {
        var result = packages.isUpdateable(packagesDir, descriptor.name, descriptor.version);
        if (result !== packages.OK) {
            var packageDir = fs.normal(fs.join(packagesDir, descriptor.name));
            term.write(term.RED);
            if (result === packages.ERR_ISFILE) {
                term.write("Can't update", descriptor.name,
                        "because a file with the same name exists in", packagesDir);
            } else if (result === packages.ERR_ISLINK) {
                term.write("Can't update", descriptor.name, "- it's a symlink to",
                        fs.canonical(fs.readLink(packageDir)));
            } else if (result === packages.ERR_NOPACKAGE) {
                term.write(term.RED, "Can't update", descriptor.name, "because",
                        packageDir, "doesn't contain a valid package");
            } else if (result === packages.ERR_RENAMED) {
                let descriptor = packages.getDescriptor(packageDir);
                term.write(packageDir, "contains", descriptor.name,
                        descriptor.version);
            } else if (result === packages.ERR_SAMEVERSION) {
                let descriptor = packages.getDescriptor(packageDir);
                term.write(term.GREEN, descriptor.name,
                        "is already the latest version (" + descriptor.version + ")");
            }
            term.writeln(term.RESET);
        }
        return result === packages.OK;
    });
};

var installPackages = function(packagesDir, descriptors) {
    term.writeln(term.BOLD, "\nAbout to update/install in", packagesDir + ":",
            term.RESET);
    for each (let descriptor in descriptors) {
        let current = packages.getDescriptor(packagesDir, descriptor.name);
        if (current === null) {
            term.writeln(indent(descriptor.name, 1), descriptor.version);
        } else {
            term.writeln(indent(descriptor.name, 1), "(" + current.version,
                    "->", descriptor.version + ")");
        }
    }
    if (!proceed("n")) {
        term.writeln("Cancelled");
    } else {
        descriptors.forEach(function(descriptor) {
            installPackage(packagesDir, descriptor);
        });
    }
};

var installPackage = function(dir, descriptor) {
    var file = null;
    var tmpInstallDir = null;
    var installDir = fs.join(dir, descriptor.name);
    try {
        term.writeln("Downloading", descriptor.name, descriptor.version, "...");
        file = registry.getPackage(descriptor);
        tmpInstallDir = packages.install(file, dir, descriptor.name + ".tmp",
                descriptor.version);
        if (fs.exists(installDir)) {
            fs.removeTree(installDir);
        }
        fs.move(tmpInstallDir, installDir);
        log.debug("Moved", tmpInstallDir, "to", installDir);
        term.writeln(term.GREEN, "Installed", descriptor.name,
                descriptor.version, "in", installDir, term.RESET);
    } finally {
        // cleanup: remove temporary package archive file and the temporary
        // installation directory (if existing)
        if (file !== null && fs.exists(file)) {
            fs.remove(file);
        }
        if (tmpInstallDir !== null && fs.exists(tmpInstallDir)) {
            fs.removeTree(tmpInstallDir);
        }
    }
};
<commit_msg>modified update command: don't stop resolving when a package isn't found in registry<commit_after>var fs = require("fs");
var term = require("ringo/term");
var shell = require("ringo/shell");
var {Parser} = require("ringo/args");
var semver = require("../utils/semver");
var packages = require("../utils/packages");
var registry = require("../utils/registry");
var {Resolver, Resolved} = require("../utils/resolver");
var {indent} = require("../utils/strings");
var log = require("ringo/logging").getLogger(module.id);
var {proceed} = require("../utils/shell");

//argument parser
var parser = new Parser();
parser.addOption("g", "global", null, "Update globally installed packages");

exports.description = "Updates installed packages";

exports.help = function help() {
    term.writeln("\n" + exports.description, "\n");
    term.writeln("Usage:");
    term.writeln("  rp update [options] [<name> [<name> ...]]");
    term.writeln("\nOptions:");
    term.writeln(parser.help());
    term.writeln();
};

exports.update = function(args) {
    var opts = {};
    try {
        parser.parse(args, opts);
    } catch (e) {
        term.writeln(term.RED, e.message, term.RESET);
        term.writeln("Available options:");
        term.writeln(parser.help());
        return;
    }

    var dir = packages[(opts.global === true) ? "getGlobalDir" : "getLocalDir"]();
    var packagesDir = packages.getPackagesDir(dir);
    if (!fs.exists(packagesDir)) {
        log.debug(packagesDir, "does not exist");
        term.writeln("No packages found (wrong directory?)");
        return false;
    }
    log.debug("Updating packages in", packagesDir);
    var descriptor = packages.getDescriptor(dir);
    var resolver;
    if (descriptor !== null && descriptor.hasOwnProperty("dependencies")) {
        term.writeln("Resolving dependencies of", descriptor.name, "...");
        resolver = resolvePackages(Object.keys(descriptor.dependencies),
            descriptor.dependencies);
    } else {
        term.writeln("Resolving packages installed in", packagesDir, "...");
        resolver = resolvePackages(getInstalled(packagesDir));
    }
    var resolved = resolver.getDescriptors();
    if (args.length > 0) {
        log.debug("Reducing packages to:", args.join(", "));
        resolved = resolved.filter(function(descriptor) {
            return args.indexOf(descriptor.name) > -1;
        });
    }
    var toInstall = filterUpdateable(packagesDir, resolved);
    if (toInstall.length > 0) {
        installPackages(packagesDir, toInstall);
    }
};

var resolvePackages = function(names, ranges) {
    var resolver = new Resolver(registry);
    ranges = ranges || {};
    for each (let name in names) {
        try {
            resolver.resolve(name, ranges[name]);
        } catch (e) {
            term.writeln(term.RED, e.message, term.RESET);
        }
    }
    return resolver;
};

var getInstalled = function(packagesDir) {
    return fs.list(packagesDir).filter(function(name) {
        if (name.charAt(0) === ".") {
            log.debug("ignoring", name);
            return false;
        }
        let dir = fs.join(packagesDir, name);
        if (fs.isFile(dir)) {
            log.debug("ignoring", dir, "- it's a file");
            return false;
        } else if (fs.isLink(dir)) {
            log.debug("ignoring", dir, "linking to", fs.readLink(dir));
            term.writeln(term.YELLOW, "Ignoring symlinked package", fs.base(dir), term.RESET);
            return false;
        }
        let descriptor = packages.getDescriptor(dir);
        if (!descriptor) {
            log.debug("ignoring", dir, "- doesn't containg a package descriptor");
            return false;
        } else if (descriptor.name !== name) {
            log.debug("ignoring", dir, "- it contains", descriptor.name,
                    descriptor.version);
            return false;
        }
        return true;
    });
};

var filterUpdateable = function(packagesDir, descriptors) {
    return descriptors.filter(function(descriptor) {
        var result = packages.isUpdateable(packagesDir, descriptor.name, descriptor.version);
        if (result !== packages.OK) {
            var packageDir = fs.normal(fs.join(packagesDir, descriptor.name));
            term.write(term.RED);
            if (result === packages.ERR_ISFILE) {
                term.write("Can't update", descriptor.name,
                        "because a file with the same name exists in", packagesDir);
            } else if (result === packages.ERR_ISLINK) {
                term.write("Can't update", descriptor.name, "- it's a symlink to",
                        fs.readLink(packageDir));
            } else if (result === packages.ERR_NOPACKAGE) {
                term.write(term.RED, "Can't update", descriptor.name, "because",
                        packageDir, "doesn't contain a valid package");
            } else if (result === packages.ERR_RENAMED) {
                let descriptor = packages.getDescriptor(packageDir);
                term.write(packageDir, "contains", descriptor.name,
                        descriptor.version);
            } else if (result === packages.ERR_SAMEVERSION) {
                let descriptor = packages.getDescriptor(packageDir);
                term.write(term.GREEN, descriptor.name,
                        "is already the latest version (" + descriptor.version + ")");
            }
            term.writeln(term.RESET);
        }
        return result === packages.OK;
    });
};

var installPackages = function(packagesDir, descriptors) {
    term.writeln(term.BOLD, "\nAbout to update/install in", packagesDir + ":",
            term.RESET);
    for each (let descriptor in descriptors) {
        let current = packages.getDescriptor(packagesDir, descriptor.name);
        if (current === null) {
            term.writeln(indent(descriptor.name, 1), descriptor.version);
        } else {
            term.writeln(indent(descriptor.name, 1), "(" + current.version,
                    "->", descriptor.version + ")");
        }
    }
    if (!proceed("n")) {
        term.writeln("Cancelled");
    } else {
        descriptors.forEach(function(descriptor) {
            installPackage(packagesDir, descriptor);
        });
    }
};

var installPackage = function(dir, descriptor) {
    var file = null;
    var tmpInstallDir = null;
    var installDir = fs.join(dir, descriptor.name);
    try {
        term.writeln("Downloading", descriptor.name, descriptor.version, "...");
        file = registry.getPackage(descriptor);
        tmpInstallDir = packages.install(file, dir, descriptor.name + ".tmp",
                descriptor.version);
        if (fs.exists(installDir)) {
            fs.removeTree(installDir);
        }
        fs.move(tmpInstallDir, installDir);
        log.debug("Moved", tmpInstallDir, "to", installDir);
        term.writeln(term.GREEN, "Installed", descriptor.name,
                descriptor.version, "in", installDir, term.RESET);
    } finally {
        // cleanup: remove temporary package archive file and the temporary
        // installation directory (if existing)
        if (file !== null && fs.exists(file)) {
            fs.remove(file);
        }
        if (tmpInstallDir !== null && fs.exists(tmpInstallDir)) {
            fs.removeTree(tmpInstallDir);
        }
    }
};
<|endoftext|>


<commit_before>/**
 * @name Archiver
 * @version 0.1
 * @fileoverview provides extraction and modification functionality for zip archives
 *               uses 7z (on windows and linux), keka (on Mac) or unzip
 */

var unzip = require('unzip');
var fs = require('fs-extra');
var path = require('path');
var exec = require('child_process').exec;
var maxBuffer = 524288;

/**
 * Constructor of Archiver
 * initialises archiver detection
 * @class
 */
function Archiver(path7z) {
    this.sevenZipPath = path7z || "7z";
    this.detectZipArchiver();
}

/**
 * Archiver mode: 7z, 7z64, keka7z, unzip
 * @type {string}
 */
Archiver.prototype.mode = '';

/**
 * Examine which program should be use to modify or extract zip-archives
 */
Archiver.prototype.detectZipArchiver = function () {
    var _self = this;
    exec(_self.sevenZipPath, {maxBuffer: maxBuffer}, function (err) {
        if (!err) {
            _self.mode = '7z';
        } else {
            _self.guessZipArchiver();
        }
    });
};

/**
 * Tries to guess the 7z or keka7z paths
 */
Archiver.prototype.guessZipArchiver = function () {
    this.mode = 'unzip';

    var _path7z, _mode;
    if ((/^win/).test(process.platform)) {
        _path7z = '"C:\\Program Files\\7-Zip\\7z.exe"';
        _mode = '7z64';
    } else if (os.platform() === 'darwin') {
        _path7z = '/Applications/Keka.app/Contents/Resources/keka7z';
        _mode = 'keka7z';
    }

    if (_mode) {
        var _self = this;
        exec(_path7z, {maxBuffer: maxBuffer}, function (err) {
            if (!err) {
                _self.mode = _mode;
                _self.sevenZipPath = _path7z;
            }
        });
    }
};

/**
 * Modify a zip-archive
 *
 * @param {Build} build      - the build object
 * @param {String} modifier  - 7z modifier flag (e.g. a / e / l)
 * @param {String} file      - path to the zip file
 * @param {String} filenames - space separated list of filenames to remove, add,...
 * @param {Object} opts      - additional options for the execution
 * @param {function} done    - callback function
 */
Archiver.prototype.modifyArchive = function (build, modifier, file, filenames, opts, done) {
    var _self = this;
    var verb = modifier === 'a' ? 'adding' : 'removing';
    var into = modifier === 'a' ? 'to' : 'from';
    var errMsg = 'Error {2} {3} {4} archive via {5}\n{6}\n{7}';
    switch (_self.mode) {
        case '7z':
        case '7z64':
        case 'keka7z':
            var _cmd = '{0} {1} -tzip {2} {3}'.format(_self.sevenZipPath, modifier, file, filenames);
            exec(_cmd, opts, function (err, stdout, stderr) {
                if (build.conf.status === 'cancelled') {
                    return;
                }
                if (err) {
                    return _self.buildFailed(build, errMsg, verb, filenames, into, _self.mode, err, stderr);
                }
                done();
            });
            break;
        case 'unzip':
            exec('unzip -uo {0} -d {1} '.format(file, target), opts, function (err, stdout, stderr) {
                stdout && agent.log(build, Msg.debug, '{2}', stdout);
                if (err || stderr) return agent.buildFailed(build, 'error executing unzip\n{2}\n{3}', err, stderr);
                done();
            });
            break;
        default:
            return _self.buildFailed(build, '7z could not be found!');
    }
};

/**
 * Extract a zip-archive
 *
 * @param {Build} build   - the build object
 * @param {String} file   - path to the zip file
 * @param {String} target - path to the target directory
 * @param {Object} opts   - additional options for the execution
 * @param {function} done - callback function
 */
Archiver.prototype.extractArchive = function (build, file, target, opts, done) {
    var _self = this;
    switch (_self.mode) {
        case '7z':
        case '7z64':
        case 'keka7z':
            var _cmd = '{0} x {1} -o{2} -y'.format(_self.sevenZipPath, file, target);
            exec(_cmd, opts, function (err, stdout, stderr) {
                if (build.conf.status === 'cancelled') {
                    return;
                }
                if (err) {
                    return _self.buildFailed(build, 'Error executing {2}:\nCMD:{3}\nOpts:{4}\nStdout:{5}\nErr:{6}\nStdErr:{7}', _self.sevenZipPath, cmd, JSON.stringify(opts), stdout, err, stderr);
                }
                done();
            });
            break;
        case 'unzip':
            var extrator = unzip.Extract({path: path.resolve(target)});
            fs.createReadStream(file).pipe(extrator);
            extrator.on('error', function (err) {
                if (err) {
                    return _self.buildFailed(build, 'Error unzipping {2}:\nTarget:{3}\nErr:{4}', file, target, err);
                } else {
                    return _self.buildFailed(build, 'Error unzipping {2}:\nTarget:{3}\nError is not available!', file, target);
                }
            });
            extrator.on('close', function () {
                if (build.conf.status === 'cancelled') {
                    return;
                }
                done();
            });
            break;
        default:
            return _self.buildFailed(build, '7z could not be found!');
    }
};

module.exports = Archiver;<commit_msg>satisfy jshint<commit_after>/**
 * @name Archiver
 * @version 0.1
 * @fileoverview provides extraction and modification functionality for zip archives
 *               uses 7z (on windows and linux), keka (on Mac) or unzip
 */

var unzip = require('unzip');
var fs = require('fs-extra');
var path = require('path');
var exec = require('child_process').exec;
var maxBuffer = 524288;

/**
 * Constructor of Archiver
 * initialises archiver detection
 * @class
 */
function Archiver(path7z) {
    this.sevenZipPath = path7z || "7z";
    this.detectZipArchiver();
}

/**
 * Archiver mode: 7z, 7z64, keka7z, unzip
 * @type {string}
 */
Archiver.prototype.mode = '';

/**
 * Examine which program should be use to modify or extract zip-archives
 */
Archiver.prototype.detectZipArchiver = function () {
    var _self = this;
    exec(_self.sevenZipPath, {maxBuffer: maxBuffer}, function (err) {
        if (!err) {
            _self.mode = '7z';
        } else {
            _self.guessZipArchiver();
        }
    });
};

/**
 * Tries to guess the 7z or keka7z paths
 */
Archiver.prototype.guessZipArchiver = function () {
    this.mode = 'unzip';

    var _path7z, _mode;
    if ((/^win/).test(process.platform)) {
        _path7z = '"C:\\Program Files\\7-Zip\\7z.exe"';
        _mode = '7z64';
    } else if (os.platform() === 'darwin') {
        _path7z = '/Applications/Keka.app/Contents/Resources/keka7z';
        _mode = 'keka7z';
    }

    if (_mode) {
        var _self = this;
        exec(_path7z, {maxBuffer: maxBuffer}, function (err) {
            if (!err) {
                _self.mode = _mode;
                _self.sevenZipPath = _path7z;
            }
        });
    }
};

/**
 * Modify a zip-archive
 *
 * @param {Build} build      - the build object
 * @param {String} modifier  - 7z modifier flag (e.g. a / e / l)
 * @param {String} file      - path to the zip file
 * @param {String} filenames - space separated list of filenames to remove, add,...
 * @param {Object} opts      - additional options for the execution
 * @param {function} done    - callback function
 */
Archiver.prototype.modifyArchive = function (build, modifier, file, filenames, opts, done) {
    var _self = this;
    var verb = modifier === 'a' ? 'adding' : 'removing';
    var into = modifier === 'a' ? 'to' : 'from';
    var errMsg = 'Error {2} {3} {4} archive via {5}\n{6}\n{7}';
    switch (_self.mode) {
        case '7z':
        case '7z64':
        case 'keka7z':
            var _cmd = '{0} {1} -tzip {2} {3}'.format(_self.sevenZipPath, modifier, file, filenames);
            exec(_cmd, opts, function (err, stdout, stderr) {
                if (build.conf.status === 'cancelled') {
                    return;
                }
                if (err) {
                    return _self.buildFailed(build, errMsg, verb, filenames, into, _self.mode, err, stderr);
                }
                done();
            });
            break;
        case 'unzip':
            exec('unzip -uo {0} -d {1} '.format(file, target), opts, function (err, stdout, stderr) {
                if (stdout) {
                    agent.log(build, Msg.debug, '{2}', stdout);
                }
                if (err || stderr) {
                    return agent.buildFailed(build, 'error executing unzip\n{2}\n{3}', err, stderr);
                }
                done();
            });
            break;
        default:
            return _self.buildFailed(build, '7z could not be found!');
    }
};

/**
 * Extract a zip-archive
 *
 * @param {Build} build   - the build object
 * @param {String} file   - path to the zip file
 * @param {String} target - path to the target directory
 * @param {Object} opts   - additional options for the execution
 * @param {function} done - callback function
 */
Archiver.prototype.extractArchive = function (build, file, target, opts, done) {
    var _self = this;
    switch (_self.mode) {
        case '7z':
        case '7z64':
        case 'keka7z':
            var _cmd = '{0} x {1} -o{2} -y'.format(_self.sevenZipPath, file, target);
            exec(_cmd, opts, function (err, stdout, stderr) {
                if (build.conf.status === 'cancelled') {
                    return;
                }
                if (err) {
                    return _self.buildFailed(build, 'Error executing {2}:\nCMD:{3}\nOpts:{4}\nStdout:{5}\nErr:{6}\nStdErr:{7}', _self.sevenZipPath, cmd, JSON.stringify(opts), stdout, err, stderr);
                }
                done();
            });
            break;
        case 'unzip':
            var extrator = unzip.Extract({path: path.resolve(target)});
            fs.createReadStream(file).pipe(extrator);
            extrator.on('error', function (err) {
                if (err) {
                    return _self.buildFailed(build, 'Error unzipping {2}:\nTarget:{3}\nErr:{4}', file, target, err);
                } else {
                    return _self.buildFailed(build, 'Error unzipping {2}:\nTarget:{3}\nError is not available!', file, target);
                }
            });
            extrator.on('close', function () {
                if (build.conf.status === 'cancelled') {
                    return;
                }
                done();
            });
            break;
        default:
            return _self.buildFailed(build, '7z could not be found!');
    }
};

module.exports = Archiver;<|endoftext|>


<commit_before>// Copyright (c) 2019, Compiler Explorer Team
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
//     * Redistributions of source code must retain the above copyright notice,
//       this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above copyright
//       notice, this list of conditions and the following disclaimer in the
//       documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.

const
    BaseCompiler = require('../base-compiler'),
    fs = require('fs-extra'),
    path = require('path'),
    logger = require('../logger').logger;

class CleanCompiler extends BaseCompiler {
    optionsForFilter(filters, outputFilename) {
        if (filters.binary) {
			return [];
        } else {
            return ['-S'];
        }
    }

    getOutputFilename(dirPath, outputFilebase) {
        return path.join(dirPath, "Clean System Files/example.s");
    }

    runCompiler(compiler, options, inputFilename, execOptions) {
        const tmpDir = path.dirname(inputFilename);
		const moduleName = path.basename(inputFilename, '.icl');
		const compilerPath = path.dirname(compiler);
        execOptions = this.getDefaultExecOptions();
        execOptions.customCwd = tmpDir;
		execOptions.env.CLEANLIB = path.join(compilerPath, "../exe");
		execOptions.env.CLEANPATH = this.compiler.libPath;
        options.pop();
        options.push(moduleName);
        return super.runCompiler(compiler, options, moduleName, execOptions).then(result => {
            if (fs.existsSync(this.getOutputFilename(tmpDir))) {
                result.code = 0;
            }
            return result;
        });
    }
}

module.exports = CleanCompiler;
<commit_msg>bintest<commit_after>// Copyright (c) 2019, Compiler Explorer Team
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
//     * Redistributions of source code must retain the above copyright notice,
//       this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above copyright
//       notice, this list of conditions and the following disclaimer in the
//       documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.

const
    BaseCompiler = require('../base-compiler'),
    fs = require('fs-extra'),
    path = require('path'),
    logger = require('../logger').logger;

class CleanCompiler extends BaseCompiler {
    optionsForFilter(filters, outputFilename) {
        if (filters.binary) {
			return [];
        } else {
            return ['-S'];
        }
    }

    getOutputFilename(dirPath, outputFilebase) {
        return path.join(dirPath, "Clean System Files/example.s");
    }

    objdump(outputFilename, result, maxSize, intelAsm, demangle) {
        logger.info(outputFilename);
        let args = ["-d", outputFilename, "-l", "--insn-width=16"];
        if (demangle) args = args.concat("-C");
        if (intelAsm) args = args.concat(["-M", "intel"]);
        return this.exec(this.compiler.objdumper, args, {maxOutput: maxSize})
            .then(objResult => {
                result.asm = objResult.stdout;
                if (objResult.code !== 0) {
                    result.asm = `<No output: objdump returned ${objResult.code}>`;
                }
                return result;
            });
    }

    runCompiler(compiler, options, inputFilename, execOptions) {
        const tmpDir = path.dirname(inputFilename);
		const moduleName = path.basename(inputFilename, '.icl');
		const compilerPath = path.dirname(compiler);
        execOptions = this.getDefaultExecOptions();
        execOptions.customCwd = tmpDir;
		execOptions.env.CLEANLIB = path.join(compilerPath, "../exe");
		execOptions.env.CLEANPATH = this.compiler.libPath;
        options.pop();
        options.push(moduleName);
        return super.runCompiler(compiler, options, moduleName, execOptions).then(result => {
            if (fs.existsSync(this.getOutputFilename(tmpDir))) {
                result.code = 0;
            }
            return result;
        });
    }
}

module.exports = CleanCompiler;
<|endoftext|>