source: Dev/trunk/node_modules/grunt-zip/tasks/zip.js @ 484

Last change on this file since 484 was 484, checked in by hendrikvanantwerpen, 11 years ago

Commit node_modules, to make checkouts and builds more deterministic.

File size: 5.4 KB
Line 
1/*
2 * grunt-zip
3 * https://github.com/twolfson/grunt-zip
4 *
5 * Copyright (c) 2013 Todd Wolfson
6 * Licensed under the MIT license.
7 */
8
9var fs = require('fs'),
10    path = require('path'),
11    Zip = require('node-zip'),
12    gruntRetro = require('grunt-retro');
13module.exports = function(grunt) {
14  // Load and bind grunt-retro
15  grunt = gruntRetro(grunt);
16
17  // Please see the grunt documentation for more information regarding task and
18  // helper creation: https://github.com/gruntjs/grunt/blob/master/docs/toc.md
19
20  // ==========================================================================
21  // TASKS
22  // ==========================================================================
23
24  // Localize underscore
25  var _ = grunt.utils._;
26
27  grunt.registerMultiTask('zip', 'Zip files together', function() {
28    // Localize variables
29    var file = this.file,
30        data = this.data,
31        src = file.src,
32        dest = file.dest,
33        router = data.router;
34
35    // Fallback options (e.g. base64, compression)
36    _.defaults(data, {
37      base64: false
38    });
39
40    // Collect our file paths
41    var globOptions = {dot: data.dot},
42        srcFolders = grunt.file.expandDirs(globOptions, src),
43        srcFiles = grunt.file.expandFiles(globOptions, src);
44
45    // If there is no router
46    if (!router) {
47      // Grab the cwd and return the relative path as our router
48      var cwd = data.cwd || process.cwd();
49      router = function routerFn (filepath) {
50        return path.relative(cwd, filepath);
51      };
52    } else if (data.cwd) {
53    // Otherwise, if a `cwd` was specified, throw a fit and leave
54      grunt.fail.warn('grunt-zip does not accept `cwd` and `router` in the same config due to potential ordering complications. Please choose one.');
55    }
56
57    // Generate our zipper
58    var zip = new Zip();
59
60    // For each of the srcFolders
61    srcFolders.forEach(function (folderpath) {
62      // Route the folder
63      var routedPath = router(folderpath);
64
65      // If there is a folder, add it to the zip (allows for skipping)
66      if (routedPath) {
67        zip.folder(routedPath);
68      }
69    });
70
71    // For each of the srcFiles
72    srcFiles.forEach(function (filepath) {
73      // Read in the content and add it to the zip
74      var input = fs.readFileSync(filepath, 'binary'),
75          routedPath = router(filepath);
76
77      // If it has a path, add it (allows for skipping)
78      if (routedPath) {
79        zip.file(routedPath, input, {binary: true});
80      }
81    });
82
83    // Create the destination directory
84    var destDir = path.dirname(dest);
85    grunt.file.mkdir(destDir);
86
87    // Write out the content
88    var output = zip.generate({base64: data.base64, compression: data.compression});
89    fs.writeFileSync(dest, output, 'binary');
90
91    // Fail task if errors were logged.
92    if (this.errorCount) { return false; }
93
94    // Otherwise, print a success message.
95    grunt.log.writeln('File "' + dest + '" created.');
96  });
97
98  function echo(a) {
99    return a;
100  }
101  grunt.registerMultiTask('unzip', 'Unzip files into a folder', function() {
102    // Collect the filepaths we need
103    var file = this.file,
104        data = this.data,
105        src = file.src,
106        srcFiles = grunt.file.expand(src),
107        dest = file.dest,
108        router = data.router || echo;
109
110    // Fallback options (e.g. checkCRC32)
111    _.defaults(data, {
112      base64: false,
113      checkCRC32: true
114    });
115
116    // Iterate over the srcFiles
117    srcFiles.forEach(function (filepath) {
118      // Read in the contents
119      var input = fs.readFileSync(filepath, 'binary');
120
121      // Unzip it
122      var zip = new Zip(input, {base64: data.base64, checkCRC32: data.checkCRC32});
123
124      // Pluck out the files
125      var files = zip.files,
126          filenames = Object.getOwnPropertyNames(files);
127
128      // Filter out all non-leaf files
129      filenames = filenames.filter(function filterNonLeafs (filename) {
130        // Iterate over the other filenames
131        var isLeaf = true,
132            i = filenames.length,
133            otherFile,
134            pathToFile,
135            isParentDir;
136        while (i--) {
137          // If the other file is the current file, skip it
138          otherFile = filenames[i];
139          if (otherFile === filename) {
140            continue;
141          }
142
143          // Determine if this file contains the other
144          pathToFile = path.relative(filename, otherFile);
145          isParentDir = pathToFile.indexOf('..') === -1;
146
147          // If it does, falsify isLeaf
148          if (isParentDir) {
149            isLeaf = false;
150            break;
151          }
152        }
153
154        // Return that the file was a leaf
155        return isLeaf;
156      });
157
158      // Iterate over the files
159      filenames.forEach(function (filename) {
160        // Find the content
161        var fileObj = files[filename],
162            content = fileObj.data,
163            routedName = router(filename);
164
165        // If there is a file path (allows for skipping)
166        if (routedName) {
167          // Determine the filepath
168          var filepath = path.join(dest, routedName);
169
170          // Create the destination directory
171          var fileDir = path.dirname(filepath);
172          grunt.file.mkdir(fileDir);
173
174          // Write out the content
175          fs.writeFileSync(filepath, content, 'binary');
176        }
177      });
178    });
179
180    // Fail task if errors were logged.
181    if (this.errorCount) { return false; }
182
183    // Otherwise, print a success message.
184    grunt.log.writeln('File "' + this.file.dest + '" created.');
185  });
186
187};
Note: See TracBrowser for help on using the repository browser.