1 | # Cakefile
|
2 | # batman
|
3 | # Copyright Shopify, 2011
|
4 |
|
5 | muffin = require 'muffin'
|
6 | fs = require 'fs'
|
7 | q = require 'q'
|
8 | glob = require 'glob'
|
9 | path = require 'path'
|
10 |
|
11 |
|
12 | option '-w', '--watch', 'continue to watch the files and rebuild them when they change'
|
13 | option '-c', '--commit', 'operate on the git index instead of the working tree'
|
14 | option '-d', '--dist', 'compile minified versions of the platform dependent code into lib/dist (build task only)'
|
15 | option '-m', '--compare', 'compare to git refs (stat task only)'
|
16 | option '-s', '--coverage', 'run jscoverage during tests and report coverage (test task only)'
|
17 |
|
18 | task 'build', 'compile Batman.js and all the tools', (options) ->
|
19 | muffin.run
|
20 | files: './src/**/*'
|
21 | options: options
|
22 | map:
|
23 | 'src/batman\.coffee' : (matches) -> muffin.compileScript(matches[0], 'lib/batman.js', options)
|
24 | 'src/batman\.(.+)\.coffee' : (matches) -> muffin.compileScript(matches[0], "lib/batman.#{matches[1]}.js", options)
|
25 | 'src/tools/batman\.coffee' : (matches) -> muffin.compileScript(matches[0], "tools/batman", muffin.extend({bare: true}, options, {mode: 755}))
|
26 | 'src/tools/(.+)\.coffee' : (matches) -> muffin.compileScript(matches[0], "tools/#{matches[1]}.js", options)
|
27 |
|
28 | if options.dist
|
29 | temp = require 'temp'
|
30 | tmpdir = temp.mkdirSync()
|
31 | distDir = "lib/dist"
|
32 |
|
33 | # Compile the scripts to the distribution folder by:
|
34 | # 1. Finding each platform specific batman file of the form `batman.platform.coffee`
|
35 | # 2. Concatenating each platform specific file with the main Batman source, and storing that in a temp file.
|
36 | # 3. Compiling each complete platform specific batman distribution into JavaScript in `./lib/dist`
|
37 | # 4. Minify each complete platform specific distribution in to a .min.js file in `./lib/dist`
|
38 | compileDist = (platformName) ->
|
39 | return if platformName == 'node'
|
40 | joinedCoffeePath = "#{tmpdir}/batman.#{platformName}.coffee"
|
41 |
|
42 | # Read the platform specific code
|
43 | platform = muffin.readFile "src/batman.#{platformName}.coffee", options
|
44 | standard = muffin.readFile 'src/batman.coffee', options
|
45 | q.join platform, standard, (platformSource, standardSource) ->
|
46 | # Write the joined coffeescript to a temp dir
|
47 | write = muffin.writeFile(joinedCoffeePath, standardSource + "\n" + platformSource, options)
|
48 | q.when write, (result) ->
|
49 | # Compile the temp coffeescript to the build dir
|
50 | fs.mkdirSync(distDir, 0777) unless path.existsSync(distDir)
|
51 | destination = "#{distDir}/batman#{if platformName is 'solo' then '' else '.' + platformName}.js"
|
52 | compile = muffin.compileScript(joinedCoffeePath, destination, options)
|
53 | compile.then( ->
|
54 | muffin.minifyScript destination, options
|
55 | ).then( ->
|
56 | muffin.notify(destination, "File #{destination} minified and gzipped.")
|
57 | )
|
58 |
|
59 | # Run a task which concats the coffeescript, compiles it, and then minifies it
|
60 | first = true
|
61 | muffin.run
|
62 | files: './src/**/*'
|
63 | options: options
|
64 | map:
|
65 | 'src/batman\.(.+)\.coffee': (matches) -> compileDist(matches[1])
|
66 | 'src/batman.coffee' : (matches) ->
|
67 | if first
|
68 | first = false
|
69 | return
|
70 | # When the the root batman file changes, compile all the platform files.
|
71 | platformFiles = glob.globSync('./src/batman.*.coffee')
|
72 | for file in platformFiles
|
73 | matches = /src\/batman.(.+).coffee/.exec(file)
|
74 | compileDist(matches[1])
|
75 |
|
76 | task 'doc', 'build the Docco documentation', (options) ->
|
77 | muffin.run
|
78 | files: './src/**/*'
|
79 | options: options
|
80 | map:
|
81 | 'src/batman.coffee': (matches) -> muffin.doccoFile(matches[0], options)
|
82 |
|
83 | task 'test', 'compile Batman.js and the tests and run them on the command line', (options) ->
|
84 | temp = require 'temp'
|
85 | runner = require 'qunit'
|
86 | runner.options.coverage = false
|
87 | tmpdir = temp.mkdirSync()
|
88 | first = false
|
89 |
|
90 | muffin.run
|
91 | files: glob.globSync('./src/**/*.coffee').concat(glob.globSync('./tests/**/*.coffee'))
|
92 | options: options
|
93 | map:
|
94 | 'src/batman.coffee' : (matches) -> muffin.compileScript(matches[0], "#{tmpdir}/batman.js", muffin.extend {notify: first}, options)
|
95 | 'src/batman.solo.coffee' : (matches) -> muffin.compileScript(matches[0], "#{tmpdir}/batman.solo.js", muffin.extend {notify: first}, options)
|
96 | 'tests/batman/(.+)_test.coffee' : (matches) -> muffin.compileScript(matches[0], "#{tmpdir}/#{matches[1]}_test.js", muffin.extend {notify: first}, options)
|
97 | 'tests/batman/test_helper.coffee' : (matches) -> muffin.compileScript(matches[0], "#{tmpdir}/test_helper.js", muffin.extend {notify: first}, options)
|
98 | after: ->
|
99 | first = true
|
100 | runner.run
|
101 | code: {namespace: "Batman", path: "#{tmpdir}/batman.js"}
|
102 | deps: ["jsdom", "#{tmpdir}/test_helper.js", "./tests/lib/jquery.js"]
|
103 | tests: glob.globSync("#{tmpdir}/*_test.js")
|
104 | coverage: options.coverage || false
|
105 | , (report) ->
|
106 | unless options.watch
|
107 | exit = -> process.exit report.errors
|
108 | unless process.stdout.flush()
|
109 | process.stdout.once 'drain', exit
|
110 | else
|
111 | exit
|
112 |
|
113 | task 'stats', 'compile the files and report on their final size', (options) ->
|
114 | muffin.statFiles(glob.globSync('./src/**/*.coffee').concat(glob.globSync('./lib/**/*.js')), options)
|