Comparing version 0.3.1 to 0.4.0
@@ -60,4 +60,3 @@ // Generated by CoffeeScript 1.3.3 | ||
without_ext = options.mainfile.substring(0, options.mainfile.length - ext.length); | ||
console.error("Warning: don't include the file extension for input_file."); | ||
console.error("Did you mean this? " + without_ext); | ||
options.mainfile = without_ext; | ||
} | ||
@@ -64,0 +63,0 @@ |
146
jspackage.js
// Generated by CoffeeScript 1.3.3 | ||
var async, cached_files, collectDependencies, compile, extensions, fs, libs, options, parseFile, path, resolveDependencyChain, resolveImport, root, watchFile, watchFileFallback, watchFiles; | ||
var async, cached_files, collectDependencies, compile, extensions, fs, libs, parseFile, path, resolveDepend, resolveDependencyChain, root, watchFile, watchFileFallback, watchFiles, watching, | ||
__indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; | ||
@@ -12,15 +13,18 @@ fs = require('fs'); | ||
watching = null; | ||
libs = null; | ||
root = null; | ||
options = null; | ||
parseFile = function(full_path, cb) { | ||
parseFile = function(resolved_dep, cb) { | ||
var file; | ||
file = { | ||
path: full_path, | ||
path: resolved_dep.path, | ||
compiled_js: null, | ||
mtime: null, | ||
deps: [] | ||
deps: [], | ||
cwd: path.dirname(resolved_dep.path) | ||
}; | ||
return fs.stat(full_path, function(err, stat) { | ||
return fs.stat(resolved_dep.path, function(err, stat) { | ||
if (err) { | ||
@@ -31,4 +35,4 @@ cb(err); | ||
file.mtime = +stat.mtime; | ||
return fs.readFile(full_path, 'utf8', function(err, source) { | ||
var import_string, parser, re, result, timestamp; | ||
return fs.readFile(resolved_dep.path, 'utf8', function(err, source) { | ||
var depend, options, parser, re, result, seen, timestamp; | ||
if (err) { | ||
@@ -38,18 +42,27 @@ cb(err); | ||
} | ||
parser = extensions[path.extname(full_path)]; | ||
parser = extensions[path.extname(resolved_dep.path)]; | ||
try { | ||
file.compiled_js = parser.compile(source); | ||
file.compiled_js = parser.compile(source, resolved_dep.options); | ||
} catch (err) { | ||
cb("" + full_path + "\n" + err, file); | ||
cb("" + resolved_dep.path + "\n" + err, file); | ||
return; | ||
} | ||
if (options.watch) { | ||
if (watching) { | ||
timestamp = (new Date()).toLocaleTimeString(); | ||
console.info("" + timestamp + " - compiled " + file.path); | ||
} | ||
re = parser.import_re; | ||
re = parser.depend_re; | ||
re.lastIndex = 0; | ||
while (result = re.exec(source)) { | ||
import_string = result[1].slice(1, -1); | ||
file.deps.push(import_string); | ||
depend = result[1]; | ||
options = { | ||
bare: result[2] != null | ||
}; | ||
seen = resolved_dep.seen.concat(file.path); | ||
file.deps.push({ | ||
depend: depend, | ||
options: options, | ||
cwd: file.cwd, | ||
seen: seen | ||
}); | ||
} | ||
@@ -61,3 +74,3 @@ return cb(null, file); | ||
resolveImport = function(cwd, import_string, doneResolvingImport) { | ||
resolveDepend = function(dep, doneResolvingDepend) { | ||
var lib_index, tryNextLib, try_exts; | ||
@@ -71,3 +84,3 @@ try_exts = Object.keys(extensions); | ||
var resolved_path; | ||
resolved_path = path.resolve(cwd, try_lib, import_string + ext); | ||
resolved_path = path.resolve(dep.cwd, try_lib, dep.depend + ext); | ||
return fs.realpath(resolved_path, function(err, real_path) { | ||
@@ -92,7 +105,11 @@ if (err) { | ||
if (results.length === 1) { | ||
doneResolvingImport(null, results[0]); | ||
doneResolvingDepend(null, { | ||
path: results[0], | ||
options: dep.options, | ||
seen: dep.seen | ||
}); | ||
} else if (results.length === 0) { | ||
tryNextLib(); | ||
} else if (results.length > 1) { | ||
doneResolvingImport("ambiguous import: " + import_string); | ||
doneResolvingDepend("ambiguous dependency: " + dep.depend); | ||
} | ||
@@ -102,3 +119,3 @@ }); | ||
} else { | ||
return doneResolvingImport("unable to resolve import: " + import_string); | ||
return doneResolvingDepend("unable to resolve dependency: " + dep.depend); | ||
} | ||
@@ -110,12 +127,8 @@ }; | ||
resolveDependencyChain = function(root, doneResolvingDependencyChain) { | ||
var deps, processNode, seen; | ||
deps = []; | ||
var files, processNode, seen; | ||
files = []; | ||
seen = {}; | ||
processNode = function(node, doneProcessingNode) { | ||
var resolveFromDep; | ||
resolveFromDep = function(dep, cb) { | ||
return resolveImport(path.dirname(node.path), dep, cb); | ||
}; | ||
return async.map(node.deps, resolveFromDep, function(err, resolved_deps) { | ||
var dep, dep_path, funcs, _i, _len; | ||
return async.map(node.deps, resolveDepend, function(err, resolved_deps) { | ||
var dep, file, funcs, _i, _len; | ||
if (err) { | ||
@@ -127,9 +140,9 @@ doneResolvingDependencyChain(err); | ||
for (_i = 0, _len = resolved_deps.length; _i < _len; _i++) { | ||
dep_path = resolved_deps[_i]; | ||
dep = cached_files[dep_path]; | ||
if (seen[dep.path] != null) { | ||
dep = resolved_deps[_i]; | ||
file = cached_files[dep.path]; | ||
if (seen[file.path] != null) { | ||
continue; | ||
} | ||
seen[dep.path] = true; | ||
funcs.push(async.apply(processNode, dep)); | ||
seen[file.path] = true; | ||
funcs.push(async.apply(processNode, file)); | ||
} | ||
@@ -141,3 +154,3 @@ return async.parallel(funcs, function(err, results) { | ||
} | ||
deps.push(node); | ||
files.push(node); | ||
return doneProcessingNode(); | ||
@@ -148,9 +161,9 @@ }); | ||
return processNode(root, function() { | ||
return doneResolvingDependencyChain(null, deps); | ||
return doneResolvingDependencyChain(null, files); | ||
}); | ||
}; | ||
collectDependencies = function(cwd, import_string, doneCollectingDependencies) { | ||
return resolveImport(cwd, import_string, function(err, canonical_path) { | ||
var cached_file, callNext, parseAndHandleErr; | ||
collectDependencies = function(dep, doneCollectingDependencies) { | ||
return resolveDepend(dep, function(err, resolved_dep) { | ||
var cached_file, callNext, dep_chain, parseAndHandleErr, _ref; | ||
if (err) { | ||
@@ -160,4 +173,9 @@ doneCollectingDependencies(err); | ||
} | ||
if (_ref = resolved_dep.path, __indexOf.call(dep.seen, _ref) >= 0) { | ||
dep_chain = dep.seen.concat(resolved_dep.path).join(" depends on\n"); | ||
doneCollectingDependencies("circular dependency:\n" + dep_chain); | ||
return; | ||
} | ||
parseAndHandleErr = function(cb) { | ||
return parseFile(canonical_path, function(err, file) { | ||
return parseFile(resolved_dep, function(err, file) { | ||
if (file) { | ||
@@ -177,10 +195,6 @@ cached_files[file.path] = file; | ||
callNext = function(file) { | ||
var collectFromFile; | ||
collectFromFile = function(dep, cb) { | ||
return collectDependencies(path.dirname(file.path), dep, cb); | ||
}; | ||
return async.map(file.deps, collectFromFile, doneCollectingDependencies); | ||
return async.map(file.deps, collectDependencies, doneCollectingDependencies); | ||
}; | ||
if ((cached_file = cached_files[canonical_path]) != null) { | ||
return fs.stat(canonical_path, function(err, stat) { | ||
if ((cached_file = cached_files[resolved_dep.path]) != null) { | ||
return fs.stat(resolved_dep.path, function(err, stat) { | ||
if (cached_file.mtime === +stat.mtime) { | ||
@@ -243,7 +257,5 @@ if (root == null) { | ||
libs = null; | ||
compile = function(_options, cb) { | ||
var lib, _ref; | ||
options = _options; | ||
compile = function(options, cb) { | ||
var dep, lib, _ref; | ||
watching = options.watch; | ||
libs = (_ref = options.libs) != null ? _ref : []; | ||
@@ -261,3 +273,11 @@ libs = (function() { | ||
root = null; | ||
return collectDependencies(process.cwd(), options.mainfile, function(collect_err) { | ||
dep = { | ||
depend: options.mainfile, | ||
options: { | ||
bare: options.bare | ||
}, | ||
cwd: process.cwd(), | ||
seen: [] | ||
}; | ||
return collectDependencies(dep, function(collect_err) { | ||
if (collect_err && !(root != null)) { | ||
@@ -268,4 +288,4 @@ cb(collect_err); | ||
return resolveDependencyChain(root, function(err, dependency_chain) { | ||
var dep, output; | ||
if (_options.watch) { | ||
var output; | ||
if (watching) { | ||
watchFiles((function() { | ||
@@ -305,3 +325,3 @@ var _i, _len, _results; | ||
'.coffee': { | ||
compile: function(code) { | ||
compile: function(code, options) { | ||
return require('coffee-script').compile(code, { | ||
@@ -311,6 +331,6 @@ bare: options.bare | ||
}, | ||
import_re: /^#import (".+")$/gm | ||
depend_re: /^#depend "(.+)"( bare)?$/gm | ||
}, | ||
'.js': { | ||
compile: function(code) { | ||
compile: function(code, options) { | ||
if (options.bare) { | ||
@@ -322,6 +342,6 @@ return code; | ||
}, | ||
import_re: /^\/\/import (".+");?$/gm | ||
depend_re: /^\/\/depend "(.+)"( bare)?;?$/gm | ||
}, | ||
'.co': { | ||
compile: function(code) { | ||
compile: function(code, options) { | ||
return require('coco').compile(code, { | ||
@@ -331,6 +351,6 @@ bare: options.bare | ||
}, | ||
import_re: /^#import (".+")$/gm | ||
depend_re: /^#depend "(.+)"( bare)?$/gm | ||
}, | ||
'.ls': { | ||
compile: function(code) { | ||
compile: function(code, options) { | ||
return require('LiveScript').compile(code, { | ||
@@ -340,3 +360,3 @@ bare: options.bare | ||
}, | ||
import_re: /^#import (".+")$/gm | ||
depend_re: /^#depend "(.+)"( bare)?$/gm | ||
} | ||
@@ -343,0 +363,0 @@ }; |
{ | ||
"name": "jspackage", | ||
"description": "build tool which adds client-side import syntax", | ||
"version": "0.3.1", | ||
"version": "0.4.0", | ||
"author": { | ||
@@ -6,0 +6,0 @@ "name": "Andrew Kelley", |
@@ -1,18 +0,20 @@ | ||
Build tool to bundle client side code with an import syntax | ||
=========================================================== | ||
Bundle client side code with inline dependency declaration syntax | ||
================================================================= | ||
Ever wanted to have an `#import` statement in your favorite language which | ||
compiles into JavaScript that works like `#include` in other languages? | ||
Well now you have one! Importing files and concatenating them in the right | ||
place is now as easy as: | ||
## Synopsis | ||
#import "some_js_file" | ||
#import "another_one" | ||
#import "even_coco_is_supported" | ||
#import "and_livescript" | ||
# in your source code, declare the files you depend on: | ||
# some code using the imported files here... | ||
#depend "some_js_file" | ||
#depend "or_some_coffee_file" | ||
#depend "even_coco_is_supported" | ||
#depend "some/path/and_livescript" | ||
# leave off the top-level function wrapper | ||
#depend "vendor/Audiolet" bare | ||
In JavaScript, the `//import` directive is used instead of `#import`. | ||
# some code using the files here. | ||
In JavaScript, the `//depend` directive is used instead of `#depend`. | ||
Be sure to install the languages you wish to use with `npm install -g`. | ||
@@ -23,5 +25,5 @@ | ||
* File extensions are automatically resolved, and in fact are not allowed in | ||
import statements. This goes for the input_file too. | ||
depend statements. This goes for the input_file too. | ||
* Files will only be included once in the resulting code, regardless of how | ||
many times a file is imported. | ||
many times a file is depended upon. | ||
* Compiling CoffeeScript, JavaScript, Coco, and LiveScript source files are | ||
@@ -46,3 +48,2 @@ included out of the box. You can add more to the `compile.extensions` | ||
-h, --help shows this help section | ||
-b, --bare compile without a top-level function wrapper | ||
-w, --watch watch source files and recompile when any change | ||
@@ -86,4 +87,4 @@ -l, --lib PATH add an additional search directory for source files | ||
extensions['.lua'] = | ||
compile: (code) -> lua.compile(code) | ||
import_re: /^--import (".+")$/gm | ||
compile: (code, options) -> lua.compile(code, bare: options.bare) | ||
depend_re: /^--depend "(.+)"( bare)?$/gm | ||
``` | ||
@@ -90,0 +91,0 @@ |
@@ -1,3 +0,3 @@ | ||
//import "joy" | ||
//depend "joy" bare | ||
console.log("./path2/electric"); |
@@ -1,4 +0,3 @@ | ||
-b | ||
--lib tests/libfun/path1 | ||
--lib tests/libfun/path2 | ||
--lib tests/libfun/path3 |
@@ -1,3 +0,3 @@ | ||
//import "robin" | ||
//depend "robin" bare | ||
console.log("./thing"); |
@@ -1,4 +0,4 @@ | ||
//import "c" | ||
//depend "c" | ||
var A, C; | ||
A = B = C = "B"; |
@@ -1,3 +0,3 @@ | ||
//import "two" | ||
//import "three" | ||
//depend "two" bare | ||
//depend "three" bare | ||
@@ -4,0 +4,0 @@ var One; |
@@ -1,4 +0,4 @@ | ||
//import "one" | ||
//depend "one" bare | ||
console.log("main module") | ||
console.log("main module"); | ||
One(); |
@@ -1,2 +0,2 @@ | ||
//import "three" | ||
//depend "three" bare | ||
@@ -3,0 +3,0 @@ console.log("Two module"); |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
31753
521
102
40