exports.generateManifest = function(productPath, options)
{
    options = options || {};

    indexFilePath = options.index || FILE.join(productPath, "index.html");

    if (!FILE.isFile(indexFilePath)) {
        print("Warning: Skipping cache manifest generation, no index file at "+indexFilePath);
        return;
    }

    var index = FILE.read(indexFilePath, { charset : "UTF-8" });

    var manifestName = "app.manifest";
    var manifestPath = FILE.join(productPath, manifestName);
    var manifestAttribute = 'manifest="'+manifestName+'"';

    print("Generating cache manifest: " + manifestPath);

    var manifestOut = FILE.open(manifestPath, "w", { charset : "UTF-8" });
    manifestOut.print("CACHE MANIFEST");
    manifestOut.print("");
    manifestOut.print("CACHE:");

    var list = new FileList(FILE.join(productPath, "**", "*"));
    list.exclude(manifestPath);
    list.exclude("**/.DS_Store", "**/.htaccess");
    list.exclude("**/LICENSE");
    list.exclude("**/MHTML*");
    list.exclude("**/CommonJS.environment/*");
    list.exclude("**/*.cur");


    if (index.indexOf('"Frameworks/Debug"') < 0)
        list.exclude("**/Frameworks/Debug/*");

    if (options.exclude)
        options.exclude.forEach(list.exclude.bind(list));

    list.forEach(function(path) {
        if (FILE.isFile(path)) {
            var relative = FILE.relative(productPath, path);



            if (BundleTask.isSpritable(path) && index.indexOf(relative) < 0)
                return;


            var hash = MD5.hash(FILE.read(path, "b")).decodeToString("base16");
            manifestOut.print("# " + hash);
            manifestOut.print(relative);
        }
    });

    manifestOut.print("");
    manifestOut.print("NETWORK:");
    manifestOut.print("*");
    manifestOut.close();


    var matchTag = index.match(/<html[^>]*>/i);
    if (matchTag) {
        var htmlTag = matchTag[0];
        var newHTMLTag = null;

        var matchAttr = htmlTag.match(/manifest\s*=\s*"([^"]*)"/i);
        if (matchAttr) {
            if (matchAttr[1] !== manifestName) {
                newHTMLTag = htmlTag.replace(matchAttr[0], manifestAttribute);
            }
        } else {
            newHTMLTag = htmlTag.replace(/>$/, " "+manifestAttribute+">");
        }

        if (newHTMLTag) {
            print("Replacing html tag: \n    " + htmlTag + "\nwith:\n    " + newHTMLTag);
            var newIndex = index.replace(htmlTag, newHTMLTag);
            if (newIndex === index) {
                print("Warning: No change!");
            } else {
                FILE.write(indexFilePath, newIndex, { charset : "UTF-8" });
            }
        }
    }
    else {
        print("Warning: Couldn't find <html> tag in "+indexFilePath);
    }



    var htaccessPath = FILE.join(productPath, ".htaccess");
    var htaccess = FILE.isFile(htaccessPath) ? FILE.read(htaccessPath, { charset : "UTF-8" }) : "";

    var htaccessOut = FILE.open(htaccessPath, "w", { charset : "UTF-8" });
    htaccessOut.print(htaccess);

    var openTag = "<Files "+manifestName+">";
    if (htaccess.indexOf(openTag) < 0) {
        htaccessOut.print("");
        htaccessOut.print(openTag);
        htaccessOut.print("\tHeader set Content-Type text/cache-manifest");
        htaccessOut.print("</Files>");
    }
    htaccessOut.close();
}
Esempio n. 2
0
task('test', ['concat'], function () {
    // TODO: use a testing suite for testing: nodeunit, mocha, tap, ...
    var filelist = new jake.FileList();
    filelist.include([
        './test/**/*.js'
    ]);

    var files = filelist.toArray();
    files.forEach(function (file) {
        require('./' + file);
    });

    console.log('Executed ' + files.length + ' test files successfully');
});
Esempio n. 3
0
task("lint", [], function() {

    console.log('---------- lint the code');
    var files = new jake.FileList();
    files.include("src/*.js");

    var options = {
        node: true
    };

    var globals = {
        describe: false
    };

    var pass = lint.validateFileList(files.toArray(), options, globals);
    if (!pass) fail("Lint failed");
});
Esempio n. 4
0
/**
 * Minify files using uglify-js.
 *
 * Example:
 *     var result = minify({
 *         src:  [
 *             './lib/mylibrary.js'
 *         ],
 *         dest: './lib/mylibrary.min.js',       // optional
 *         options: {},                          // uglify-js options. optional
 *         header: '// license information...',  // optional
 *         separator: '\n',                      // optional
 *         footer: '// the end...'               // optional
 *     });
 *
 * @param {Object} params  Object containing:
 *                         {String | String[]} src  One source file or an array
 *                                                  with source files to be
 *                                                  minified. The file names
 *                                                  can contain patterns.
 *                         {String} [dest]      The target file. Optional
 *                         {Object} [options]   uglify-js options.
 *                         {String} [header]    Text to be added on top.
 *                                              Optional.
 *                         {String} [separator] Text to be inserted between
 *                                              header, contents and footer.
 *                                              Optional.
 *                         {String} [footer]    Text to be added at the bottom.
 *                                              Optional.
 * @return {Object} res    Result information. The object contains:
 *                         {String[]} src       List with the filenames of the
 *                                              files which are minified
 *                         {String} code        The contents of the minified
 *                                              file.
 */
function minify (params) {
    // do some checks on the provided parameters
    if (!(params instanceof Object)) {
        throw new Error('Object with parameters expected as first argument.');
    }
    if (!params.src) {
        throw new Error('Parameter "src" containing an array with filenames missing.');
    }
    if (params.options) {
        if (!(params.options instanceof Object)) {
            throw new Error('Parameter "options" must be an object.');
        }
    }

    var code = '';
    var separator = params.separator ? String(params.separator) : '';
    var options = params.options || {};

    // header
    if (params.header) {
        code += String(params.header) + separator;
    }

    // src
    var filelist = new jake.FileList();
    filelist.include(params.src);
    var filenames = filelist.toArray();
    var minified = uglify.minify(filenames, options);
    code += minified.code;

    // footer
    if (params.footer) {
        code += separator + String(params.footer);
    }

    // write output
    if (params.dest) {
        write(params.dest, code);
    }

    return {
        src: filenames,
        code: code
    };
}
Esempio n. 5
0
/**
 * Replace patterns in text files.
 * Patterns can be a string or a regular expression.
 *
 * Example usage:
 *     var result = replace({
 *         replacements: [
 *             {pattern: '@@date',    replacement: '2013-02-18'},
 *             {pattern: '@@version', replacement: '1.4.0'}
 *         },
 *         src: [
 *          'main.js',
 *          'other/*.js'
 *         ]
 *     });
 *
 * @param {Object} params Object containing parameters:
 *                        {Object[]} replacements Array containing objects with
 *                                                parameters:
 *                                                {String | RegExp} pattern
 *                                                {String}          replacement
 *                        {String | String[]} src The filenames. Can contain
 *                                                patterns.
 * @return {Object} res   Result information. The object contains:
 *                        {String[]} src       List with the filenames on which
 *                                             the replacement is executed
 * @throws {Error}
 */
// TODO: change params of src such that we can also use regex expressions
function replace (params) {
    // do some checks on the provided parameters
    if (!(params instanceof Object)) {
        throw new Error('Object with parameters expected as first argument.');
    }
    if (!params.replacements) {
        throw new Error('Parameter "replacements" missing.');
    }
    if (!(params.replacements instanceof Array)) {
        throw new Error('Parameter "replacements" must be an array.');
    }
    if (!params.src) {
        throw new Error('Parameter "src" containing an array with filenames missing.');
    }

    var filelist = new jake.FileList();
    filelist.include(params.src);
    var filenames = filelist.toArray();

    filenames.forEach(function (filename) {
        var file = String(read(filename));
        params.replacements.forEach(function (replacement, index) {
            // check the replacement parameters
            if (!(replacement instanceof Object)) {
                throw new Error('Parameter "replacement" must be an object.');
            }
            if (!replacement.pattern) {
                throw new Error('Parameter "pattern" in missing replacement object ' +
                    '(index ' + index + ')');
            }
            if (!replacement.replacement) {
                throw new Error('Parameter "replacement" missing in replacement object ' +
                    '(index ' + index + ')');
            }

            file = file.replace(replacement.pattern, replacement.replacement);
        });
        write(filename, file);
    });

    return {
        src: filenames
    }
}
Esempio n. 6
0
/**
 * Concatenate a list with files into one file
 *
 * Example:
 *     var result = concat({
 *         src: [
 *             './src/main.js',
 *             './src/extra.js',
 *             './src/functions/**',
 *         ],
 *         dest: './lib/mylibrary.js',           // optional
 *         header: '// license information...',  // optional
 *         separator: '\n',                      // optional
 *         footer: '// the end...'               // optional
 *     });
 *
 * @param {Object} params  Object containing:
 *                         {String[]} src       A list with source files to be
 *                                              Included. Can contain patterns.
 *                         {String} [dest]      The target file. Optional
 *                         {String} [separator] Text to be inserted between the
 *                                              files. Optional.
 *                         {String} [header]    Text to be added on top.
 *                                              Optional.
 *                         {String} [footer]    Text to be added at the bottom.
 *                                              Optional.
 * @return {Object} res    Result information. The object contains:
 *                         {String[]} src       List with the filenames of the
 *                                              files which are concatenated
 *                         {String} code        The contents of the concatenated
 *                                              file
 */
function concat (params) {
    // do some checks on the provided parameters
    if (!(params instanceof Object)) {
        throw new Error('Object with parameters expected as first argument.');
    }
    if (!params.src) {
        throw new Error('Parameter "src" containing an array with filenames missing.');
    }

    var code = '';
    var separator = params.separator ? String(params.separator) : '';

    // header
    if (params.header) {
        code += String(params.header) + separator;
    }

    // files
    var filelist = new jake.FileList();
    filelist.include(params.src);
    var filenames = filelist.toArray();
    filenames.map(function(filename) {
        code += read(filename) + separator;
    });

    // footer
    if (params.footer) {
        code += String(params.footer);
    }

    // write output
    if (params.dest) {
        // write file
        write(params.dest, code);
    }

    return {
        src: filenames,
        code: code
    };
}
Esempio n. 7
0
 var TARGET_UNCOMPRESSED_DEPENDENCIES = (function () {
     var all = new jake.FileList();
     all.include('./Jakefile.js', 'own-testcases.json');
     all.include('src/**');
     all.include('test/**');
     all.exclude(TARGET_COMPRESSED);
     return all.toArray();
 }());
Esempio n. 8
0
/**
 * Compiles less files to css
 *
 * @param Object options
 * @param Function cb
 *
 * Options:
 *
 * - Array src - List of glob patterns for source files
 * - String dest - Destination directory
 * - Boolean debug - if true source maps will be generated
 */
function compileLess(options, cb)
{
  cb = cb || noop;
  var src = options.src;
  var dest = options.dest;

  var lessFiles = new jake.FileList();
  lessFiles.include(src);

  var done = 0;

  var fileCb = (typeof options.dest === 'function') ? toCb(options.dest) : toFile;

  lessFiles = lessFiles.toArray();
  lessFiles.forEach(fileCb);

  function toFile(file) {
    var destFile = path.join(dest, path.basename(file).replace('.less', '.css'));

    // remove existing css
    jake.rmRf(destFile, {silent: true});

    console.log('Writing css to ' + destFile);
    less.render(
        fs.readFileSync(file, 'utf8'),
        {
          paths: src.map(function(_src) { return path.dirname(_src); }),
          sourceMap: true
        },
        onRendered.bind(null, destFile)
    );
  }

  function toCb(cb) {
    return function(file) {
      less.render(
        fs.readFileSync(file, 'utf8'),
        {
          paths: src.map(function(_src) { return path.dirname(_src); }),
          sourceMap: true
        },
        cb
      );
    };
  }

  function onRendered(dest, error, css) {
    if (error) {
      console.error(error);
      onDone();
    }
    else {
      if (!options.debug) {
        fs.writeFile(dest, css.css, 'utf8', onDone);
        return;
      }

      var s = new stream.Readable();
      s._read = noop;
      s.push(css.css);
      s.push(null);

      var smap = new stream.Duplex();

      smap._write = function(data) {
        smap.push(data.toString().replace(new RegExp("\/\/# sourceMappingURL=(.*)?"), '/*# sourceMappingURL=$1*/'));
        smap.push(null);
      };
      smap._read = noop;

      s.pipe(exorcist(dest + '.map'))
          .pipe(smap)
          .pipe(fs.createWriteStream(dest, 'utf8'))
          .on('finish', onDone);
    }
  }

  function onDone()
  {
    done++;

    if (done === lessFiles.length) {
      cb(null);
    }
  }
}