UNPKG

3.21 kBtext/coffeescriptView Raw
1fs = require 'fs'
2path = require 'path'
3Stream = require 'stream'
4
5coffee = require 'coffee-script'
6coffee_helpers = require 'coffee-script/lib/coffee-script/helpers'
7convert = require 'convert-source-map'
8optparse = require 'optparse'
9
10conf =
11 quiet: false
12 progname: path.basename process.argv[1]
13
14 maps: true
15 output: process.stdout
16 stdin_literate: false
17 bare: false
18 header: true
19
20errx = (exit_code, msg) ->
21 console.error "#{conf.progname} error: #{msg}" unless conf.quiet
22 process.exit exit_code if exit_code
23
24user_agent = ->
25 ver = JSON.parse(fs.readFileSync "#{__dirname}/../package.json").version
26 ver_cs = require('coffee-script/lib/coffee-script/coffee-script').VERSION
27 "#{conf.progname}/#{ver} (CoffeeScript #{ver_cs}; #{process.platform}; #{process.arch}) node/#{process.versions.node}"
28
29parse_opts = (src) ->
30 opt = [
31 ["-h", "--help", "output usage information & exit"]
32 ["-V", "--version", "output the version number & exit"]
33 ["-o", "--output [FILE]", "write result to a FILE instead of stdout"]
34 ["-l", "--literate", "treat stdin as literate style coffee-script"]
35 ["-b", "--bare", "compile without a top-level function wrapper"]
36 ["--no-map", "don't include inline source map (why?)"]
37 ]
38 p = new optparse.OptionParser opt
39 p.banner = "Usage: #{conf.progname} [options] [file.coffee]"
40
41 p.on 'no-map', -> conf.maps = false
42
43 p.on 'bare', -> conf.bare = true
44
45 p.on 'help', ->
46 console.log p.toString()
47 process.exit 0
48
49 p.on 'version', ->
50 console.log user_agent()
51 process.exit 0
52
53 p.on 'output', (unused, val) -> conf.output = val
54
55 p.on 'literate', -> conf.stdin_literate = true
56
57 p.on (o) -> errx 1, "unknown option #{o}"
58
59 [(p.parse src), p]
60
61read_file = (fname) ->
62 try
63 fs.readFileSync(fname).toString()
64 catch e
65 errx 1, "#{fname} reading: #{e.message}"
66
67# TODO: fix this for Windows
68read_stdin = ->
69 read_file '/dev/stdin'
70
71# Crash or return a string.
72compile = (fname, fcontent, opt = {}) ->
73 return '' if fcontent.match /^\s*$/
74
75 options = {
76 sourceMap: conf.maps
77 generatedFile: fname
78 filename: fname
79 bare: conf.bare
80 header: conf.header
81 inline: true
82 literate: coffee_helpers.isLiterate(fname)
83 }
84 # override computed options from user provided opt object
85 options[key] = val for key,val of opt
86
87 try
88 compiled = coffee.compile fcontent, options
89 catch e
90 console.error coffee_helpers.updateSyntaxError e.toString(), fcontent, fname
91 process.exit 1
92
93 if conf.maps
94 comment = convert
95 .fromJSON(compiled.v3SourceMap)
96 .setProperty('sources', [fname])
97 .toComment()
98
99 "#{compiled.js}\n#{comment}"
100 else
101 compiled.toString()
102
103
104exports.main = ->
105 [args, p] = parse_opts process.argv
106 args = args[2..-1]
107
108 if args.length
109 js = compile args[0], read_file args[0]
110 else
111 js = compile '[stdin]', read_stdin(), { literate: conf.stdin_literate }
112
113 # create output stream only after a successful compilation
114 unless conf.output instanceof Stream
115 conf.output = fs.createWriteStream conf.output
116
117 conf.output.on 'error', (err) ->
118 errx 1, "output stream: #{err.message}"
119
120 conf.output.write js
121 conf.output.end() if conf.output.path