Permalink
Browse files

initial commit

  • Loading branch information...
1 parent f06b620 commit 8356d9293abebcb83fc16f5689663f26b802eed3 @sergiok committed Jun 12, 2012
Showing with 430 additions and 0 deletions.
  1. +3 −0 .gitignore
  2. +4 −0 .npmignore
  3. +5 −0 History.md
  4. +22 −0 LICENSE
  5. +3 −0 TODO
  6. +1 −0 index.js
  7. +259 −0 lib/bundler.js
  8. +82 −0 lib/util.js
  9. BIN lib/yuicompressor-2.4.7.jar
  10. +22 −0 package.json
  11. +29 −0 sample-assets.yml
View
@@ -0,0 +1,3 @@
+.DS_Store
+node_modules/
+tests/
View
@@ -0,0 +1,4 @@
+.git*
+examples/
+.DS_Store
+sample-assets.yml
View
@@ -0,0 +1,5 @@
+0.6.0 / 2012-06-12
+==================
+
+ * Initial release
+ * Basic package bundles
View
22 LICENSE
@@ -0,0 +1,22 @@
+(The MIT License)
+
+Copyright (c) 2012 Sergio Kuba <sk@skdev.me>
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+'Software'), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
View
3 TODO
@@ -0,0 +1,3 @@
+TODO
+- error handling
+- bundle dependencies
View
@@ -0,0 +1 @@
+module.exports = require('./lib/bundler')
View
@@ -0,0 +1,259 @@
+/*!
+ * Copyright(c) 2012 Sergio Kuba <sk@skdev.me>
+ * MIT Licensed
+ */
+var util = require('./util.js'),
+ fs = require('fs'),
+ exec = require('child_process').exec;
+
+var exports = module.exports,
+ RDIR = process.cwd();
+
+// default module config
+var _settings = {
+ debug: false,
+ deployDir: './',
+ fileEncoding: 'utf8',
+ isDevelopment: false,
+ license: '',
+ postfix: '',
+ prefix: '',
+ sourceDir: './',
+ staticCSS: '/css',
+ staticJS: '/js'
+};
+var _packages = {};
+
+var _log = function(msg) {
+ if (_settings.debug) {
+ console.log(msg);
+ }
+};
+
+var configure = function(config) {
+ if (typeof config === "string") {
+ config = util.getConfigContents(RDIR + '/' + config);
+
+ if (config.packages) {
+ setPackages(config.packages);
+ }
+
+ config = config.config;
+ }
+
+ if (config.license) {
+ config.license = ['/*!'].concat(config.license.split('\n').map(function(line) {
+ return ' * ' + line;
+ }));
+ config.license.push(' */');
+ config.license = config.license.join('\n');
+ }
+ util.extendObj(_settings, config);
+};
+
+var setPackages = function(packages) {
+ if (typeof packages === "string") {
+ packages = util.getConfigContents(RDIR + '/' + packages);
+ }
+
+ util.extendObj(_packages, packages);
+};
+
+var _processsDevelopmentFiles = function(pkgName, pkg, type, callback) {
+ var pkg = pkg[type],
+ srcFiles = pkg.sources,
+ scripts = [],
+ staticPath = _settings['static' + type.toUpperCase()] + (pkg.baseDir ? pkg.baseDir + '/' : '/'),
+ filesDir = RDIR + _settings.sourceDir + staticPath,
+ regexp = new RegExp("\." + type + "$", "i");
+
+ fs.readdir(filesDir, function(err, files) {
+ var srcFile;
+
+ for (var i = 0, srcFilesCount = srcFiles.length; i < srcFilesCount; i++) {
+ srcFile = srcFiles[i].split(':');
+
+ if (srcFile[0] === "*") {
+ for (var j = 0, filesCount = files.length; j < filesCount; j++) {
+ if ( !regexp.test(files[j]) ) {
+ continue;
+ }
+ scripts.push(staticPath + files[j]);
+ }
+
+ } else {
+ scripts.push(staticPath + srcFile[0]);
+ files = util.filterFiles(srcFile[0], files);
+ }
+ }
+ pkg.files = scripts;
+
+ callback();
+ });
+};
+
+var _processPkgFiles = function(pkgName, pkg, type, callback) {
+ var pkg = pkg[type],
+ srcFiles = pkg.sources,
+ scripts = [],
+ staticPath = _settings['static' + type.toUpperCase()] + (pkg.baseDir ? pkg.baseDir + '/' : '/'),
+ filesDir = RDIR + _settings.sourceDir + staticPath,
+ packedData = [],
+ regexp = new RegExp("\." + type + "$", "i");
+
+ pkg.asyncScriptsCount = pkg.asyncProcessedCount = 0;
+
+ var packFile = function(filename, compress, scriptIndex) {
+ if (compress) {
+ _log("------ PACKAGE " + pkgName + ": " + type.toUpperCase() + " compressing " + filename + ".");
+ exec('java -jar ' + __dirname + '/yuicompressor-2.4.7.jar ' + filename, function(err, stdout, stderr) {
+ _log("------ PACKAGE " + pkgName + ": finished " + type.toUpperCase() + " compressing " + filename + ".");
+ packedData[scriptIndex] = stdout;
+ pkg.asyncProcessedCount++;
+
+ checkPackComplete();
+ });
+
+ } else {
+ _log("------ PACKAGE " + pkgName + ": " + type.toUpperCase() + " appending " + filename + ".");
+ fs.readFile(filename, _settings.fileEncoding, function(err, data) {
+ _log("------ PACKAGE " + pkgName + ": finished " + type.toUpperCase() + " appending " + filename + ".");
+ packedData[scriptIndex] = data;
+ pkg.asyncProcessedCount++;
+
+ checkPackComplete();
+ });
+ }
+ };
+
+ var checkPackComplete = function() {
+ if (pkg.asyncScriptsCount === pkg.asyncProcessedCount) {
+ var packedFileName = _settings['static' + type.toUpperCase()] + '/' + _settings.prefix + pkgName + _settings.postfix + '.' + type;
+
+ util.rMakeDir(RDIR + _settings.deployDir + _settings['static' + type.toUpperCase()], 0755, function(err) {
+ if (err) throw err;
+
+ packedData = (type === "js" && _settings.license ? _settings.license + '\n' : '') + packedData.join('\n');
+ fs.writeFile(RDIR + _settings.deployDir + packedFileName, packedData, _settings.fileEncoding, function(err) {
+ if (err) throw err;
+
+ scripts.push(packedFileName);
+ pkg.files = scripts;
+
+ callback();
+ });
+ });
+ }
+ };
+
+ fs.readdir(filesDir, function(err, files) {
+ var srcFile;
+
+ for (var i = 0, srcFilesCount = srcFiles.length; i < srcFilesCount; i++) {
+ srcFile = srcFiles[i].split(':');
+
+ if (srcFile.length > 1 && srcFile[1] === "nocompression") {
+ if (srcFile[0] === "*") {
+ for (var j = 0, filesCount = files.length; j < filesCount; j++) {
+ if ( !regexp.test(files[j]) ) {
+ continue;
+ }
+
+ pkg.asyncScriptsCount++;
+ packFile(filesDir + files[j], false, pkg.asyncScriptsCount);
+ }
+
+ } else {
+ pkg.asyncScriptsCount++;
+ packFile(filesDir + srcFile[0], false, pkg.asyncScriptsCount);
+ files = util.filterFiles(srcFile[0], files);
+ }
+
+ } else {
+ if (srcFile[0] === "*") {
+ for (var j = 0, filesCount = files.length; j < filesCount; j++) {
+ if ( !regexp.test(files[j]) ) {
+ continue;
+ }
+
+ pkg.asyncScriptsCount++;
+ packFile(filesDir + files[j], true, pkg.asyncScriptsCount);
+ }
+
+ } else {
+ pkg.asyncScriptsCount++;
+ packFile(filesDir + srcFile[0], true, pkg.asyncScriptsCount);
+ files = util.filterFiles(srcFile[0], files);
+ };
+ }
+ }
+
+ if (pkg.asyncScriptsCount === 0) {
+ pkg.files = [];
+ callback();
+ }
+ });
+};
+
+var _processPackage = function(pkgName, pkg, cb) {
+ var processCount = 0,
+ processingFn;
+
+ var processCallback = function(assetType) {
+ processCount--;
+
+ _log("---- finished processing " + pkgName + " " + assetType.toUpperCase() + " files.");
+ if (processCount === 0) {
+ _log("-- finished processing PACKAGE: " + pkgName + ".");
+ cb();
+ }
+ };
+
+ if (_settings.isDevelopment) {
+ processingFn = _processsDevelopmentFiles;
+ } else {
+ processingFn = _processPkgFiles;
+ }
+
+
+ for (var assetType in pkg) {
+ processCount++;
+ _log("---- processing " + pkgName + " " + assetType.toUpperCase() + " files.");
+ processingFn(pkgName, pkg, assetType, (function(assetType) {
+ return function() {
+ processCallback(assetType);
+ }
+ })(assetType));
+ }
+};
+
+var init = function(cb) {
+ var pkgCount = pkgProcessed = 0;
+
+ for (var pkgName in _packages) {
+ pkgCount++;
+
+ _log("-- processing PACKAGE: " + pkgName + ".");
+ _processPackage(pkgName, _packages[pkgName], function() {
+ pkgProcessed++;
+ if (pkgCount === pkgProcessed) {
+ cb && cb();
+ }
+ });
+ }
+};
+
+var getFiles = function(pkgName, type) {
+ return _packages[pkgName][type].files;
+};
+
+// look for default configuration file and configure module
+try {
+ configure('assets.yml');
+} catch(e) {
+}
+
+exports.configure = configure;
+exports.setPackages = setPackages;
+exports.init = init;
+exports.getFiles = getFiles;
View
@@ -0,0 +1,82 @@
+/*!
+ * Copyright(c) 2012 Sergio Kuba <sk@skdev.me>
+ * MIT Licensed
+ */
+
+var fs = require('fs'),
+ yaml = require('js-yaml');
+
+var exports = module.exports;
+
+exports.extendObj = function(obj, newObj) {
+ for (x in newObj) {
+ obj[x] = newObj[x];
+ }
+
+ return obj;
+};
+
+exports.fileExists = function(filename) {
+ try {
+ fs.statSync(filename);
+ } catch(e) {
+ return false;
+ }
+
+ return true;
+};
+
+exports.getConfigContents = function(filename) {
+ if (this.fileExists(filename)) {
+ return require(filename).shift();
+ } else {
+ throw new Error('bad or missing config file.');
+ }
+};
+
+exports.filterFiles = function(filename, files) {
+ return files.filter(function(file) {
+ return (file !== filename);
+ });
+};
+
+
+/**
+ * recursive mkdir
+ * functionality was taken from https://github.com/bpedro/node-fs
+ * by Bruno Pedro https://github.com/bpedro
+ * I wasn't comfortable with overriding fs.mkdir :)
+ */
+exports.rMakeDir = function(path, mode, callback, position) {
+ /**
+ * Offers functionality similar to mkdir -p
+ *
+ * Asynchronous operation. No arguments other than a possible exception
+ * are given to the completion callback.
+ */
+ var osSep = process.platform === 'win32' ? '\\' : '/',
+ parts = require('path').normalize(path).split(osSep),
+ self = this;
+
+ mode = mode || process.umask();
+ position = position || 0;
+
+ if (position >= parts.length) {
+ return callback();
+ }
+
+ var directory = parts.slice(0, position + 1).join(osSep) || osSep;
+ fs.stat(directory, function(err) {
+ if (err === null) {
+ self.rMakeDir(path, mode, callback, position + 1);
+ } else {
+ fs.mkdir(directory, mode, function (err) {
+ if (err && err.errno != 17) {
+ return callback(err);
+ } else {
+ self.rMakeDir(path, mode, callback, position + 1);
+ }
+ });
+ }
+ });
+};
View
Binary file not shown.
Oops, something went wrong.

0 comments on commit 8356d92

Please sign in to comment.