You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							210 lines
						
					
					
						
							6.7 KiB
						
					
					
				
			
		
		
	
	
							210 lines
						
					
					
						
							6.7 KiB
						
					
					
				/**
 | 
						|
 * archiver-utils
 | 
						|
 *
 | 
						|
 * Copyright (c) 2012-2014 Chris Talkington, contributors.
 | 
						|
 * Licensed under the MIT license.
 | 
						|
 * https://github.com/archiverjs/node-archiver/blob/master/LICENSE-MIT
 | 
						|
 */
 | 
						|
var fs = require('graceful-fs');
 | 
						|
var path = require('path');
 | 
						|
 | 
						|
var flatten = require('lodash.flatten');
 | 
						|
var difference = require('lodash.difference');
 | 
						|
var union = require('lodash.union');
 | 
						|
var isPlainObject = require('lodash.isplainobject');
 | 
						|
 | 
						|
var glob = require('glob');
 | 
						|
 | 
						|
var file = module.exports = {};
 | 
						|
 | 
						|
var pathSeparatorRe = /[\/\\]/g;
 | 
						|
 | 
						|
// Process specified wildcard glob patterns or filenames against a
 | 
						|
// callback, excluding and uniquing files in the result set.
 | 
						|
var processPatterns = function(patterns, fn) {
 | 
						|
  // Filepaths to return.
 | 
						|
  var result = [];
 | 
						|
  // Iterate over flattened patterns array.
 | 
						|
  flatten(patterns).forEach(function(pattern) {
 | 
						|
    // If the first character is ! it should be omitted
 | 
						|
    var exclusion = pattern.indexOf('!') === 0;
 | 
						|
    // If the pattern is an exclusion, remove the !
 | 
						|
    if (exclusion) { pattern = pattern.slice(1); }
 | 
						|
    // Find all matching files for this pattern.
 | 
						|
    var matches = fn(pattern);
 | 
						|
    if (exclusion) {
 | 
						|
      // If an exclusion, remove matching files.
 | 
						|
      result = difference(result, matches);
 | 
						|
    } else {
 | 
						|
      // Otherwise add matching files.
 | 
						|
      result = union(result, matches);
 | 
						|
    }
 | 
						|
  });
 | 
						|
  return result;
 | 
						|
};
 | 
						|
 | 
						|
// True if the file path exists.
 | 
						|
file.exists = function() {
 | 
						|
  var filepath = path.join.apply(path, arguments);
 | 
						|
  return fs.existsSync(filepath);
 | 
						|
};
 | 
						|
 | 
						|
// Return an array of all file paths that match the given wildcard patterns.
 | 
						|
file.expand = function(...args) {
 | 
						|
  // If the first argument is an options object, save those options to pass
 | 
						|
  // into the File.prototype.glob.sync method.
 | 
						|
  var options = isPlainObject(args[0]) ? args.shift() : {};
 | 
						|
  // Use the first argument if it's an Array, otherwise convert the arguments
 | 
						|
  // object to an array and use that.
 | 
						|
  var patterns = Array.isArray(args[0]) ? args[0] : args;
 | 
						|
  // Return empty set if there are no patterns or filepaths.
 | 
						|
  if (patterns.length === 0) { return []; }
 | 
						|
  // Return all matching filepaths.
 | 
						|
  var matches = processPatterns(patterns, function(pattern) {
 | 
						|
    // Find all matching files for this pattern.
 | 
						|
    return glob.sync(pattern, options);
 | 
						|
  });
 | 
						|
  // Filter result set?
 | 
						|
  if (options.filter) {
 | 
						|
    matches = matches.filter(function(filepath) {
 | 
						|
      filepath = path.join(options.cwd || '', filepath);
 | 
						|
      try {
 | 
						|
        if (typeof options.filter === 'function') {
 | 
						|
          return options.filter(filepath);
 | 
						|
        } else {
 | 
						|
          // If the file is of the right type and exists, this should work.
 | 
						|
          return fs.statSync(filepath)[options.filter]();
 | 
						|
        }
 | 
						|
      } catch(e) {
 | 
						|
        // Otherwise, it's probably not the right type.
 | 
						|
        return false;
 | 
						|
      }
 | 
						|
    });
 | 
						|
  }
 | 
						|
  return matches;
 | 
						|
};
 | 
						|
 | 
						|
// Build a multi task "files" object dynamically.
 | 
						|
file.expandMapping = function(patterns, destBase, options) {
 | 
						|
  options = Object.assign({
 | 
						|
    rename: function(destBase, destPath) {
 | 
						|
      return path.join(destBase || '', destPath);
 | 
						|
    }
 | 
						|
  }, options);
 | 
						|
  var files = [];
 | 
						|
  var fileByDest = {};
 | 
						|
  // Find all files matching pattern, using passed-in options.
 | 
						|
  file.expand(options, patterns).forEach(function(src) {
 | 
						|
    var destPath = src;
 | 
						|
    // Flatten?
 | 
						|
    if (options.flatten) {
 | 
						|
      destPath = path.basename(destPath);
 | 
						|
    }
 | 
						|
    // Change the extension?
 | 
						|
    if (options.ext) {
 | 
						|
      destPath = destPath.replace(/(\.[^\/]*)?$/, options.ext);
 | 
						|
    }
 | 
						|
    // Generate destination filename.
 | 
						|
    var dest = options.rename(destBase, destPath, options);
 | 
						|
    // Prepend cwd to src path if necessary.
 | 
						|
    if (options.cwd) { src = path.join(options.cwd, src); }
 | 
						|
    // Normalize filepaths to be unix-style.
 | 
						|
    dest = dest.replace(pathSeparatorRe, '/');
 | 
						|
    src = src.replace(pathSeparatorRe, '/');
 | 
						|
    // Map correct src path to dest path.
 | 
						|
    if (fileByDest[dest]) {
 | 
						|
      // If dest already exists, push this src onto that dest's src array.
 | 
						|
      fileByDest[dest].src.push(src);
 | 
						|
    } else {
 | 
						|
      // Otherwise create a new src-dest file mapping object.
 | 
						|
      files.push({
 | 
						|
        src: [src],
 | 
						|
        dest: dest,
 | 
						|
      });
 | 
						|
      // And store a reference for later use.
 | 
						|
      fileByDest[dest] = files[files.length - 1];
 | 
						|
    }
 | 
						|
  });
 | 
						|
  return files;
 | 
						|
};
 | 
						|
 | 
						|
// reusing bits of grunt's multi-task source normalization
 | 
						|
file.normalizeFilesArray = function(data) {
 | 
						|
  var files = [];
 | 
						|
 | 
						|
  data.forEach(function(obj) {
 | 
						|
    var prop;
 | 
						|
    if ('src' in obj || 'dest' in obj) {
 | 
						|
      files.push(obj);
 | 
						|
    }
 | 
						|
  });
 | 
						|
 | 
						|
  if (files.length === 0) {
 | 
						|
    return [];
 | 
						|
  }
 | 
						|
 | 
						|
  files = _(files).chain().forEach(function(obj) {
 | 
						|
    if (!('src' in obj) || !obj.src) { return; }
 | 
						|
    // Normalize .src properties to flattened array.
 | 
						|
    if (Array.isArray(obj.src)) {
 | 
						|
      obj.src = flatten(obj.src);
 | 
						|
    } else {
 | 
						|
      obj.src = [obj.src];
 | 
						|
    }
 | 
						|
  }).map(function(obj) {
 | 
						|
    // Build options object, removing unwanted properties.
 | 
						|
    var expandOptions = Object.assign({}, obj);
 | 
						|
    delete expandOptions.src;
 | 
						|
    delete expandOptions.dest;
 | 
						|
 | 
						|
    // Expand file mappings.
 | 
						|
    if (obj.expand) {
 | 
						|
      return file.expandMapping(obj.src, obj.dest, expandOptions).map(function(mapObj) {
 | 
						|
        // Copy obj properties to result.
 | 
						|
        var result = Object.assign({}, obj);
 | 
						|
        // Make a clone of the orig obj available.
 | 
						|
        result.orig = Object.assign({}, obj);
 | 
						|
        // Set .src and .dest, processing both as templates.
 | 
						|
        result.src = mapObj.src;
 | 
						|
        result.dest = mapObj.dest;
 | 
						|
        // Remove unwanted properties.
 | 
						|
        ['expand', 'cwd', 'flatten', 'rename', 'ext'].forEach(function(prop) {
 | 
						|
          delete result[prop];
 | 
						|
        });
 | 
						|
        return result;
 | 
						|
      });
 | 
						|
    }
 | 
						|
 | 
						|
    // Copy obj properties to result, adding an .orig property.
 | 
						|
    var result = Object.assign({}, obj);
 | 
						|
    // Make a clone of the orig obj available.
 | 
						|
    result.orig = Object.assign({}, obj);
 | 
						|
 | 
						|
    if ('src' in result) {
 | 
						|
      // Expose an expand-on-demand getter method as .src.
 | 
						|
      Object.defineProperty(result, 'src', {
 | 
						|
        enumerable: true,
 | 
						|
        get: function fn() {
 | 
						|
          var src;
 | 
						|
          if (!('result' in fn)) {
 | 
						|
            src = obj.src;
 | 
						|
            // If src is an array, flatten it. Otherwise, make it into an array.
 | 
						|
            src = Array.isArray(src) ? flatten(src) : [src];
 | 
						|
            // Expand src files, memoizing result.
 | 
						|
            fn.result = file.expand(expandOptions, src);
 | 
						|
          }
 | 
						|
          return fn.result;
 | 
						|
        }
 | 
						|
      });
 | 
						|
    }
 | 
						|
 | 
						|
    if ('dest' in result) {
 | 
						|
      result.dest = obj.dest;
 | 
						|
    }
 | 
						|
 | 
						|
    return result;
 | 
						|
  }).flatten().value();
 | 
						|
 | 
						|
  return files;
 | 
						|
};
 |