Search code examples
node.jszipglob

Creating Zip archive from git ls-files list using ArchiverJS


I am trying to create a zip archive using archiverjs that contains only the files that git ls-files would show, less some exclusions.

My code to get the file names is

var listFiles = function() {
  var promise = new Promise(function (resolve, reject) {
    var exec = require('child_process').exec;
    var child;

    child = exec("cd ..; git ls-files", function (error, stdout, stderr) {
      if (error !== null) {
        return reject(error)
      }

      var result = stdout.split("\n");
      resolve(result);
    });
  });
  return promise;
};

Then my actual bundling function looks like

DeploymentUtil.prototype.CreateApplicationVersionBundle = function (pathToApplication,
                                                                    versionLabel,
                                                                    target) {
  var promise = new Promise(function (resolve, reject) {
      // Create the archive
      var output = fs.createWriteStream(versionLabel + ".zip");
      output.on('close', function () {
        resolve(output);
      });

      var archive = archiver.create("zip");

      // Error handling
      archive.on('error', function (err) {
        reject(err);
      });

      // get the files from git
      listFiles().then(function(files) {
        var exclusions = [
          '!**/.keep',
          '!.codeclimate.yml',
          '!.csslintrc',
          '!.travis.yml',
          '!env_sample',
          '!spec/**'
        ];

        for(var i = 0, l = 9; i < l; i++ ) {
          console.log(files[i]);
        }

        archive.bulk([{
          expand: true,
          cwd: pathToApplication,
          src: files.concat(exclusions),
          dot: true
        }]);

        archive.pipe(output);
        archive.finalize();
      }).catch(reject);
  });
  return promise;
}

Running this archive.bulk throws an error: must provide pattern.

If I replace src: files.concat(exclusions) with [**/**] however it works (only I get a lot of files I don't want in my archive).

How can I fix this?


Solution

  • The output from git ls-files will contain a terminating newline character.

    When you then call split("\n") on theresult, you will get an array where the last element is the empty string ("").

    ArchiverJS probably does not like an empty string as a pattern.

    One solution is to trim the string before splitting it:

    var result = stdout.trim().split("\n");