<commit_before>/*
 * grunt-amd-tamer
 * https://github.com/freezedev/grunt-amd-tamer
 *
 */

'use strict';

var path = require('path');
var SourceMapConcat = require('sourcemap-concat').SourceMapConcatenator;

module.exports = function(grunt) {

  // Please see the Grunt documentation for more information regarding task
  // creation: http://gruntjs.com/creating-tasks

  grunt.registerMultiTask('amd_tamer', 'Tame your AMD modules', function() {
    // Merge task-specific and/or target-specific options with these defaults.
    var options = this.options({
      separator: grunt.util.linefeed,
      normalizeIndexFile: true,
      base: null,
      doubleQuotes: false,
      namespace: null,
      sourceMap: true,
      processName: function(name /*, basename */) {
        return name;
      },
      process: function(content /*, moduleName */) {
      	return content;
      },
      shim: {},
      modules: {},
      blacklist: []
    });

    var quotes = (options.doubleQuotes) ? '"' : '\'';

    // Iterate over all specified file groups.
    this.files.forEach(function(f) {

      var sourceMapConcat = new SourceMapConcat({file: f.dest});

      // Concat specified files.
      var src = f.src.filter(function(filepath) {
        // Warn on and remove invalid source files (if nonull was set).
        if (!grunt.file.exists(filepath)) {
          grunt.log.warn('Source file "' + filepath + '" not found.');
          return false;
        } else {
          return true;
        }
      }).map(function(filepath) {
        // Read file source.
        var source = grunt.file.read(filepath);
        var extension = path.extname(filepath);
        var isCoffeeScript = (extension === '.coffee');

        var moduleName = filepath.split(extension)[0];
        if (options.base && moduleName.indexOf(options.base) === 0) {
          moduleName = moduleName.split(options.base)[1];
        }

        if (options.normalizeIndexFile && moduleName.indexOf('/index') > 0) {
          moduleName = moduleName.replace('/index', '');
        }

        if (options.namespace) {
          // If index.js is in the root folder and a namespace has been defined
          // use the namespace as the module name
          if (options.normalizeIndexFile && moduleName === 'index') {
            moduleName = options.namespace;
          } else {
            moduleName = options.namespace + '/' + moduleName;
          }
        }

        moduleName = options.processName(moduleName, path.basename(moduleName));

        var defineStatement = 'define(';

        var defineStartPos = source.indexOf(defineStatement);
        var defineIndex = defineStartPos + defineStatement.length;

        if (isCoffeeScript && defineStartPos === -1) {
          defineStartPos = source.indexOf('define ');
          defineIndex = defineStartPos + defineStatement.length;
          defineStatement = 'define ';
        }

        var quoteIndex = source.substr(defineIndex).search(/('|")/);

        var abortProcessing = false;
        var abortCondition = false;

        if (defineStartPos === -1) {
          abortCondition = true;
        } else {
          if (quoteIndex >= 0 && source.substr(defineIndex, quoteIndex).trim().length === 0) {
            abortCondition = true;
          }
        }

        if (options.blacklist.indexOf(moduleName) >= 0) {
          abortProcessing = true;
        }

        if (!abortProcessing) {
          if (!abortCondition) {
            source = source.replace(defineStatement, defineStatement + quotes + moduleName + quotes + ', ');
          } else {
            if (source.indexOf(defineStatement) === -1) {
              var deps = '';
              var exports = '';

              if (options.shim[moduleName]) {
                if (options.shim[moduleName].deps) {
                  deps = '[' + options.shim[moduleName].deps.map(function(val) { return quotes + val + quotes; }).join(', ') + '], ';
                }

                if (options.shim[moduleName].exports) {
                  if (typeof options.shim[moduleName].exports === 'function') {
                    exports = options.shim[moduleName].exports;
                  } else {
                    if (isCoffeeScript) {
                      exports = 'root.' + options.shim[moduleName].exports;
                    } else {
                      exports = 'return root.' + options.shim[moduleName].exports + ';';
                    }
                  }
                }
              }

              source += '\n';

              if (exports) {
                if (isCoffeeScript) {
                  source += '\ndo (root) ->';
                } else {
                  source += '\n(function(root) {';
                }
              }
              source += '\n';
              if (exports) {
                source += '\t';
              }

              if (isCoffeeScript) {
                source += 'define(' + quotes + moduleName + quotes + ', ' + deps + '-> ' + exports + ' )';
              } else {
                if (exports && typeof exports === 'function') {
                  source += 'define(' + quotes + moduleName + quotes + ', ' + deps + exports.toString() + ');';
                } else {
                  source += 'define(' + quotes + moduleName + quotes + ', ' + deps + 'function() { ' + exports + ' });';
                }
              }

              if (exports && !isCoffeeScript) {
                source += '\n})(this);';
              }
            }
          }
        }

        source = options.process(source, moduleName);

        if (options.sourceMap) {
          var prevSourceMap;
          if (grunt.file.exists(filepath + '.map')) {
            prevSourceMap = grunt.file.read(filepath + '.map');
          }

          sourceMapConcat.add(filepath, source, prevSourceMap);
        }

        return source;
      }).join(grunt.util.normalizelf(options.separator));

      var modules = options.modules;

      var moduleKeys = Object.keys(modules);

      for (var i = 0, j = moduleKeys.length; i < j; i++) {
        (function(key, value) {
          src += 'define(' + quotes + key + quotes + ', ' + value.toString() + ');';
        })(moduleKeys[i], modules[moduleKeys[i]]);
      }

      // Write the destination file.
      grunt.file.write(f.dest, src);

      if (options.sourceMap) {
        grunt.file.write(f.dest + '.map', sourceMapConcat.sourceMap);
      }

      // Print a success message.
      grunt.log.writeln('File "' + f.dest + '" created.');
    });
  });

};
<commit_msg>Fixes a critical bug when the source map was already provided<commit_after>/*
 * grunt-amd-tamer
 * https://github.com/freezedev/grunt-amd-tamer
 *
 */

'use strict';

var path = require('path');
var SourceMapConcat = require('sourcemap-concat').SourceMapConcatenator;

module.exports = function(grunt) {

  // Please see the Grunt documentation for more information regarding task
  // creation: http://gruntjs.com/creating-tasks

  grunt.registerMultiTask('amd_tamer', 'Tame your AMD modules', function() {
    // Merge task-specific and/or target-specific options with these defaults.
    var options = this.options({
      separator: grunt.util.linefeed,
      normalizeIndexFile: true,
      base: null,
      doubleQuotes: false,
      namespace: null,
      sourceMap: true,
      processName: function(name /*, basename */) {
        return name;
      },
      process: function(content /*, moduleName */) {
      	return content;
      },
      shim: {},
      modules: {},
      blacklist: []
    });

    var quotes = (options.doubleQuotes) ? '"' : '\'';

    // Iterate over all specified file groups.
    this.files.forEach(function(f) {

      var sourceMapConcat = new SourceMapConcat({file: f.dest});

      // Concat specified files.
      var src = f.src.filter(function(filepath) {
        // Warn on and remove invalid source files (if nonull was set).
        if (!grunt.file.exists(filepath)) {
          grunt.log.warn('Source file "' + filepath + '" not found.');
          return false;
        } else {
          return true;
        }
      }).map(function(filepath) {
        // Read file source.
        var source = grunt.file.read(filepath);
        var extension = path.extname(filepath);
        var isCoffeeScript = (extension === '.coffee');

        var moduleName = filepath.split(extension)[0];
        if (options.base && moduleName.indexOf(options.base) === 0) {
          moduleName = moduleName.split(options.base)[1];
        }

        if (options.normalizeIndexFile && moduleName.indexOf('/index') > 0) {
          moduleName = moduleName.replace('/index', '');
        }

        if (options.namespace) {
          // If index.js is in the root folder and a namespace has been defined
          // use the namespace as the module name
          if (options.normalizeIndexFile && moduleName === 'index') {
            moduleName = options.namespace;
          } else {
            moduleName = options.namespace + '/' + moduleName;
          }
        }

        moduleName = options.processName(moduleName, path.basename(moduleName));

        var defineStatement = 'define(';

        var defineStartPos = source.indexOf(defineStatement);
        var defineIndex = defineStartPos + defineStatement.length;

        if (isCoffeeScript && defineStartPos === -1) {
          defineStartPos = source.indexOf('define ');
          defineIndex = defineStartPos + defineStatement.length;
          defineStatement = 'define ';
        }

        var quoteIndex = source.substr(defineIndex).search(/('|")/);

        var abortProcessing = false;
        var abortCondition = false;

        if (defineStartPos === -1) {
          abortCondition = true;
        } else {
          if (quoteIndex >= 0 && source.substr(defineIndex, quoteIndex).trim().length === 0) {
            abortCondition = true;
          }
        }

        if (options.blacklist.indexOf(moduleName) >= 0) {
          abortProcessing = true;
        }

        if (!abortProcessing) {
          if (!abortCondition) {
            source = source.replace(defineStatement, defineStatement + quotes + moduleName + quotes + ', ');
          } else {
            if (source.indexOf(defineStatement) === -1) {
              var deps = '';
              var exports = '';

              if (options.shim[moduleName]) {
                if (options.shim[moduleName].deps) {
                  deps = '[' + options.shim[moduleName].deps.map(function(val) { return quotes + val + quotes; }).join(', ') + '], ';
                }

                if (options.shim[moduleName].exports) {
                  if (typeof options.shim[moduleName].exports === 'function') {
                    exports = options.shim[moduleName].exports;
                  } else {
                    if (isCoffeeScript) {
                      exports = 'root.' + options.shim[moduleName].exports;
                    } else {
                      exports = 'return root.' + options.shim[moduleName].exports + ';';
                    }
                  }
                }
              }

              source += '\n';

              if (exports) {
                if (isCoffeeScript) {
                  source += '\ndo (root) ->';
                } else {
                  source += '\n(function(root) {';
                }
              }
              source += '\n';
              if (exports) {
                source += '\t';
              }

              if (isCoffeeScript) {
                source += 'define(' + quotes + moduleName + quotes + ', ' + deps + '-> ' + exports + ' )';
              } else {
                if (exports && typeof exports === 'function') {
                  source += 'define(' + quotes + moduleName + quotes + ', ' + deps + exports.toString() + ');';
                } else {
                  source += 'define(' + quotes + moduleName + quotes + ', ' + deps + 'function() { ' + exports + ' });';
                }
              }

              if (exports && !isCoffeeScript) {
                source += '\n})(this);';
              }
            }
          }
        }

        source = options.process(source, moduleName);

        if (options.sourceMap) {
          var prevSourceMap;
          if (grunt.file.exists(filepath + '.map')) {
            prevSourceMap = grunt.file.readJSON(filepath + '.map');
          }

          sourceMapConcat.add(filepath, source, prevSourceMap);
        }

        return source;
      }).join(grunt.util.normalizelf(options.separator));

      var modules = options.modules;

      var moduleKeys = Object.keys(modules);

      for (var i = 0, j = moduleKeys.length; i < j; i++) {
        (function(key, value) {
          src += 'define(' + quotes + key + quotes + ', ' + value.toString() + ');';
        })(moduleKeys[i], modules[moduleKeys[i]]);
      }

      // Write the destination file.
      grunt.file.write(f.dest, src);

      if (options.sourceMap) {
        grunt.file.write(f.dest + '.map', sourceMapConcat.sourceMap);
      }

      // Print a success message.
      grunt.log.writeln('File "' + f.dest + '" created.');
    });
  });

};
<|endoftext|>


<commit_before>'use strict';

module.exports = function(grunt) {
  var azure = require('azure'),
      Q = require('q'),
      util = require('util'),
      path = require('path'),
      zlib = require('zlib'),
      mime = require('mime'),
      fs = require('fs'),
      tmp = require('tmp');

  grunt.registerMultiTask('azureblob', 'Copy html assets to azure blob/cdn storage', function() {
    // Merge task-specific and/or target-specific options with these defaults.
    var options = this.options({
        serviceOptions: [], // custom arguments to azure.createBlobService
        containerName: null, // container name, required
        containerDelete: false, // deletes container if it exists
        containerOptions: {publicAccessLevel: "blob", timeoutIntervalInMs: 10000}, // container options
        metadata: {cacheControl: 'public, max-age=31556926'}, // file metadata properties
        copySimulation: false,
        gzip: false, // gzip files
        maxNumberOfConcurrentUploads: 10 // Maximum number of concurrent uploads
      }),
      blobService = azure.createBlobService(),
      done = this.async(),
      self = this;

    grunt.verbose.writeflags(options,'options');
    //tmp.setGracefulCleanup(); //cleanup the temporary files even when an uncaught exception occurs.

    // execute task
    deleteContainer()
      .then(createContainer)
      .then(iterateFiles)
      .then(function(count) {
        grunt.log.write(util.format('blobStorage copy completed (%s) files...',count)).ok();
          done(true); // mark async done completed
        })
      .fail(function(error) {
         // handle any error from deleteContainer, createContainer or processFiles
         grunt.log.error(util.format('Error processing %s', self.nameArgs));
         grunt.fail.fatal(error);
        })
      .done();

    // Iterate each of the defined files and copy to Blob Storage
    // returns a q promise
    function iterateFiles() {
      var deferred = Q.defer(),
        files = self.files.filter(fileExistsAndIsWellFormed); // filesSrc can include dir's, not just files

      grunt.verbose.writeln(util.format('\tprocess (%s) files', files.length));

      // Iterate over all specified file groups, <options.maxNumberOfConcurrentUploads> files at a time
      grunt.util.async.forEachLimit(files, options.maxNumberOfConcurrentUploads, copyFile, function(err){
        if (err) {
          deferred.reject(err);
        }
        deferred.resolve(files.length);
      });

      return deferred.promise;
    }

    // When optioned, delete blob container
    // returns q promise
    function deleteContainer() {
      var deferred = Q.defer();

      if (options.containerDelete && !options.copySimulation) {
        grunt.log.write(util.format('%s - deleting container [%s] ...', self.nameArgs, options.containerName));
        blobService.deleteContainer(options.containerName, {timeoutIntervalInMs:25000}, function(err){
          if (err) {
              grunt.log.writeln(err);
          }
            /* // ignore errors for now - just move on
            if (err) {
              grunt.log.writeln(err);
              deferred.reject(err);
            }
            */
        });
        grunt.log.ok();
        deferred.resolve();
      } else {
        grunt.log.write(util.format('skiping delete of container[%s]...',options.containerName));
        grunt.log.ok();
        deferred.resolve();
      }
      return deferred.promise;
    }

    // Creates Blob container name in options.containerName, if it doesn't already exist
    // returns q promise
    function createContainer() {
      var deferred = Q.defer(),
          completed = false,
          count = 0,
          waitMs = 100,
          maxTry = 10;

      options.containerOptions.timeoutIntervalInMs = options.containerOptions.timeoutIntervalInMs || 15000; // 15sec
      grunt.log.write(util.format('%s - Create blob containter [%s] ...', self.nameArgs, options.containerName));

      if(options.copySimulation){
        completed = true;
        tryCallback();
      } else {
        grunt.util.async.whilst(continueAttempts, tryCreate, tryCallback);
      }

      return deferred.promise;

      function continueAttempts() {
        return ((count < maxTry) && !completed); // sync truth test before each execution of fn
      }
      function tryCreate(callback) {
        count++;
        setTimeout(function() {
              grunt.log.write('.');
              blobService.createContainerIfNotExists(options.containerName, options.containerOptions, function(error){
                  if (error) {
                    if (error.code !== 'ContainerBeingDeleted') {
                      callback(error); // error - abort
                    } else {
                      callback();
                    }
                  } else {
                    completed = true;
                    callback(); // success
                  }
              });
            }, waitMs);
         waitMs = 10000; // up the wait-time after the initial attempt
      }
      function tryCallback(err){
        var errorMessage = err || '[ no error reason given]';
        if (completed) {
            grunt.log.ok();
            deferred.resolve();
          } else {
            grunt.log.writeln('! createContainer not completed !');
            grunt.log.error(errorMessage);
            deferred.reject(errorMessage);
          }
      }
    }

    // Iterator called from grunt.util.async.forEachLimit - for each source file in task
    function copyFile(file, callback) {
      var source = file.src,
          destination = file.dest,
          meta = options.metadata,
          srcFile = path.basename(source),
          gzip = options.gzip,
          fileExt = path.extname(source),
          fnCopyToBlob;

      // configure proper azure metadata for file
      meta.contentType = mime.lookup(source);
      meta.contentTypeHeader =  mime.lookup(source);
      meta.contentEncoding =  gzip ? 'gzip': null;

      var logMessage = util.format('\tCopy %s => %s/%s ', srcFile, options.containerName, destination);

      if(options.copySimulation){
        grunt.log.write(logMessage);
        grunt.log.ok('skip copy ok');
        callback();
        return;
      }

      fnCopyToBlob = gzip ? compressFileToBlobStorage : copyFileToBlobStorage; // use correct fn to pre-compress

      Q.when(fnCopyToBlob(options.containerName, destination, source, meta))
        .then(function(){
            grunt.log.write(logMessage); // We have to save logging about the file upload until here since
                                         // we are iterating over many files concurrently. Otherwise the
                                         // log output becomes interleaved and therefore unintelligible.
            grunt.log.ok();
            callback();
        }).done();
    }

    function compressFileToBlobStorage(containerName, destFileName, sourceFile, metadata) {
      return gzipFile(sourceFile)
              .then(function(tmpFile) {
                return copyFileToBlobStorage(containerName, destFileName, tmpFile, metadata)
                        .finally(function(){
                          fs.unlinkSync(tmpFile);
                        });
              });
    }

    function copyFileToBlobStorage(containerName, destFileName, sourceFile, metadata) {
      var deferred = Q.defer();
      blobService.createBlockBlobFromFile(containerName, destFileName, sourceFile, metadata, function(err) {
        if (err) {
          grunt.log.error(err);
          deferred.reject(err);
        } else {
          deferred.resolve();
        }
      });
      return deferred.promise;
    }

    function gzipFile(source){
      var deferred = Q.defer(),
        gzip = zlib.createGzip(),
        fileExt = path.extname(source),
        inp,
        out;

      gzip.on('error', function(err) {
        grunt.log.error(err);
        grunt.fail.warn('Gziping failed.');
        deferred.reject(err);
      });

      tmp.tmpName({ template: 'tmp-XXXXXX' + fileExt }, function(err, tempFile) {
        if (err) {
          deferred.reject(err);
        }

        inp = fs.createReadStream(source);

        out = fs.createWriteStream(tempFile);
        out.on('close', function() {
          deferred.resolve(tempFile); // once file closes, file is written and available.
        });
        inp.pipe(gzip).pipe(out);
        //inp.pipe(out); // test to just copy file
      });
      return deferred.promise;
    }

    function fileExistsAndIsWellFormed(file) {
      if (file.src.length !== 1) {
        grunt.fail.warn('File mapping must contain exactly one source to one destination.');
      }

      file.src = file.src[0];

      return fs.statSync(file.src).isFile() && fs.existsSync(file.src);
    }

  });
};
<commit_msg>Update azureblob.js<commit_after>/*
 * grunt-azureblob
 * https://github.com/jstott/grunt-azureblob//
 *
 * Copyright (c) 2013 James Stott, contributors
 * Licensed under the MIT license.
 */

'use strict';

module.exports = function(grunt) {
  var azure = require('azure'),
      Q = require('q'),
      util = require('util'),
      path = require('path'),
      zlib = require('zlib'),
      mime = require('mime'),
      fs = require('fs'),
      tmp = require('tmp');

  grunt.registerMultiTask('azureblob', 'Copy html assets to azure blob/cdn storage', function() {
    // Merge task-specific and/or target-specific options with these defaults.
    var options = this.options({
        serviceOptions: [], // custom arguments to azure.createBlobService
        containerName: null, // container name, required
        containerDelete: false, // deletes container if it exists
        containerOptions: {publicAccessLevel: "blob", timeoutIntervalInMs: 10000}, // container options
        metadata: {cacheControl: 'public, max-age=31556926'}, // file metadata properties
        copySimulation: false,
        gzip: false, // gzip files
        maxNumberOfConcurrentUploads: 10 // Maximum number of concurrent uploads
      }),
      blobService = azure.createBlobService(),
      done = this.async(),
      self = this;

    grunt.verbose.writeflags(options,'options');
    //tmp.setGracefulCleanup(); //cleanup the temporary files even when an uncaught exception occurs.

    // execute task
    deleteContainer()
      .then(createContainer)
      .then(iterateFiles)
      .then(function(count) {
        grunt.log.write(util.format('blobStorage copy completed (%s) files...',count)).ok();
          done(true); // mark async done completed
        })
      .fail(function(error) {
         // handle any error from deleteContainer, createContainer or processFiles
         grunt.log.error(util.format('Error processing %s', self.nameArgs));
         grunt.fail.fatal(error);
        })
      .done();

    // Iterate each of the defined files and copy to Blob Storage
    // returns a q promise
    function iterateFiles() {
      var deferred = Q.defer(),
        files = self.files.filter(fileExistsAndIsWellFormed); // filesSrc can include dir's, not just files

      grunt.verbose.writeln(util.format('\tprocess (%s) files', files.length));

      // Iterate over all specified file groups, <options.maxNumberOfConcurrentUploads> files at a time
      grunt.util.async.forEachLimit(files, options.maxNumberOfConcurrentUploads, copyFile, function(err){
        if (err) {
          deferred.reject(err);
        }
        deferred.resolve(files.length);
      });

      return deferred.promise;
    }

    // When optioned, delete blob container
    // returns q promise
    function deleteContainer() {
      var deferred = Q.defer();

      if (options.containerDelete && !options.copySimulation) {
        grunt.log.write(util.format('%s - deleting container [%s] ...', self.nameArgs, options.containerName));
        blobService.deleteContainer(options.containerName, {timeoutIntervalInMs:25000}, function(err){
          if (err) {
              grunt.log.writeln(err);
          }
            /* // ignore errors for now - just move on
            if (err) {
              grunt.log.writeln(err);
              deferred.reject(err);
            }
            */
        });
        grunt.log.ok();
        deferred.resolve();
      } else {
        grunt.log.write(util.format('skiping delete of container[%s]...',options.containerName));
        grunt.log.ok();
        deferred.resolve();
      }
      return deferred.promise;
    }

    // Creates Blob container name in options.containerName, if it doesn't already exist
    // returns q promise
    function createContainer() {
      var deferred = Q.defer(),
          completed = false,
          count = 0,
          waitMs = 100,
          maxTry = 10;

      options.containerOptions.timeoutIntervalInMs = options.containerOptions.timeoutIntervalInMs || 15000; // 15sec
      grunt.log.write(util.format('%s - Create blob containter [%s] ...', self.nameArgs, options.containerName));

      if(options.copySimulation){
        completed = true;
        tryCallback();
      } else {
        grunt.util.async.whilst(continueAttempts, tryCreate, tryCallback);
      }

      return deferred.promise;

      function continueAttempts() {
        return ((count < maxTry) && !completed); // sync truth test before each execution of fn
      }
      function tryCreate(callback) {
        count++;
        setTimeout(function() {
              grunt.log.write('.');
              blobService.createContainerIfNotExists(options.containerName, options.containerOptions, function(error){
                  if (error) {
                    if (error.code !== 'ContainerBeingDeleted') {
                      callback(error); // error - abort
                    } else {
                      callback();
                    }
                  } else {
                    completed = true;
                    callback(); // success
                  }
              });
            }, waitMs);
         waitMs = 10000; // up the wait-time after the initial attempt
      }
      function tryCallback(err){
        var errorMessage = err || '[ no error reason given]';
        if (completed) {
            grunt.log.ok();
            deferred.resolve();
          } else {
            grunt.log.writeln('! createContainer not completed !');
            grunt.log.error(errorMessage);
            deferred.reject(errorMessage);
          }
      }
    }

    // Iterator called from grunt.util.async.forEachLimit - for each source file in task
    function copyFile(file, callback) {
      var source = file.src,
          destination = file.dest,
          meta = options.metadata,
          srcFile = path.basename(source),
          gzip = options.gzip,
          fileExt = path.extname(source),
          fnCopyToBlob;

      // configure proper azure metadata for file
      meta.contentType = mime.lookup(source);
      meta.contentTypeHeader =  mime.lookup(source);
      meta.contentEncoding =  gzip ? 'gzip': null;

      var logMessage = util.format('\tCopy %s => %s/%s ', srcFile, options.containerName, destination);

      if(options.copySimulation){
        grunt.log.write(logMessage);
        grunt.log.ok('skip copy ok');
        callback();
        return;
      }

      fnCopyToBlob = gzip ? compressFileToBlobStorage : copyFileToBlobStorage; // use correct fn to pre-compress

      Q.when(fnCopyToBlob(options.containerName, destination, source, meta))
        .then(function(){
            grunt.log.write(logMessage); // We have to save logging about the file upload until here since
                                         // we are iterating over many files concurrently. Otherwise the
                                         // log output becomes interleaved and therefore unintelligible.
            grunt.log.ok();
            callback();
        }).done();
    }

    function compressFileToBlobStorage(containerName, destFileName, sourceFile, metadata) {
      return gzipFile(sourceFile)
              .then(function(tmpFile) {
                return copyFileToBlobStorage(containerName, destFileName, tmpFile, metadata)
                        .finally(function(){
                          fs.unlinkSync(tmpFile);
                        });
              });
    }

    function copyFileToBlobStorage(containerName, destFileName, sourceFile, metadata) {
      var deferred = Q.defer();
      blobService.createBlockBlobFromFile(containerName, destFileName, sourceFile, metadata, function(err) {
        if (err) {
          grunt.log.error(err);
          deferred.reject(err);
        } else {
          deferred.resolve();
        }
      });
      return deferred.promise;
    }

    function gzipFile(source){
      var deferred = Q.defer(),
        gzip = zlib.createGzip(),
        fileExt = path.extname(source),
        inp,
        out;

      gzip.on('error', function(err) {
        grunt.log.error(err);
        grunt.fail.warn('Gziping failed.');
        deferred.reject(err);
      });

      tmp.tmpName({ template: 'tmp-XXXXXX' + fileExt }, function(err, tempFile) {
        if (err) {
          deferred.reject(err);
        }

        inp = fs.createReadStream(source);

        out = fs.createWriteStream(tempFile);
        out.on('close', function() {
          deferred.resolve(tempFile); // once file closes, file is written and available.
        });
        inp.pipe(gzip).pipe(out);
        //inp.pipe(out); // test to just copy file
      });
      return deferred.promise;
    }

    function fileExistsAndIsWellFormed(file) {
      if (file.src.length !== 1) {
        grunt.fail.warn('File mapping must contain exactly one source to one destination.');
      }

      file.src = file.src[0];

      return fs.statSync(file.src).isFile() && fs.existsSync(file.src);
    }

  });
};
<|endoftext|>


<commit_before>'use strict';

var gulp = require('gulp'),
    config = require('../../config'),
    plumber = require('gulp-plumber'),
    sourcemap = require('gulp-sourcemaps'),
    sass = require('gulp-sass'),
    normalize = require('node-normalize-scss').includePaths,
    postcss = require('gulp-postcss'),
    bulksass = require('gulp-sass-bulk-import'),
    mqpacker = require('css-mqpacker'),
    autoprefix = require('autoprefixer'),
    pxtorem = require('postcss-pxtorem'),
    cssnano = require('cssnano'),
    banner = require('postcss-banner'),
    notify = require('gulp-notify');

module.exports = function() {
    var key,
        postProcessors,
        themeHeader = '',
        themeHeaderArr = {
            // 'Header Name': 'Key under config.theme',
            'Theme Name': 'name',
            'Theme URI': 'themeuri',
            Author: 'author',
            'Author URI': 'authoruri',
            Description: 'description',
            Version: 'version',
            Status: 'status',
            License: 'license',
            'License URI': 'licenseuri',
            Tags: 'tags',
            'Text Domain': 'textdomain',
            'Domain Path': 'domainpath',
            Template: 'template'
        };

    // Loop through above object properties.
    for ( key in themeHeaderArr ) {
        // If a value has been set in config.theme.???, ...
        if ( config.theme[themeHeaderArr[key]] ) {
            // Then build the file header for it.
            themeHeader += key + ': ' + config.theme[themeHeaderArr[key]] + '\n';
        }
    }

    if ( config.theme.notes ) {
        themeHeader += '\n' + config.theme.notes;
    }

    // Remove final new line character.
    themeHeader = themeHeader.slice(0, -1);

    postProcessors = [
        mqpacker({
            sort: true
        }),
        autoprefix(),
        pxtorem({
            root_value: config.css.basefontsize,
            replace: false,
            media_query: true
        }),
        cssnano(),
        banner({
            banner: themeHeader
        })
    ];

    // Don't minify if expanded CSS is desired.
    if ( 'expanded' === config.css.outputStyle ) {
        postProcessors.splice(3, 1); // 3, as cssnano() is the 3rd item in the zero-based array above.
    }

    return gulp
        .src(config.src.scss)
        .pipe(bulksass())
        .pipe(plumber())
        .pipe(sourcemap.init())
        .pipe(sass.sync({
            outputStyle: config.css.outputStyle,
            includePaths: [].concat(normalize)
        }))
        .pipe(postcss(postProcessors))
        .pipe(sourcemap.write('.'))
        .pipe(gulp.dest(config.dest.css))
        .pipe(notify({message: config.messages.css}));
};
<commit_msg>Basic scaffolding of CSS task to iterate through config object<commit_after>'use strict';

var gulp = require('gulp'),
    config = require('../../config'),
    plumber = require('gulp-plumber'),
    sourcemap = require('gulp-sourcemaps'),
    sass = require('gulp-sass'),
    normalize = require('node-normalize-scss').includePaths,
    postcss = require('gulp-postcss'),
    bulksass = require('gulp-sass-bulk-import'),
    mqpacker = require('css-mqpacker'),
    autoprefix = require('autoprefixer'),
    pxtorem = require('postcss-pxtorem'),
    cssnano = require('cssnano'),
    banner = require('postcss-banner'),
    notify = require('gulp-notify'),
    map = require('lodash.map'),
    rename = require('gulp-rename');

module.exports = function() {
    var key,
        postProcessors,
        themeHeader = '',
        themeHeaderArr = {
            // 'Header Name': 'Key under config.theme',
            'Theme Name': 'name',
            'Theme URI': 'themeuri',
            Author: 'author',
            'Author URI': 'authoruri',
            Description: 'description',
            Version: 'version',
            Status: 'status',
            License: 'license',
            'License URI': 'licenseuri',
            Tags: 'tags',
            'Text Domain': 'textdomain',
            'Domain Path': 'domainpath',
            Template: 'template'
        };

    // Loop through above object properties.
    for ( key in themeHeaderArr ) {
        // If a value has been set in config.theme.???, ...
        if ( config.theme[themeHeaderArr[key]] ) {
            // Then build the file header for it.
            themeHeader += key + ': ' + config.theme[themeHeaderArr[key]] + '\n';
        }
    }

    if ( config.theme.notes ) {
        themeHeader += '\n' + config.theme.notes;
    }

    // Remove final new line character.
    themeHeader = themeHeader.slice(0, -1);

    postProcessors = [
        mqpacker({
            sort: true
        }),
        autoprefix(),
        pxtorem({
            root_value: config.css.basefontsize,
            replace: false,
            media_query: true
        }),
        cssnano(),
        banner({
            banner: themeHeader
        })
    ];

    // Don't minify if expanded CSS is desired.
    if ( 'expanded' === config.css.outputStyle ) {
        postProcessors.splice(3, 1); // 3, as cssnano() is the 3rd item in the zero-based array above.
    }

    return map(config.scss, function(outputConfig, outputFilename) {
        return gulp
        .src(outputConfig.src)
        .pipe(bulksass())
        .pipe(plumber())
        .pipe(rename(outputFilename))
        .pipe(sourcemap.init())
        .pipe(sass.sync({
            outputStyle: outputConfig.outputStyle,
            includePaths: [].concat(normalize)
        }))
        .pipe(postcss(postProcessors))
        .pipe(sourcemap.write(outputConfig.dest))
        .pipe(gulp.dest(config.dest.css))
        .pipe(notify({message: config.messages.css}));
    });
};
<|endoftext|>


<commit_before>/*
 * grunt-lemonsync
 * https://github.com/ubuntu/workspace
 *
 * Copyright (c) 2016 Amir Farzan
 * Licensed under the MIT license.
 */

'use strict';

module.exports = function(grunt) {

  var aws = require('aws-sdk');
  var fs = require('fs');
  var https = require('https');
  var mime = require('mime-types');
  var clone = require('git-clone');

  grunt.registerMultiTask('lemonsync', 'A grunt plugin for working on LemonStand themes locally.', function() {

    var done = this.async();

    var lsTask = this;

    var userOptions = this.options({
      access_token: '',
      store_host: '',
      theme_api_code: '',
      theme_repository: ''
    });

    var httpsOptions = {
      headers: {
        'Authorization': 'Bearer ' + userOptions.access_token,
        'Content-Type': 'application/json'
      },
      hostname: userOptions.store_host,
      path: '/api/v2/identity/s3',
      method: 'POST'
    };

    var awsKey;
    var awsSecret;
    var awsToken;
    var bucket;
    var store;

    var request = https.request(httpsOptions, (res) => {

      res.on('data', (d) => {

        awsKey = JSON.parse(d).data.key;
        awsSecret = JSON.parse(d).data.secret;
        awsToken = JSON.parse(d).data.token;
        bucket = JSON.parse(d).data.bucket;
        store = JSON.parse(d).data.store;

        aws.config.update({accessKeyId: awsKey, secretAccessKey: awsSecret, sessionToken: awsToken});

        listObjects(bucket + '/' + store + '/themes/' + userOptions.theme_api_code + '/theme.yaml');

      });
    });

    request.on('error', (e) => {
      console.error(e);
    });

    request.end();

    // Uploads theme files to S3.
    function s3Upload(file) {
      var fileStream = fs.createReadStream(file);

      fileStream.on('error', function (err) {

        if (err) {
          throw err;
        }
      });

      fileStream.on('open', function () {
        var s3 = new aws.S3();
        var uploadBucket = bucket + '/' + store + '/themes/' + userOptions.theme_api_code;
        var s3PathUpload = normalizePath(file);

        s3.putObject({
          Bucket: uploadBucket,
          Key: s3PathUpload,
          Body: fileStream,
          CacheControl: 'no-cache',
          ContentType: mime.lookup(file) || 'application/octet-stream',
        }, function (err, data) {

          function s3Copy(file) {
            var s3CopyObject = new aws.S3();

            s3CopyObject.copyObject({
              Bucket: bucket + '/' + store + '/themes/' + userOptions.theme_api_code,
              CopySource: bucket + '/' + store + '/themes/' + userOptions.theme_api_code + '/' + file,
              Key: file,
              CacheControl: 'no-cache',
              ContentType: mime.lookup(file),
              MetadataDirective: 'REPLACE'
            });
          }

          if (err) {
            throw new Error('Error in s3Upload function -> ' + err);
          } else {
            grunt.log.oklns('Uploaded... '+file);
            // s3Copy(file);
            // done();
          }
        });
      });
    }

    function s3Head(file) {
      var getObjectHead = new aws.S3();
      var s3PathCheck = normalizePath(file);

      getObjectHead.headObject({
        Bucket: bucket + '/' + store + '/themes/' + userOptions.theme_api_code,
        Key: s3PathCheck
      }, function (err, data) {
        if (err) {
          s3Upload(file);
        } else {
          var lastModifiedRemote = new Date(data.LastModified);
          var statLocal = fs.statSync(file);
          var lastModifiedLocal = new Date(statLocal.mtime);

          if (lastModifiedLocal.getTime() > lastModifiedRemote.getTime()) {
            s3Upload(file);

          }
        }
      });
    }

    function cloneRepo(repo) {
      clone(repo, process.cwd() + '/theme', function(err) {
        if (err) {
          throw err;
        } else {
          checkFiles();
        }
      });
    }

    function checkFiles() {
      lsTask.files.forEach(function(file) {
        for (var i = 0; i < file.src.length; i++) {
          if (grunt.file.isFile(file.src[i])) {
            s3Head(file.src[i]);
          }
        }
      });
    }

    function listObjects(repo) {
      var s3List = new aws.S3();
      s3List.listObjectsV2({
        Bucket: repo
      }, function(err, data) {
        if (err.statusCode !== 200) {
          grunt.log.oklns('Downloading theme repository...');
          cloneRepo(userOptions.theme_repository);
        } else {
          checkFiles();
        }
      });
    }

    function normalizePath(file) {
      return file.replace('theme/', '');
    }

  });

};
<commit_msg>Implemented temp files for syncing.<commit_after>/*
 * grunt-lemonsync
 * https://github.com/ubuntu/workspace
 *
 * Copyright (c) 2016 Amir Farzan
 * Licensed under the MIT license.
 */

'use strict';

module.exports = function(grunt) {

  var aws = require('aws-sdk');
  var fs = require('fs');
  var https = require('https');
  var mime = require('mime-types');
  var clone = require('git-clone');

  grunt.registerMultiTask('lemonsync', 'A grunt plugin for working on LemonStand themes locally.', function() {

    var done = this.async();

    var lsTask = this;

    var userOptions = this.options({
      access_token: '',
      store_host: '',
      theme_api_code: '',
      theme_repository: ''
    });

    var httpsOptions = {
      headers: {
        'Authorization': 'Bearer ' + userOptions.access_token,
        'Content-Type': 'application/json'
      },
      hostname: userOptions.store_host,
      path: '/api/v2/identity/s3',
      method: 'POST'
    };

    var awsKey;
    var awsSecret;
    var awsToken;
    var bucket;
    var store;

    var request = https.request(httpsOptions, (res) => {

      res.on('data', (d) => {

        awsKey = JSON.parse(d).data.key;
        awsSecret = JSON.parse(d).data.secret;
        awsToken = JSON.parse(d).data.token;
        bucket = JSON.parse(d).data.bucket;
        store = JSON.parse(d).data.store;

        aws.config.update({accessKeyId: awsKey, secretAccessKey: awsSecret, sessionToken: awsToken});

        listObjects(bucket + '/' + store + '/themes/' + userOptions.theme_api_code + '/theme.yaml');

      });
    });

    request.on('error', (e) => {
      console.error(e);
    });

    request.end();

    // Uploads theme files to S3.
    function s3Upload(file) {
      var fileStream = fs.createReadStream(file);

      fileStream.on('error', function (err) {

        if (err) {
          throw err;
        }
      });

      fileStream.on('open', function () {
        var s3 = new aws.S3();
        var uploadBucket = bucket + '/' + store + '/themes/' + userOptions.theme_api_code;
        var s3PathUpload = normalizePath(file);

        s3.putObject({
          Bucket: uploadBucket,
          Key: s3PathUpload,
          Body: fileStream,
          CacheControl: 'no-cache',
          ContentType: mime.lookup(file) || 'application/octet-stream',
        }, function (err, data) {

          function s3Copy(file) {
            var s3CopyObject = new aws.S3();

            s3CopyObject.copyObject({
              Bucket: bucket + '/' + store + '/themes/' + userOptions.theme_api_code,
              CopySource: bucket + '/' + store + '/themes/' + userOptions.theme_api_code + '/' + file,
              Key: file,
              CacheControl: 'no-cache',
              ContentType: mime.lookup(file),
              MetadataDirective: 'REPLACE'
            });
          }

          if (err) {
            throw new Error('Error in s3Upload function -> ' + err);
          } else {
            grunt.log.oklns('Uploaded... '+file);
            // s3Copy(file);
            // done();
          }
        });
      });
    }

    function cloneRepo(repo) {
      clone(repo, process.cwd() + '/theme', function(err) {
        if (err) {
          throw err;
        } else {
          checkFiles();
        }
      });
    }

    function checkFiles() {
      lsTask.files.forEach(function(file) {
        for (var i = 0; i < file.src.length; i++) {

          if (grunt.file.isFile(file.src[i])) {

            if ( !grunt.file.exists(".ls-temp/"+file.src[i]) ) {
                grunt.file.write(".ls-temp/"+file.src[i], '');
                s3Upload(file.src[i]);
            } else {
              var tempStat = fs.statSync(".ls-temp/"+file.src[i]);
              var currentStat = fs.statSync(file.src[i]);
              var tempTime = new Date(tempStat.mtime);
              var currentTime = new Date(currentStat.mtime);
              if (currentTime.getTime() > tempTime.getTime()) {
                grunt.file.write(".ls-temp/"+file.src[i], '');
                s3Upload(file.src[i]);
              }
            }
          }
        }
      });
    }

    function listObjects(repo) {
      var s3List = new aws.S3();
      s3List.listObjectsV2({
        Bucket: repo
      }, function(err, data) {
        if (err.statusCode !== 200) {
          grunt.log.oklns('Downloading theme repository...');
          cloneRepo(userOptions.theme_repository);
        } else {
          checkFiles();
        }
      });
    }

    function normalizePath(file) {
      return file.replace('theme/', '');
    }

  });

};
<|endoftext|>


<commit_before>'use strict';

var ejs = require('ejs');
var dateformat = require('dateformat');
var crypto = require('crypto');
var async = require('async');
var fs = require("fs");
var chalk = require('chalk');
var path = require('path');
var mkdirp = require('mkdirp');

var exec;

ejs.open = "{{";
ejs.close = "}}";

var cwd = __dirname;

var createFile = function (template, options) {
    var outerMetadata = fs.readFileSync(path.resolve(cwd, '../template/' + template)).toString();
    var metadata = ejs.render(outerMetadata, options);
    return metadata;
};

var md5 = function (str) {
    var hash = crypto.createHash('md5');
    return hash.update(str).digest('hex');
};

var sha1 = function (str) {
    var hash = crypto.createHash('sha1');
    return hash.update(str).digest('hex');
};

var save = function (fileContent, pomDir, fileName) {
    mkdirp.sync(pomDir);
    fs.writeFileSync(pomDir + '/' + fileName, fileContent);
    fs.writeFileSync(pomDir + '/' + fileName + '.md5', md5(fileContent));
    fs.writeFileSync(pomDir + '/' + fileName + '.sha1', sha1(fileContent));
};

var directoryExists = function(dir) {
    try {
        return fs.statSync(dir).isDirectory();
    } catch (e) {
        // error is thrown by statSync when path does not exist
        if (e.code === 'ENOENT') {
            return false
        }
        throw e;
    }
};

var createAndUploadArtifacts = function (options, done) {
    var pomDir = options.pomDir || 'test/poms';

    options.parallel = options.parallel === undefined ? false : options.parallel;
    if (!directoryExists(pomDir)) {
        fs.mkdirSync(pomDir);
    }

    save(createFile('project-metadata.xml', options), pomDir, 'outer.xml');
    save(createFile('latest-metadata.xml', options), pomDir, 'inner.xml');
    save(createFile('pom.xml', options), pomDir, 'pom.xml');

    var upload = function (fileLocation, targetFile) {
        var uploadArtifact = function (cb) {
            var targetUri = options.url + '/' + targetFile, status;
            if (!options.quiet) {
                console.log(chalk.blue('Uploading to ' + targetUri + "\n\n"));
            }

            var curlOptions = [
                '--silent',
                '--output', '/dev/stderr',
                '--write-out', '"%{http_code}"',
                '--upload-file', fileLocation,
                '--noproxy', options.noproxy ? options.noproxy : '127.0.0.1'
            ];

            if (options.auth) {
                curlOptions.push('-u');
                curlOptions.push('"'+options.auth.username + ":" + options.auth.password+'"');
            }

            if (options.insecure) {
                curlOptions.push('--insecure');
            }

            var execOptions = {};
            options.cwd && (execOptions.cwd = options.cwd);

            var curlCmd = ['curl', curlOptions.join(' '), targetUri].join(' ');

            var childProcess = exec(curlCmd, execOptions, function () {
            });
            childProcess.stdout.on('data', function (data) {
                status = data;
            });
            childProcess.on('close', function (code) {
                if (status.substring(0, 1) == "2" || code == 0) {
                    cb(null, "Ok");
                } else  {
                    cb("Status code " + status + " for " + targetUri, null);
                }
            });
        };
        return uploadArtifact;
    };

    var artifactStream = fs.createReadStream(options.artifact);
    var md5Hash = crypto.createHash('md5');
    var sha1Hash = crypto.createHash('sha1');

    artifactStream.on('data', function(chunk) {

        var binaryChunk = chunk.toString('binary');

        md5Hash.update(binaryChunk);
        sha1Hash.update(binaryChunk);
    });

    artifactStream.on('end', function() {

        fs.writeFileSync(pomDir + '/artifact.' + options.packaging + '.md5', md5Hash.digest('hex'));
        fs.writeFileSync(pomDir + '/artifact.' + options.packaging + '.sha1', sha1Hash.digest('hex'));

        var uploads = {};

        var groupIdAsPath = options.groupId.replace(/\./g, "/");
        var groupArtifactPath = groupIdAsPath + '/' + options.artifactId;

        uploads[pomDir + "/outer.xml"] = groupArtifactPath + '/' + 'maven-metadata.xml';
        uploads[pomDir + "/outer.xml.sha1"] = groupArtifactPath + '/' + 'maven-metadata.xml.sha1';
        uploads[pomDir + "/outer.xml.md5"] = groupArtifactPath + '/' + 'maven-metadata.xml.md5';

        var SNAPSHOT_VER = /.*SNAPSHOT$/i;

        var groupArtifactVersionPath = groupArtifactPath + '/' + options.version;
        if (SNAPSHOT_VER.test(options.version)) {
            uploads[pomDir + "/inner.xml"] = groupArtifactVersionPath + '/' + 'maven-metadata.xml';
            uploads[pomDir + "/inner.xml.sha1"] = groupArtifactVersionPath + '/' + 'maven-metadata.xml.sha1';
            uploads[pomDir + "/inner.xml.md5"] = groupArtifactVersionPath + '/' + 'maven-metadata.xml.md5';
        }

        var remoteArtifactName = options.artifactId + '-' + options.version;
        uploads[pomDir + "/pom.xml"] = groupArtifactVersionPath + '/' + remoteArtifactName + '.pom';
        uploads[pomDir + "/pom.xml.sha1"] = groupArtifactVersionPath + '/' + remoteArtifactName + '.pom.sha1';
        uploads[pomDir + "/pom.xml.md5"] = groupArtifactVersionPath + '/' + remoteArtifactName + '.pom.md5';

        if(options.classifier) {
            remoteArtifactName = remoteArtifactName + "-" + options.classifier;
        }
        uploads[options.artifact] = groupArtifactVersionPath + '/' + remoteArtifactName + '.' + options.packaging;
        uploads[pomDir + "/artifact." + options.packaging + ".sha1"] = groupArtifactVersionPath + '/' + remoteArtifactName + '.' + options.packaging + '.sha1';
        uploads[pomDir + "/artifact." + options.packaging + ".md5"] = groupArtifactVersionPath + '/' + remoteArtifactName + '.' + options.packaging + '.md5';

        var fns = [];
        for (var u in uploads) {
            if (uploads.hasOwnProperty(u)) {
                fns.push(upload(u, uploads[u]));
            }
        }

        var asyncFn = options.parallel ? async.parallel : async.series;
        asyncFn(fns, function (err) {
            if (!options.quiet) {
                console.log(chalk.blue('-------------------------------------------\n'));
                if (err) {
                    console.log(chalk.red('Artifact Upload failed\n' + String(err)));
                } else {
                    console.log(chalk.green('Artifacts uploaded successfully'));
                }
            }
            done(err);
        });

    });

};

module.exports = function (options, cb) {
    if (!options) {
        throw {name: "IllegalArgumentException", message: "upload artifact options required."};
    }
    exec = process.env.MOCK_NEXUS ? require('./mockexec') : require('child_process').exec;
    options.lastUpdated = process.env.MOCK_NEXUS ? '11111111111111': dateformat(new Date(), "yyyymmddHHMMss");
    createAndUploadArtifacts(options, cb);
};<commit_msg>Handling errors on artifactStream.<commit_after>'use strict';

var ejs = require('ejs');
var dateformat = require('dateformat');
var crypto = require('crypto');
var async = require('async');
var fs = require("fs");
var chalk = require('chalk');
var path = require('path');
var mkdirp = require('mkdirp');

var exec;

ejs.open = "{{";
ejs.close = "}}";

var cwd = __dirname;

var createFile = function (template, options) {
    var outerMetadata = fs.readFileSync(path.resolve(cwd, '../template/' + template)).toString();
    var metadata = ejs.render(outerMetadata, options);
    return metadata;
};

var md5 = function (str) {
    var hash = crypto.createHash('md5');
    return hash.update(str).digest('hex');
};

var sha1 = function (str) {
    var hash = crypto.createHash('sha1');
    return hash.update(str).digest('hex');
};

var save = function (fileContent, pomDir, fileName) {
    mkdirp.sync(pomDir);
    fs.writeFileSync(pomDir + '/' + fileName, fileContent);
    fs.writeFileSync(pomDir + '/' + fileName + '.md5', md5(fileContent));
    fs.writeFileSync(pomDir + '/' + fileName + '.sha1', sha1(fileContent));
};

var directoryExists = function(dir) {
    try {
        return fs.statSync(dir).isDirectory();
    } catch (e) {
        // error is thrown by statSync when path does not exist
        if (e.code === 'ENOENT') {
            return false
        }
        throw e;
    }
};

var createAndUploadArtifacts = function (options, done) {
    var pomDir = options.pomDir || 'test/poms';

    options.parallel = options.parallel === undefined ? false : options.parallel;
    if (!directoryExists(pomDir)) {
        fs.mkdirSync(pomDir);
    }

    save(createFile('project-metadata.xml', options), pomDir, 'outer.xml');
    save(createFile('latest-metadata.xml', options), pomDir, 'inner.xml');
    save(createFile('pom.xml', options), pomDir, 'pom.xml');

    var upload = function (fileLocation, targetFile) {
        var uploadArtifact = function (cb) {
            var targetUri = options.url + '/' + targetFile, status;
            if (!options.quiet) {
                console.log(chalk.blue('Uploading to ' + targetUri + "\n\n"));
            }

            var curlOptions = [
                '--silent',
                '--output', '/dev/stderr',
                '--write-out', '"%{http_code}"',
                '--upload-file', fileLocation,
                '--noproxy', options.noproxy ? options.noproxy : '127.0.0.1'
            ];

            if (options.auth) {
                curlOptions.push('-u');
                curlOptions.push('"'+options.auth.username + ":" + options.auth.password+'"');
            }

            if (options.insecure) {
                curlOptions.push('--insecure');
            }

            var execOptions = {};
            options.cwd && (execOptions.cwd = options.cwd);

            var curlCmd = ['curl', curlOptions.join(' '), targetUri].join(' ');

            var childProcess = exec(curlCmd, execOptions, function () {
            });
            childProcess.stdout.on('data', function (data) {
                status = data;
            });
            childProcess.on('close', function (code) {
                if (status.substring(0, 1) == "2" || code == 0) {
                    cb(null, "Ok");
                } else  {
                    cb("Status code " + status + " for " + targetUri, null);
                }
            });
        };
        return uploadArtifact;
    };

    var artifactStream = fs.createReadStream(options.artifact);
    var md5Hash = crypto.createHash('md5');
    var sha1Hash = crypto.createHash('sha1');

    artifactStream.on('data', function(chunk) {

        var binaryChunk = chunk.toString('binary');

        md5Hash.update(binaryChunk);
        sha1Hash.update(binaryChunk);
    });

    artifactStream.on('error', function(error) {
        console.log(chalk.red(error));
        done(error);
    });

    artifactStream.on('end', function() {

        fs.writeFileSync(pomDir + '/artifact.' + options.packaging + '.md5', md5Hash.digest('hex'));
        fs.writeFileSync(pomDir + '/artifact.' + options.packaging + '.sha1', sha1Hash.digest('hex'));

        var uploads = {};

        var groupIdAsPath = options.groupId.replace(/\./g, "/");
        var groupArtifactPath = groupIdAsPath + '/' + options.artifactId;

        uploads[pomDir + "/outer.xml"] = groupArtifactPath + '/' + 'maven-metadata.xml';
        uploads[pomDir + "/outer.xml.sha1"] = groupArtifactPath + '/' + 'maven-metadata.xml.sha1';
        uploads[pomDir + "/outer.xml.md5"] = groupArtifactPath + '/' + 'maven-metadata.xml.md5';

        var SNAPSHOT_VER = /.*SNAPSHOT$/i;

        var groupArtifactVersionPath = groupArtifactPath + '/' + options.version;
        if (SNAPSHOT_VER.test(options.version)) {
            uploads[pomDir + "/inner.xml"] = groupArtifactVersionPath + '/' + 'maven-metadata.xml';
            uploads[pomDir + "/inner.xml.sha1"] = groupArtifactVersionPath + '/' + 'maven-metadata.xml.sha1';
            uploads[pomDir + "/inner.xml.md5"] = groupArtifactVersionPath + '/' + 'maven-metadata.xml.md5';
        }

        var remoteArtifactName = options.artifactId + '-' + options.version;
        uploads[pomDir + "/pom.xml"] = groupArtifactVersionPath + '/' + remoteArtifactName + '.pom';
        uploads[pomDir + "/pom.xml.sha1"] = groupArtifactVersionPath + '/' + remoteArtifactName + '.pom.sha1';
        uploads[pomDir + "/pom.xml.md5"] = groupArtifactVersionPath + '/' + remoteArtifactName + '.pom.md5';

        if(options.classifier) {
            remoteArtifactName = remoteArtifactName + "-" + options.classifier;
        }
        uploads[options.artifact] = groupArtifactVersionPath + '/' + remoteArtifactName + '.' + options.packaging;
        uploads[pomDir + "/artifact." + options.packaging + ".sha1"] = groupArtifactVersionPath + '/' + remoteArtifactName + '.' + options.packaging + '.sha1';
        uploads[pomDir + "/artifact." + options.packaging + ".md5"] = groupArtifactVersionPath + '/' + remoteArtifactName + '.' + options.packaging + '.md5';

        var fns = [];
        for (var u in uploads) {
            if (uploads.hasOwnProperty(u)) {
                fns.push(upload(u, uploads[u]));
            }
        }

        var asyncFn = options.parallel ? async.parallel : async.series;
        asyncFn(fns, function (err) {
            if (!options.quiet) {
                console.log(chalk.blue('-------------------------------------------\n'));
                if (err) {
                    console.log(chalk.red('Artifact Upload failed\n' + String(err)));
                } else {
                    console.log(chalk.green('Artifacts uploaded successfully'));
                }
            }
            done(err);
        });

    });

};

module.exports = function (options, cb) {
    if (!options) {
        throw {name: "IllegalArgumentException", message: "upload artifact options required."};
    }
    exec = process.env.MOCK_NEXUS ? require('./mockexec') : require('child_process').exec;
    options.lastUpdated = process.env.MOCK_NEXUS ? '11111111111111': dateformat(new Date(), "yyyymmddHHMMss");
    createAndUploadArtifacts(options, cb);
};<|endoftext|>


<commit_before>const pug = require('gulp-pug');
const data = require('gulp-data');
const changed = require('gulp-changed');
const cached = require('gulp-cached');
const pugInheritance = require('gulp-pug-inheritance');
const filter = require('gulp-filter');
const plumber = require('gulp-plumber');
const fs = require('fs');
const gulpif = require('gulp-if');

const yamlMerge = require('gulp-yaml-merge');
const yaml = require('js-yaml');
const md5File = require('md5-file');

const { templates, templatesData } = require('./../config.js');
const browserSync = require('./browserSync').browserSync;
const handleError = require('./../utils/handleError.js');
const { getFlag } = require('./../utils/flags');

let dataFileHashCache = null;
let iconsHashCache = null;
let isFirstRun = null;
let isYamlError = false;

// Compile pug to html

const templatesTask = gulp => (done) => {
  const {
    src,
    base,
    filterPaths,
    iconsPaths,
    cfg,
    pugInheritanceCfg,
    dest,
  } = templates();

  const { dataPath, helpersPath, requires, additionalData } = templatesData();

  // get data file hash with cached data file to determine if file changes
  const dataFileHash = md5File.sync(dataPath);
  // get icon files hashes to determine if icons changed
  const iconsHash = Object
    .keys(iconsPaths)
    .map(key => iconsPaths[key])
    .reduce((acc, file) => {
      if (fs.existsSync(file)) {
        acc.push(file);
      }
      return acc;
    }, [])
    .reduce((acc, file) => (acc + md5File.sync(file)), '');

  const isExternalChange = (
    (
      (dataFileHashCache !== null)
      && (dataFileHashCache !== dataFileHash)
    )
    || (
      (iconsHashCache !== null)
      && (iconsHashCache !== iconsHash)
    )
  );

  dataFileHashCache = dataFileHash;
  iconsHashCache = iconsHash;

  // check if this is first run of this task
  isFirstRun = (isFirstRun === null);

  gulp.src(src, { base })
    .pipe(plumber(handleError))
    .pipe(gulpif(getFlag('isWatch') && !isExternalChange, changed('.tmp', { extension: '.html' })))
    .pipe(gulpif(getFlag('isWatch') && !isExternalChange, cached('pug')))
    // Do not run pug-inheritance in the first run. It's not needed, because we compile
    // everything anyway and it takes too much time.
    .pipe(
      gulpif(
        getFlag('isWatch') && !isExternalChange && !isFirstRun,
        pugInheritance(pugInheritanceCfg)
      )
    )
    .pipe(filter(
      file => (
        filterPaths
          .map(path => path.test(file.relative))
          .reduce((acc, val) => acc || val)
      )
    ))
    .pipe(data(() => {
      const yamlData = yaml.safeLoad(
        fs.readFileSync(dataPath, 'utf8')
      );
      const helpers = fs.existsSync(helpersPath) ? require(helpersPath) : {}; // eslint-disable-line
      return Object.assign({}, yamlData, helpers, requires, { iconsPaths }, additionalData);
    }))
    .pipe(pug(cfg))
    .pipe(gulp.dest(dest))
    .on('finish', () => {
      if (!isYamlError && getFlag('isWatch')) {
        browserSync.reload({ once: true });
      }
      done();
    });
};

// Concat *.json file to single data.json

const templatesPrepareDataTask = gulp => () => {
  const { src, dataName, dest } = templatesData();

  isYamlError = false;
  return gulp.src(src)
    .pipe(plumber(function stylesErrorHandler(error) {
      isYamlError = true;
      handleError.call(this, error);
    }))
    .pipe(yamlMerge(dataName))
    .pipe(gulp.dest(dest));
};

module.exports = {
  templatesTask,
  templatesPrepareDataTask,
};
<commit_msg>Use pug config when generating templates<commit_after>const pug = require('gulp-pug');
const data = require('gulp-data');
const changed = require('gulp-changed');
const cached = require('gulp-cached');
const pugInheritance = require('gulp-pug-inheritance');
const filter = require('gulp-filter');
const plumber = require('gulp-plumber');
const fs = require('fs');
const gulpif = require('gulp-if');

const yamlMerge = require('gulp-yaml-merge');
const yaml = require('js-yaml');
const md5File = require('md5-file');

const { templates, templatesData } = require('./../config.js');
const browserSync = require('./browserSync').browserSync;
const handleError = require('./../utils/handleError.js');
const { getFlag } = require('./../utils/flags');

let dataFileHashCache = null;
let iconsHashCache = null;
let isFirstRun = null;
let isYamlError = false;

// Compile pug to html

const templatesTask = gulp => (done) => {
  const {
    src,
    base,
    filterPaths,
    iconsPaths,
    pugCfg,
    pugInheritanceCfg,
    dest,
  } = templates();

  const { dataPath, helpersPath, requires, additionalData } = templatesData();

  // get data file hash with cached data file to determine if file changes
  const dataFileHash = md5File.sync(dataPath);
  // get icon files hashes to determine if icons changed
  const iconsHash = Object
    .keys(iconsPaths)
    .map(key => iconsPaths[key])
    .reduce((acc, file) => {
      if (fs.existsSync(file)) {
        acc.push(file);
      }
      return acc;
    }, [])
    .reduce((acc, file) => (acc + md5File.sync(file)), '');

  const isExternalChange = (
    (
      (dataFileHashCache !== null)
      && (dataFileHashCache !== dataFileHash)
    )
    || (
      (iconsHashCache !== null)
      && (iconsHashCache !== iconsHash)
    )
  );

  dataFileHashCache = dataFileHash;
  iconsHashCache = iconsHash;

  // check if this is first run of this task
  isFirstRun = (isFirstRun === null);

  gulp.src(src, { base })
    .pipe(plumber(handleError))
    .pipe(gulpif(getFlag('isWatch') && !isExternalChange, changed('.tmp', { extension: '.html' })))
    .pipe(gulpif(getFlag('isWatch') && !isExternalChange, cached('pug')))
    // Do not run pug-inheritance in the first run. It's not needed, because we compile
    // everything anyway and it takes too much time.
    .pipe(
      gulpif(
        getFlag('isWatch') && !isExternalChange && !isFirstRun,
        pugInheritance(pugInheritanceCfg)
      )
    )
    .pipe(filter(
      file => (
        filterPaths
          .map(path => path.test(file.relative))
          .reduce((acc, val) => acc || val)
      )
    ))
    .pipe(data(() => {
      const yamlData = yaml.safeLoad(
        fs.readFileSync(dataPath, 'utf8')
      );
      const helpers = fs.existsSync(helpersPath) ? require(helpersPath) : {}; // eslint-disable-line
      return Object.assign({}, yamlData, helpers, requires, { iconsPaths }, additionalData);
    }))
    .pipe(pug(pugCfg))
    .pipe(gulp.dest(dest))
    .on('finish', () => {
      if (!isYamlError && getFlag('isWatch')) {
        browserSync.reload({ once: true });
      }
      done();
    });
};

// Concat *.json file to single data.json

const templatesPrepareDataTask = gulp => () => {
  const { src, dataName, dest } = templatesData();

  isYamlError = false;
  return gulp.src(src)
    .pipe(plumber(function stylesErrorHandler(error) {
      isYamlError = true;
      handleError.call(this, error);
    }))
    .pipe(yamlMerge(dataName))
    .pipe(gulp.dest(dest));
};

module.exports = {
  templatesTask,
  templatesPrepareDataTask,
};
<|endoftext|>


<commit_before>
'use strict';

// Require

const gulp = require( 'gulp' );

// Export

module.exports = ( task, core ) => {

	let globalData = {

		app: core.config.app,
		head: core.config.head,
		options: core.config.options,
		paths: {
			root: './',
			styles: './' + core.config.dist.styles,
			static: './' + core.config.dist.static,
			scripts: './' + core.config.dist.scripts,
			favicons: './' + core.config.dist.favicons
		},
		blocks: core.readBlocks(),
		isDevelopment: core.isDevelopment

	};

	task.src = core.path.pages( '*' + core.config.extnames.templates );

	task.dest = core.path.DIST;

	if ( core.config.extnames.templates === '.html' ) {

		task.require = 'gulp-file-include';

		task.data = {
			prefix: '@@',
			basepath: '@file',
			context: {
				global: globalData
			}
		};

	}

	if ( core.config.extnames.templates === '.twig' ) {

		task.require = 'gulp-twig';

		task.data = {
			data: {
				global: globalData
			}
		};

	}

	if ( core.config.extnames.templates === '.pug' ) {

		task.require = 'gulp-pug';

		task.data = {
			doctype: 'html',
			pretty: '\t',
			basedir: core.path.ROOT,
			data: {
				global: globalData
			}
		};

		task.data.data.global.newLine = task.data.pretty ? '\n' : '';

		task.dest = core.prettyFix; // https://github.com/werty1001/bempug/issues/1

	}

	return ( cb ) => {

		if ( ! task.require ) return cb();

		return gulp.src( task.src, {since: gulp.lastRun( task.name )} )
			.pipe( require( 'gulp-plumber' )( core.errorHandler ) )
			.pipe( require( task.require )( task.data ) )
			.pipe( gulp.dest( task.dest ) );

	};

};
<commit_msg>Add img path for use in templates<commit_after>
'use strict';

// Require

const gulp = require( 'gulp' );

// Export

module.exports = ( task, core ) => {

	let globalData = {

		app: core.config.app,
		head: core.config.head,
		options: core.config.options,
		paths: {
			root: './',
			img: './' + core.config.dist.img,
			styles: './' + core.config.dist.styles,
			static: './' + core.config.dist.static,
			scripts: './' + core.config.dist.scripts,
			favicons: './' + core.config.dist.favicons
		},
		blocks: core.readBlocks(),
		isDevelopment: core.isDevelopment

	};

	task.src = core.path.pages( '*' + core.config.extnames.templates );

	task.dest = core.path.DIST;

	if ( core.config.extnames.templates === '.html' ) {

		task.require = 'gulp-file-include';

		task.data = {
			prefix: '@@',
			basepath: '@file',
			context: {
				global: globalData
			}
		};

	}

	if ( core.config.extnames.templates === '.twig' ) {

		task.require = 'gulp-twig';

		task.data = {
			data: {
				global: globalData
			}
		};

	}

	if ( core.config.extnames.templates === '.pug' ) {

		task.require = 'gulp-pug';

		task.data = {
			doctype: 'html',
			pretty: '\t',
			basedir: core.path.ROOT,
			data: {
				global: globalData
			}
		};

		task.data.data.global.newLine = task.data.pretty ? '\n' : '';

		task.dest = core.prettyFix; // https://github.com/werty1001/bempug/issues/1

	}

	return ( cb ) => {

		if ( ! task.require ) return cb();

		return gulp.src( task.src, {since: gulp.lastRun( task.name )} )
			.pipe( require( 'gulp-plumber' )( core.errorHandler ) )
			.pipe( require( task.require )( task.data ) )
			.pipe( gulp.dest( task.dest ) );

	};

};
<|endoftext|>


<commit_before>var fs = require('fs');

module.exports = function (grunt) {
  grunt.registerTask('templates', function () {
    var templates = fs.readdirSync('templates').map(function (fileName) {
      return fs.readFileSync('templates/' + fileName, 'utf8');
    });
    fs.writeFileSync('gen/templates.json', JSON.stringify(templates));
  });
};
<commit_msg>fix templates task<commit_after>var fs = require('fs');
var _ = require('lodash');

module.exports = function (grunt) {
  grunt.registerTask('templates', function () {
    var templates = fs.readdirSync('templates').map(function (fileName) {
      var name = fileName.split('.')[0];
      return [name, fs.readFileSync('templates/' + fileName, 'utf8')];
    });
    fs.writeFileSync('gen/templates.json', JSON.stringify(_.zipObject(templates)));
  });
};
<|endoftext|>


<commit_before>/*
 * grunt-wp-deploy
 * https://github.com/stephenharris/wp-deploy
 *
 * Copyright (c) 2013 Stephen Harris
 * Licensed under the MIT license.
 */

'use strict';

module.exports = function(grunt) {

	var exec = require('child_process').exec;
	var inquirer = require('inquirer');
	var async = require('async');
	var path = require('path');
	var awk = process.platform === 'win32'? 'gawk' : 'awk';
	var no_run_if_empty = process.platform !== 'darwin' ? '--no-run-if-empty ' : '';

	// Please see the Grunt documentation for more information regarding task
	// creation: http://gruntjs.com/creating-tasks
	grunt.registerMultiTask('wp_deploy', 'Deploys a git Repo to the WordPress SVN repo', function() {

		var done = this.async();

		var options = this.options({
			svn_url: "http://plugins.svn.wordpress.org/{plugin-slug}",
			svn_user: false,
			plugin_main_file: false,
			plugin_slug: false,
			build_dir: false,
			assets_dir: false,
			tmp_dir: "/tmp/",
			max_buffer: 200*1024,
			skip_confirmation: false,
			force_interactive: true,
			deploy_trunk: true,
			deploy_tag: true
		});

		var pkg = grunt.file.readJSON('package.json');
		options.deploy_tag = options.deploy_tag && options.deploy_trunk;

		if( !options.plugin_slug ){
			grunt.fail.fatal( "Plug-in slug not provided" );
		}

		if( !options.build_dir ){
			grunt.fail.fatal( "Build directory not provided" );
		}

		var questions = [];
		if( !options.svn_user ){
			questions.push({
				type: "input",
				name: "svn_username",
				message: "What's your SVN username?"
			});
		}

		inquirer.prompt( questions, function( answers ) {

			//Set up slug, main file, readme file and paths.
			var slug = options.plugin_slug, plugin_file;

			var svnpath     = options.tmp_dir.replace(/\/?$/, '/') + slug;
			var build_dir   = options.build_dir.replace(/\/?$/, '/'); //trailing slash
			var readme_file = build_dir + "readme.txt";

			if ( options.plugin_main_file ) {
				plugin_file = build_dir + options.plugin_main_file;
			} else {
				plugin_file = build_dir + slug + ".php";
			}

			//SVN user/url
			var svnuser = options.svn_user || answers.svn_username;
			var svnurl = options.svn_url.replace( '{plugin-slug}', slug );

			//Try to find readme
			var exts = ['txt','md'];
			while( !grunt.file.exists(readme_file) && exts.length > 0 ) {
				var readmes = ['readme', 'README', 'ReadMe' ];
				var ext = exts.shift();
				while( !grunt.file.exists(readme_file) && readmes.length > 0 ) {
					var filename = readmes.shift();
					readme_file = build_dir + filename + '.' + ext;
					console.log( readme_file );
				}
			}
			if ( !grunt.file.exists(readme_file) ) {
				grunt.fail.warn('readme.txt file not not found at ' + readme_file );
			}

			//Try to find plug-in file
			if ( !grunt.file.exists(plugin_file) ) {
				grunt.fail.warn( plugin_file+' file not not found.');
			}

			//Get versions:
			var readme = grunt.file.read(readme_file);
			var readmeVersion = readme.match( new RegExp("^Stable tag:\\s*(\\S+)","im") );
			var plugin = grunt.file.read(plugin_file);
			var pluginVersion = plugin.match( new RegExp("^[ \t\/*#@]*Version:\\s*(\\S+)$","im") );

			//Check versions
			if( options.deploy_tag && projectVersionCompare( pluginVersion[1],  readmeVersion[1] )  !== 0 ){
				grunt.log.warn( "Readme.txt version: " + readmeVersion[1] );
				grunt.log.warn( plugin_file+".php version: " + pluginVersion[1] );
				grunt.fail.warn( 'Versions do not match:');
			}

			var ctxt = {
				new_version: pluginVersion[1],
				svnurl: svnurl,
				svnuser: svnuser,
				svnpath: svnpath,
				max_buffer: options.max_buffer,
				build_dir: build_dir,
				assets_dir: options.assets_dir,
				force_interactive: options.force_interactive ? '--force-interactive' : '',
				deploy_tag: options.deploy_tag
			};

			var steps = [
				function( callback ) {
					callback( null, ctxt );
				},
				checkOut,
				options.deploy_trunk ? clearTrunk : null,
				options.deploy_trunk ? copyBuild : null,
				options.assets_dir ? clearAssets : null,
				options.assets_dir ? copyAssets : null,
				options.skip_confirmation ? null : confirmation,
				options.deploy_trunk ? addFiles : null,
				options.deploy_trunk ? commitToTrunk : null,
				options.deploy_tag ? copyToTag : null,
				options.deploy_tag ? commitTag : null,
				options.assets_dir ? addAssets : null,
				options.assets_dir ? commitAssets : null
			].filter(function(val) { return val !== null; });

			async.waterfall( steps, function (err, result){
				done();
			});

		});//Initial questions

	}); //Register

	var checkOut = function ( ctxt, callback ) {
		grunt.log.writeln( 'Checking out '+ ctxt.svnurl+ '...' );
		exec( 'svn co ' + ctxt.force_interactive + ' '+ctxt.svnurl+ ' ' + ctxt.svnpath, { maxBuffer: ctxt.max_buffer }, function (error, stdout, stderr) {
			if (error !== null) {
				grunt.fail.fatal( 'Checkout of "'+ctxt.svnurl+'"unsuccessful: ' + error);
			}

			grunt.log.writeln( 'Check out complete.' + "\n" );

			if( ctxt.deploy_tag && grunt.file.exists(  ctxt.svnpath+"/tags/"+ctxt.new_version) ){
				grunt.fail.warn( 'Tag ' + ctxt.new_version + ' already exists');
			}
			callback( null, ctxt );
		});
	};

	var clearTrunk = function ( ctxt, callback ) {
		grunt.log.writeln( 'Clearing trunk.');
		exec( 'rm -fr '+ctxt.svnpath+"/trunk/*", function(){
			callback( null, ctxt );
		});
	};

	var clearAssets = function ( ctxt, callback ) {
		grunt.log.writeln( 'Clearing assets.');
		exec( 'rm -fr '+ctxt.svnpath+"/assets/*", function(){
			callback( null, ctxt );
		});
	};

	var copyBuild = function ( ctxt, callback ) {
		grunt.log.writeln( 'Copying build directory: ' + ctxt.build_dir + ' to ' + ctxt.svnpath+'/trunk/');
		copyDirectory( ctxt.build_dir, ctxt.svnpath+"/trunk/", function( ){
			callback( null, ctxt );
		} );
	};

	var copyAssets = function ( ctxt, callback ) {
		var assets_dir = ctxt.assets_dir.replace(/\/?$/, '/'); //trailing slash
		grunt.log.writeln( 'Copying assets directory: ' + assets_dir + ' to ' + ctxt.svnpath+'/assets/');
		copyDirectory( assets_dir, ctxt.svnpath+"/assets/", function( ){
			callback( null, ctxt );
		} );
	};

	var confirmation = function( ctxt, callback ) {
		inquirer.prompt( [
			{
				type: "confirm",
				name: "are_you_sure",
				message: "\n" + "Are you sure you want to commit '" + ctxt.new_version + "'?"
			}],
			function( answers ) {
				if( !answers.are_you_sure ){
					grunt.log.writeln( 'Aborting...' );
					return;
				}
				callback( null, ctxt );
			}
		);
	};

	var addFiles = function( ctxt, callback ) {
		var cmd = "svn status |" + awk + " '/^[?]/{print $2}' | xargs " + no_run_if_empty + "svn add;";
		cmd += "svn status | " + awk + " '/^[!]/{print $2}' | xargs " + no_run_if_empty + "svn delete;";
		exec(cmd,{cwd: ctxt.svnpath+"/trunk"}, function( a, b, c ){
			callback( null, ctxt );
		});
	};

	var commitToTrunk = function( ctxt, callback ) {
		var trunkCommitMsg = "Committing " + ctxt.new_version + " to trunk";
		grunt.log.writeln( "\n" + trunkCommitMsg + "\n" );
		var cmd = 'svn commit ' + ctxt.force_interactive + ' --username="'+ctxt.svnuser+'" -m "'+trunkCommitMsg+'"';
		exec( cmd, {cwd:ctxt.svnpath+'/trunk'}, function(error, stdout, stderr) {
			if (error !== null) {
				grunt.fail.warn( 'Failed to commit to trunk: ' + error );
			}
			callback( null, ctxt );
		});
	};

	var copyToTag = function( ctxt, callback ) {
		grunt.log.writeln( 'Copying ' + ctxt.new_version + ' to tag');
		exec( "svn copy trunk/ tags/"+ctxt.new_version, { cwd: ctxt.svnpath }, function( error, stdout, stderr) {
			if (error !== null) {
				grunt.fail.warn( 'Failed to copy to tag: ' + error );
			}
			callback( null, ctxt );
		});
	};

	var commitTag = function( ctxt, callback ) {
		var tagCommitMsg   = "Tagging " + ctxt.new_version;
		grunt.log.writeln( tagCommitMsg + "\n" );
		var cmd = 'svn commit ' + ctxt.force_interactive + ' --username="'+ctxt.svnuser+'" -m "'+tagCommitMsg+'"';
		exec( cmd , { cwd: ctxt.svnpath+'/tags/'+ctxt.new_version }, function( error, stdout, stderr) {
			if (error !== null) {
				grunt.fail.warn( 'Failed to comit tag: ' + error );
			}
			callback( null, ctxt );
		});
	};

	var addAssets = function( ctxt, callback ) {
		var cmd = "svn status |" + awk + " '/^[?]/{print $2}' | xargs " + no_run_if_empty + "svn add;";
		cmd += "svn status | " + awk + " '/^[!]/{print $2}' | xargs " + no_run_if_empty + "svn delete;";
		exec( cmd,{ cwd: ctxt.svnpath+"/assets" }, function(error, stdout, stderr) {
			if (error !== null) {
				grunt.log.writeln( cmd );
				grunt.fail.warn( 'Failed to add assets: ' + error );
			}
			callback( null, ctxt );
		} );
	};

	var commitAssets = function( ctxt, callback ) {
		var assetCommitMsg = "Committing assets for " + ctxt.new_version;
		grunt.log.writeln( assetCommitMsg + "\n" );

		var cmd = 'svn commit ' + ctxt.force_interactive + ' --username="'+ctxt.svnuser+'" -m "'+assetCommitMsg+'"';

		exec( cmd,{ cwd: ctxt.svnpath+"/assets" }, function(error, stdout, stderr) {
			if (error !== null) {
				grunt.fail.warn( 'Failed to commit to assets: ' + error );
			}
			callback( null, ctxt );
		} );
	};

	//Compares version numbers
	var projectVersionCompare = function(left, right) {
		if (typeof left + typeof right !== 'stringstring'){
			return false;
		}

		var a = left.split('.'),   b = right.split('.'),   i = 0, len = Math.max(a.length, b.length);
		for (; i < len; i++) {
			if ((a[i] && !b[i] && parseInt(a[i], 10) > 0) || (parseInt(a[i], 10) > parseInt(b[i], 10))) {
				return 1;
			} else if ((b[i] && !a[i] && parseInt(b[i], 10) > 0) || (parseInt(a[i], 10) < parseInt(b[i], 10))) {
				return -1;
			}
		}

		return 0;
	};

	var detectDestType = function(dest) {
		if (grunt.util._.endsWith(dest, '/')) {
			return 'directory';
		} else {
			return 'file';
		}
	};

	var unixifyPath = function(filepath) {
		if (process.platform === 'win32') {
			return filepath.replace(/\\/g, '/');
		} else {
			return filepath;
		}
	};

	var copyDirectory = function( src_dir, dest_dir, callback ){

		//Ensure directory has trailingslash
		if ( src_dir.substr(-1) !== '/' ) {
			src_dir = src_dir + '/';
		}

		grunt.file.expand(  { 'expand': true, 'cwd' : src_dir, dot: true }, '**/*' ).forEach( function( src ){
			var dest = unixifyPath(path.join( dest_dir, src));
			if ( grunt.file.isDir( src_dir + src ) ) {
				grunt.file.mkdir( dest);
			} else {
				grunt.file.copy( src_dir + src, dest );
			}
		});

		callback();
	};
};
<commit_msg>Remove .php extension<commit_after>/*
 * grunt-wp-deploy
 * https://github.com/stephenharris/wp-deploy
 *
 * Copyright (c) 2013 Stephen Harris
 * Licensed under the MIT license.
 */

'use strict';

module.exports = function(grunt) {

	var exec = require('child_process').exec;
	var inquirer = require('inquirer');
	var async = require('async');
	var path = require('path');
	var awk = process.platform === 'win32'? 'gawk' : 'awk';
	var no_run_if_empty = process.platform !== 'darwin' ? '--no-run-if-empty ' : '';

	// Please see the Grunt documentation for more information regarding task
	// creation: http://gruntjs.com/creating-tasks
	grunt.registerMultiTask('wp_deploy', 'Deploys a git Repo to the WordPress SVN repo', function() {

		var done = this.async();

		var options = this.options({
			svn_url: "http://plugins.svn.wordpress.org/{plugin-slug}",
			svn_user: false,
			plugin_main_file: false,
			plugin_slug: false,
			build_dir: false,
			assets_dir: false,
			tmp_dir: "/tmp/",
			max_buffer: 200*1024,
			skip_confirmation: false,
			force_interactive: true,
			deploy_trunk: true,
			deploy_tag: true
		});

		var pkg = grunt.file.readJSON('package.json');
		options.deploy_tag = options.deploy_tag && options.deploy_trunk;

		if( !options.plugin_slug ){
			grunt.fail.fatal( "Plug-in slug not provided" );
		}

		if( !options.build_dir ){
			grunt.fail.fatal( "Build directory not provided" );
		}

		var questions = [];
		if( !options.svn_user ){
			questions.push({
				type: "input",
				name: "svn_username",
				message: "What's your SVN username?"
			});
		}

		inquirer.prompt( questions, function( answers ) {

			//Set up slug, main file, readme file and paths.
			var slug = options.plugin_slug, plugin_file;

			var svnpath     = options.tmp_dir.replace(/\/?$/, '/') + slug;
			var build_dir   = options.build_dir.replace(/\/?$/, '/'); //trailing slash
			var readme_file = build_dir + "readme.txt";

			if ( options.plugin_main_file ) {
				plugin_file = build_dir + options.plugin_main_file;
			} else {
				plugin_file = build_dir + slug + ".php";
			}

			//SVN user/url
			var svnuser = options.svn_user || answers.svn_username;
			var svnurl = options.svn_url.replace( '{plugin-slug}', slug );

			//Try to find readme
			var exts = ['txt','md'];
			while( !grunt.file.exists(readme_file) && exts.length > 0 ) {
				var readmes = ['readme', 'README', 'ReadMe' ];
				var ext = exts.shift();
				while( !grunt.file.exists(readme_file) && readmes.length > 0 ) {
					var filename = readmes.shift();
					readme_file = build_dir + filename + '.' + ext;
					console.log( readme_file );
				}
			}
			if ( !grunt.file.exists(readme_file) ) {
				grunt.fail.warn('readme.txt file not not found at ' + readme_file );
			}

			//Try to find plug-in file
			if ( !grunt.file.exists(plugin_file) ) {
				grunt.fail.warn( plugin_file+' file not not found.');
			}

			//Get versions:
			var readme = grunt.file.read(readme_file);
			var readmeVersion = readme.match( new RegExp("^Stable tag:\\s*(\\S+)","im") );
			var plugin = grunt.file.read(plugin_file);
			var pluginVersion = plugin.match( new RegExp("^[ \t\/*#@]*Version:\\s*(\\S+)$","im") );

			//Check versions
			if( options.deploy_tag && projectVersionCompare( pluginVersion[1],  readmeVersion[1] )  !== 0 ){
				grunt.log.warn( "Readme.txt version: " + readmeVersion[1] );
				grunt.log.warn( plugin_file+" version: " + pluginVersion[1] );
				grunt.fail.warn( 'Versions do not match:');
			}

			var ctxt = {
				new_version: pluginVersion[1],
				svnurl: svnurl,
				svnuser: svnuser,
				svnpath: svnpath,
				max_buffer: options.max_buffer,
				build_dir: build_dir,
				assets_dir: options.assets_dir,
				force_interactive: options.force_interactive ? '--force-interactive' : '',
				deploy_tag: options.deploy_tag
			};

			var steps = [
				function( callback ) {
					callback( null, ctxt );
				},
				checkOut,
				options.deploy_trunk ? clearTrunk : null,
				options.deploy_trunk ? copyBuild : null,
				options.assets_dir ? clearAssets : null,
				options.assets_dir ? copyAssets : null,
				options.skip_confirmation ? null : confirmation,
				options.deploy_trunk ? addFiles : null,
				options.deploy_trunk ? commitToTrunk : null,
				options.deploy_tag ? copyToTag : null,
				options.deploy_tag ? commitTag : null,
				options.assets_dir ? addAssets : null,
				options.assets_dir ? commitAssets : null
			].filter(function(val) { return val !== null; });

			async.waterfall( steps, function (err, result){
				done();
			});

		});//Initial questions

	}); //Register

	var checkOut = function ( ctxt, callback ) {
		grunt.log.writeln( 'Checking out '+ ctxt.svnurl+ '...' );
		exec( 'svn co ' + ctxt.force_interactive + ' '+ctxt.svnurl+ ' ' + ctxt.svnpath, { maxBuffer: ctxt.max_buffer }, function (error, stdout, stderr) {
			if (error !== null) {
				grunt.fail.fatal( 'Checkout of "'+ctxt.svnurl+'"unsuccessful: ' + error);
			}

			grunt.log.writeln( 'Check out complete.' + "\n" );

			if( ctxt.deploy_tag && grunt.file.exists(  ctxt.svnpath+"/tags/"+ctxt.new_version) ){
				grunt.fail.warn( 'Tag ' + ctxt.new_version + ' already exists');
			}
			callback( null, ctxt );
		});
	};

	var clearTrunk = function ( ctxt, callback ) {
		grunt.log.writeln( 'Clearing trunk.');
		exec( 'rm -fr '+ctxt.svnpath+"/trunk/*", function(){
			callback( null, ctxt );
		});
	};

	var clearAssets = function ( ctxt, callback ) {
		grunt.log.writeln( 'Clearing assets.');
		exec( 'rm -fr '+ctxt.svnpath+"/assets/*", function(){
			callback( null, ctxt );
		});
	};

	var copyBuild = function ( ctxt, callback ) {
		grunt.log.writeln( 'Copying build directory: ' + ctxt.build_dir + ' to ' + ctxt.svnpath+'/trunk/');
		copyDirectory( ctxt.build_dir, ctxt.svnpath+"/trunk/", function( ){
			callback( null, ctxt );
		} );
	};

	var copyAssets = function ( ctxt, callback ) {
		var assets_dir = ctxt.assets_dir.replace(/\/?$/, '/'); //trailing slash
		grunt.log.writeln( 'Copying assets directory: ' + assets_dir + ' to ' + ctxt.svnpath+'/assets/');
		copyDirectory( assets_dir, ctxt.svnpath+"/assets/", function( ){
			callback( null, ctxt );
		} );
	};

	var confirmation = function( ctxt, callback ) {
		inquirer.prompt( [
			{
				type: "confirm",
				name: "are_you_sure",
				message: "\n" + "Are you sure you want to commit '" + ctxt.new_version + "'?"
			}],
			function( answers ) {
				if( !answers.are_you_sure ){
					grunt.log.writeln( 'Aborting...' );
					return;
				}
				callback( null, ctxt );
			}
		);
	};

	var addFiles = function( ctxt, callback ) {
		var cmd = "svn status |" + awk + " '/^[?]/{print $2}' | xargs " + no_run_if_empty + "svn add;";
		cmd += "svn status | " + awk + " '/^[!]/{print $2}' | xargs " + no_run_if_empty + "svn delete;";
		exec(cmd,{cwd: ctxt.svnpath+"/trunk"}, function( a, b, c ){
			callback( null, ctxt );
		});
	};

	var commitToTrunk = function( ctxt, callback ) {
		var trunkCommitMsg = "Committing " + ctxt.new_version + " to trunk";
		grunt.log.writeln( "\n" + trunkCommitMsg + "\n" );
		var cmd = 'svn commit ' + ctxt.force_interactive + ' --username="'+ctxt.svnuser+'" -m "'+trunkCommitMsg+'"';
		exec( cmd, {cwd:ctxt.svnpath+'/trunk'}, function(error, stdout, stderr) {
			if (error !== null) {
				grunt.fail.warn( 'Failed to commit to trunk: ' + error );
			}
			callback( null, ctxt );
		});
	};

	var copyToTag = function( ctxt, callback ) {
		grunt.log.writeln( 'Copying ' + ctxt.new_version + ' to tag');
		exec( "svn copy trunk/ tags/"+ctxt.new_version, { cwd: ctxt.svnpath }, function( error, stdout, stderr) {
			if (error !== null) {
				grunt.fail.warn( 'Failed to copy to tag: ' + error );
			}
			callback( null, ctxt );
		});
	};

	var commitTag = function( ctxt, callback ) {
		var tagCommitMsg   = "Tagging " + ctxt.new_version;
		grunt.log.writeln( tagCommitMsg + "\n" );
		var cmd = 'svn commit ' + ctxt.force_interactive + ' --username="'+ctxt.svnuser+'" -m "'+tagCommitMsg+'"';
		exec( cmd , { cwd: ctxt.svnpath+'/tags/'+ctxt.new_version }, function( error, stdout, stderr) {
			if (error !== null) {
				grunt.fail.warn( 'Failed to comit tag: ' + error );
			}
			callback( null, ctxt );
		});
	};

	var addAssets = function( ctxt, callback ) {
		var cmd = "svn status |" + awk + " '/^[?]/{print $2}' | xargs " + no_run_if_empty + "svn add;";
		cmd += "svn status | " + awk + " '/^[!]/{print $2}' | xargs " + no_run_if_empty + "svn delete;";
		exec( cmd,{ cwd: ctxt.svnpath+"/assets" }, function(error, stdout, stderr) {
			if (error !== null) {
				grunt.log.writeln( cmd );
				grunt.fail.warn( 'Failed to add assets: ' + error );
			}
			callback( null, ctxt );
		} );
	};

	var commitAssets = function( ctxt, callback ) {
		var assetCommitMsg = "Committing assets for " + ctxt.new_version;
		grunt.log.writeln( assetCommitMsg + "\n" );

		var cmd = 'svn commit ' + ctxt.force_interactive + ' --username="'+ctxt.svnuser+'" -m "'+assetCommitMsg+'"';

		exec( cmd,{ cwd: ctxt.svnpath+"/assets" }, function(error, stdout, stderr) {
			if (error !== null) {
				grunt.fail.warn( 'Failed to commit to assets: ' + error );
			}
			callback( null, ctxt );
		} );
	};

	//Compares version numbers
	var projectVersionCompare = function(left, right) {
		if (typeof left + typeof right !== 'stringstring'){
			return false;
		}

		var a = left.split('.'),   b = right.split('.'),   i = 0, len = Math.max(a.length, b.length);
		for (; i < len; i++) {
			if ((a[i] && !b[i] && parseInt(a[i], 10) > 0) || (parseInt(a[i], 10) > parseInt(b[i], 10))) {
				return 1;
			} else if ((b[i] && !a[i] && parseInt(b[i], 10) > 0) || (parseInt(a[i], 10) < parseInt(b[i], 10))) {
				return -1;
			}
		}

		return 0;
	};

	var detectDestType = function(dest) {
		if (grunt.util._.endsWith(dest, '/')) {
			return 'directory';
		} else {
			return 'file';
		}
	};

	var unixifyPath = function(filepath) {
		if (process.platform === 'win32') {
			return filepath.replace(/\\/g, '/');
		} else {
			return filepath;
		}
	};

	var copyDirectory = function( src_dir, dest_dir, callback ){

		//Ensure directory has trailingslash
		if ( src_dir.substr(-1) !== '/' ) {
			src_dir = src_dir + '/';
		}

		grunt.file.expand(  { 'expand': true, 'cwd' : src_dir, dot: true }, '**/*' ).forEach( function( src ){
			var dest = unixifyPath(path.join( dest_dir, src));
			if ( grunt.file.isDir( src_dir + src ) ) {
				grunt.file.mkdir( dest);
			} else {
				grunt.file.copy( src_dir + src, dest );
			}
		});

		callback();
	};
};
<|endoftext|>


<commit_before>/**
 * css-roole
 * =========
 *
 * Собирает *css*-файлы вместе с *roo*-файлами по deps'ам, раскрывает инклуды и ссылки, сохраняет в виде `?.css`.
 *
 * **Опции**
 *
 * * *String* **target** — Результирующий таргет. По умолчанию `?.css`.
 * * *String* **filesTarget** — files-таргет, на основе которого получается список исходных файлов
 *   (его предоставляет технология `files`). По умолчанию — `?.files`.
 *
 * **Пример**
 *
 * ```javascript
 * nodeConfig.addTech(require('enb-roole/techs/css-roole'));
 * ```
 */
var roole = require('roole');
var vowNode = require('vow-node');
var rooleCompile = vowNode.promisify(roole.compile);

module.exports = require('enb/techs/css').buildFlow()
    .name('css-roole')
    .target('target', '?.css')
    .useFileList(['css', 'roo'])
    .builder(function (sourceFiles) {
        var node = this.node;
        var options = {
            base: node.getPath()
        };
        var source = sourceFiles.map(function (file) {
            return '@import "' + node.relativePath(file.fullname) + '";';
        }).join('\n');

        return this._processCss(source, node.resolvePath(this._target))
            .then(function (source) {
                return rooleCompile(source, options);
            })
            .fail(function (err) {
                throw new Error(err);
            });
    })
    .createTech();
<commit_msg>Added error context to stack<commit_after>/**
 * css-roole
 * =========
 *
 * Собирает *css*-файлы вместе с *roo*-файлами по deps'ам, раскрывает инклуды и ссылки, сохраняет в виде `?.css`.
 *
 * **Опции**
 *
 * * *String* **target** — Результирующий таргет. По умолчанию `?.css`.
 * * *String* **filesTarget** — files-таргет, на основе которого получается список исходных файлов
 *   (его предоставляет технология `files`). По умолчанию — `?.files`.
 *
 * **Пример**
 *
 * ```javascript
 * nodeConfig.addTech(require('enb-roole/techs/css-roole'));
 * ```
 */
var path = require('path');
var vow = require('vow');
var vfs = require('enb/lib/fs/async-fs');
var roole = require('roole');
var vowNode = require('vow-node');
var rooleCompile = vowNode.promisify(roole.compile);

module.exports = require('enb/techs/css').buildFlow()
    .name('css-roole')
    .target('target', '?.css')
    .useFileList(['css', 'roo'])
    .builder(function (sourceFiles) {
        var preprocessor = this._getCssPreprocessor();
        var node = this.node;
        var imports = {};
        var options = {
            imports: imports,
            base: node.getPath()
        };

        return vow.all(
                sourceFiles.map(function (file) {
                    return vfs.read(file.fullname)
                        .then(function (source) {
                            imports[file.fullname] = preprocessor._processUrls(source.toString(), file.fullname);

                            return '@import "' + node.relativePath(file.fullname) + '";';
                        });
                })
            )
            .then(function (sources) {
                return rooleCompile(sources.join('\n'), options);
            })
            .fail(function (err) {
                var indent = '    ';
                var message = err.message;

                if (typeof err.context === 'function') {
                    message += ' at ./' + path.relative(node._root, err.loc.filename) + '\n' + err.context(indent);
                }

                throw new SyntaxError(message);
            });
    })
    .createTech();
<|endoftext|>