summaryrefslogtreecommitdiffstats
path: root/coffee/Cakefile
blob: 878a4f821c0585d5659057df5c96cb8b8c4d9eec (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
###
# ownCloud
#
# @author Bernhard Posselt
# Copyright (c) 2012 - Bernhard Posselt <nukeawhale@gmail.com>
#
# This file is licensed under the Affero General Public License version 3 or later.
# See the COPYING-README file
#
###

# imports
fs = require 'fs'
util = require 'util'
{exec} = require 'child_process'


### Configuration ###

# path that contains your coffee files
sourceDirectory = __dirname

# path and name of the compiled js file relative to this script without .js suffix
compileToFile = '../js/app'

# These files will be compiled in order before any other files
compileFirst = [
	'app.coffee'
]


### Functions ###

# Recursively searches for coffee files
# @param string path: the path to search for coffee files
# @param array coffeeFiles: a hashmap with existing files that will be ignored
getCoffeeFiles = (path, coffeeFiles) ->
	entries = fs.readdirSync(path)

	for entry in entries
		do (entry) ->
			entryPath = path + '/' + entry
			entryStats = fs.statSync(entryPath)

			if entryStats.isFile()
				if entryPath.indexOf('.coffee') > 1 and coffeeFiles[entryPath] == undefined
					coffeeFiles[entryPath] = true

			else if entryStats.isDirectory()
				getCoffeeFiles(entryPath, coffeeFiles)


# returns an array with all coffeefiles in order
getOrderedCoffeeFiles = (directory) ->
	unorderedFiles = {}
	getCoffeeFiles(directory, unorderedFiles)

	# create data structures for quick prioritized files lookup
	orderedFilesHashMap = {}
	for file in compileFirst
		filePath = directory + '/' + file
		orderedFilesHashMap[filePath] = true

	# prepend prioritized files
	orderedFiles = []
	for file in compileFirst
		orderedFiles.push(directory + '/' + file)

	# order files
	for file, exists of unorderedFiles
		if orderedFilesHashMap[file] == undefined
			orderedFiles.push(file)

	util.log "#{orderedFiles.length} coffee files found."
	return orderedFiles


# compiles an array with file content to a js file
compile = (content, toFile) ->
	toFile += '.coffee'

	fs.writeFile toFile, content.join('\n\n'), 'utf8', (error) ->
		if error
			throw error

		exec 'coffee --compile ' + toFile, (error, stdout, stderr) ->
			if error
				util.log 'Error compiling coffee file.'
				util.error error
			else
				fs.unlink toFile, (error) ->
					if error
						util.log 'Couldn\'t delete the compile cache file ' + toFile
					util.log 'Finished building coffee file.'


# register a callback on an array of files and remove already bound ones
watchFiles = (files, callback) ->
	files = {}
	getCoffeeFiles(sourceDirectory, files)
	for file, exists of files
		fs.unwatchFile(file)
		fs.watchFile(file, callback)


### Tasks ###

task 'watch', 'Watch and rebuild on changes', ->
	invoke 'build'
	util.log "Watching for changes"

	watchFiles getOrderedCoffeeFiles(sourceDirectory), ->
		invoke 'build'

	fs.watchFile sourceDirectory, (current, previous) ->
		watchFiles getOrderedCoffeeFiles(sourceDirectory), ->
			invoke 'build'


task 'build', 'Build and compress CoffeeScript into single JavaScript file', ->
	files = getOrderedCoffeeFiles(sourceDirectory)
	content = []
	remaining = files.length

	# read out content of files and compile them afterwards
	for file, index in files then do (file, index) ->
		fs.readFile file, 'utf8', (error, fileContent) ->
			if error
				throw error

			content[index] = fileContent
			remaining -= 1

			if remaining <= 0
				compile(content, compileToFile)