mirror of
https://github.com/jashkenas/coffeescript.git
synced 2022-11-09 12:23:24 -05:00
* Fix #2870: If --output ends with a filename, and the input is a file and not a path, save as the desired filename * If an output path ends in a slash, force saving into an output folder even if that folder name would contain a period (e.g. /scripts.js/); if output filename is only periods, treat it as a path * Restrict exceptions
This commit is contained in:
parent
892c4699dd
commit
3dd458267b
3 changed files with 100 additions and 82 deletions
|
@ -45,7 +45,7 @@
|
|||
BANNER = 'Usage: coffee [options] path/to/script.coffee [args]\n\nIf called without options, `coffee` will run your script.';
|
||||
|
||||
// The list of all the valid option flags that `coffee` knows how to handle.
|
||||
SWITCHES = [['-b', '--bare', 'compile without a top-level function wrapper'], ['-c', '--compile', 'compile to JavaScript and save as .js files'], ['-e', '--eval', 'pass a string from the command line as input'], ['-h', '--help', 'display this help message'], ['-i', '--interactive', 'run an interactive CoffeeScript REPL'], ['-j', '--join [FILE]', 'concatenate the source CoffeeScript before compiling'], ['-m', '--map', 'generate source map and save as .js.map files'], ['-M', '--inline-map', 'generate source map and include it directly in output'], ['-n', '--nodes', 'print out the parse tree that the parser produces'], ['--nodejs [ARGS]', 'pass options directly to the "node" binary'], ['--no-header', 'suppress the "Generated by" header'], ['-o', '--output [DIR]', 'set the output directory for compiled JavaScript'], ['-p', '--print', 'print out the compiled JavaScript'], ['-r', '--require [MODULE*]', 'require the given module before eval or REPL'], ['-s', '--stdio', 'listen for and compile scripts over stdio'], ['-l', '--literate', 'treat stdio as literate style coffeescript'], ['-t', '--tokens', 'print out the tokens that the lexer/rewriter produce'], ['-v', '--version', 'display the version number'], ['-w', '--watch', 'watch scripts for changes and rerun commands']];
|
||||
SWITCHES = [['-b', '--bare', 'compile without a top-level function wrapper'], ['-c', '--compile', 'compile to JavaScript and save as .js files'], ['-e', '--eval', 'pass a string from the command line as input'], ['-h', '--help', 'display this help message'], ['-i', '--interactive', 'run an interactive CoffeeScript REPL'], ['-j', '--join [FILE]', 'concatenate the source CoffeeScript before compiling'], ['-m', '--map', 'generate source map and save as .js.map files'], ['-M', '--inline-map', 'generate source map and include it directly in output'], ['-n', '--nodes', 'print out the parse tree that the parser produces'], ['--nodejs [ARGS]', 'pass options directly to the "node" binary'], ['--no-header', 'suppress the "Generated by" header'], ['-o', '--output [PATH]', 'set the output path or path/filename for compiled JavaScript'], ['-p', '--print', 'print out the compiled JavaScript'], ['-r', '--require [MODULE*]', 'require the given module before eval or REPL'], ['-s', '--stdio', 'listen for and compile scripts over stdio'], ['-l', '--literate', 'treat stdio as literate style coffeescript'], ['-t', '--tokens', 'print out the tokens that the lexer/rewriter produce'], ['-v', '--version', 'display the version number'], ['-w', '--watch', 'watch scripts for changes and rerun commands']];
|
||||
|
||||
// Top-level objects shared by all the functions.
|
||||
opts = {};
|
||||
|
@ -68,7 +68,7 @@
|
|||
// Many flags cause us to divert before compiling anything. Flags passed after
|
||||
// `--` will be passed verbatim to your script as arguments in `process.argv`
|
||||
exports.run = function() {
|
||||
var err, i, len, literals, ref, replCliOpts, results, source;
|
||||
var err, i, len, literals, outputBasename, ref, replCliOpts, results, source;
|
||||
optionParser = buildCSOptionParser();
|
||||
try {
|
||||
parseOptions();
|
||||
|
@ -117,7 +117,16 @@
|
|||
process.argv = process.argv.slice(0, 2).concat(literals);
|
||||
process.argv[0] = 'coffee';
|
||||
if (opts.output) {
|
||||
opts.output = path.resolve(opts.output);
|
||||
outputBasename = path.basename(opts.output);
|
||||
if (indexOf.call(outputBasename, '.') >= 0 && (outputBasename !== '.' && outputBasename !== '..') && !helpers.ends(opts.output, path.sep)) {
|
||||
// An output filename was specified, e.g. `/dist/scripts.js`.
|
||||
opts.outputFilename = outputBasename;
|
||||
opts.outputPath = path.resolve(path.dirname(opts.output));
|
||||
} else {
|
||||
// An output path was specified, e.g. `/dist`.
|
||||
opts.outputFilename = null;
|
||||
opts.outputPath = path.resolve(opts.output);
|
||||
}
|
||||
}
|
||||
if (opts.join) {
|
||||
opts.join = path.resolve(opts.join);
|
||||
|
@ -235,43 +244,43 @@
|
|||
};
|
||||
|
||||
// Compile a single source script, containing the given code, according to the
|
||||
// requested options. If evaluating the script directly sets `__filename`,
|
||||
// requested options. If evaluating the script directly, set `__filename`,
|
||||
// `__dirname` and `module.filename` to be correct relative to the script's path.
|
||||
compileScript = function(file, input, base = null) {
|
||||
var compiled, err, message, o, options, t, task;
|
||||
o = opts;
|
||||
var compiled, err, message, options, saveTo, task;
|
||||
options = compileOptions(file, base);
|
||||
try {
|
||||
t = task = {file, input, options};
|
||||
task = {file, input, options};
|
||||
CoffeeScript.emit('compile', task);
|
||||
if (o.tokens) {
|
||||
return printTokens(CoffeeScript.tokens(t.input, t.options));
|
||||
} else if (o.nodes) {
|
||||
return printLine(CoffeeScript.nodes(t.input, t.options).toString().trim());
|
||||
} else if (o.run) {
|
||||
if (opts.tokens) {
|
||||
return printTokens(CoffeeScript.tokens(task.input, task.options));
|
||||
} else if (opts.nodes) {
|
||||
return printLine(CoffeeScript.nodes(task.input, task.options).toString().trim());
|
||||
} else if (opts.run) {
|
||||
CoffeeScript.register();
|
||||
if (opts.prelude) {
|
||||
CoffeeScript.eval(opts.prelude, t.options);
|
||||
CoffeeScript.eval(opts.prelude, task.options);
|
||||
}
|
||||
return CoffeeScript.run(t.input, t.options);
|
||||
} else if (o.join && t.file !== o.join) {
|
||||
return CoffeeScript.run(task.input, task.options);
|
||||
} else if (opts.join && task.file !== opts.join) {
|
||||
if (helpers.isLiterate(file)) {
|
||||
t.input = helpers.invertLiterate(t.input);
|
||||
task.input = helpers.invertLiterate(task.input);
|
||||
}
|
||||
sourceCode[sources.indexOf(t.file)] = t.input;
|
||||
sourceCode[sources.indexOf(task.file)] = task.input;
|
||||
return compileJoin();
|
||||
} else {
|
||||
compiled = CoffeeScript.compile(t.input, t.options);
|
||||
t.output = compiled;
|
||||
if (o.map) {
|
||||
t.output = compiled.js;
|
||||
t.sourceMap = compiled.v3SourceMap;
|
||||
compiled = CoffeeScript.compile(task.input, task.options);
|
||||
task.output = compiled;
|
||||
if (opts.map) {
|
||||
task.output = compiled.js;
|
||||
task.sourceMap = compiled.v3SourceMap;
|
||||
}
|
||||
CoffeeScript.emit('success', task);
|
||||
if (o.print) {
|
||||
return printLine(t.output.trim());
|
||||
} else if (o.compile || o.map) {
|
||||
return writeJs(base, t.file, t.output, options.jsPath, t.sourceMap);
|
||||
if (opts.print) {
|
||||
return printLine(task.output.trim());
|
||||
} else if (opts.compile || opts.map) {
|
||||
saveTo = opts.outputFilename && sources.length === 1 ? path.join(opts.outputPath, opts.outputFilename) : options.jsPath;
|
||||
return writeJs(base, task.file, task.output, saveTo, task.sourceMap);
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
|
@ -281,7 +290,7 @@
|
|||
return;
|
||||
}
|
||||
message = (err != null ? err.stack : void 0) || `${err}`;
|
||||
if (o.watch) {
|
||||
if (opts.watch) {
|
||||
return printLine(message + '\x07');
|
||||
} else {
|
||||
printWarn(message);
|
||||
|
@ -486,13 +495,7 @@
|
|||
var basename, dir, srcDir;
|
||||
basename = helpers.baseFileName(source, true, useWinPathSep);
|
||||
srcDir = path.dirname(source);
|
||||
if (!opts.output) {
|
||||
dir = srcDir;
|
||||
} else if (source === base) {
|
||||
dir = opts.output;
|
||||
} else {
|
||||
dir = path.join(opts.output, path.relative(base, srcDir));
|
||||
}
|
||||
dir = !opts.outputPath ? srcDir : source === base ? opts.outputPath : path.join(opts.outputPath, path.relative(base, srcDir));
|
||||
return path.join(dir, basename + extension);
|
||||
};
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue