forked from oakmac/cljs-cheatsheet
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathGruntfile.js
217 lines (170 loc) · 6.35 KB
/
Gruntfile.js
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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
const md5 = require('md5')
const kidif = require('kidif')
const marked = require('marked')
const hashLength = 15
module.exports = function (grunt) {
'use strict'
// ---------------------------------------------------------------------------
// Build docs.HASHME.json from kidif files
function splitSection (str) {
const lines = str.split('\n')
const lines2 = []
for (var i = 0; i < lines.length; i++) {
var line = lines[i].trim()
if (line !== '') {
lines2.push(line)
}
}
return lines2
}
function docsToObj (docsArr) {
var docs = {}
for (var i = 0; i < docsArr.length; i++) {
var symbol = docsArr[i]
docs[symbol.name] = {}
docs[symbol.name]['full-name'] = symbol.name
docs[symbol.name]['signature'] = splitSection(symbol.signature)
docs[symbol.name]['description-html'] = marked(symbol.description)
if (symbol.related) {
docs[symbol.name]['related'] = splitSection(symbol.related)
}
if (symbol.type) {
docs[symbol.name]['type'] = symbol.type
}
}
return docs
}
function buildDocs () {
const allDocsArr = kidif('docfiles/*.cljsdoc')
const allDocsObj = docsToObj(allDocsArr)
const symbolsWeNeed = require('./symbols.json')
// build only the symbols we need for the cheatsheet
var docsWeNeed = {}
for (var i = 0; i < symbolsWeNeed.length; i++) {
const cljsName = symbolsWeNeed[i].replace('clojure.core', 'cljs.core')
const clojureName = symbolsWeNeed[i].replace('cljs.core', 'clojure.core')
let fullName = null
if (allDocsObj[cljsName]) fullName = cljsName
if (allDocsObj[clojureName]) fullName = clojureName
// sanity check: make sure we have the docfile for everything in symbols.json
if (!fullName) {
grunt.fail.warn('Missing docfile for ' + symbolsWeNeed[i])
}
docsWeNeed[fullName] = allDocsObj[fullName]
}
grunt.file.write('public/docs.HASHME.json', JSON.stringify(docsWeNeed))
grunt.log.writeln(symbolsWeNeed.length + ' doc symbols written to public/docs.HASHME.json')
}
// ---------------------------------------------------------------------------
// Cheatsheet Publish
// ---------------------------------------------------------------------------
function preBuildSanityCheck () {
if (!grunt.file.exists('public/index.html')) {
grunt.fail.warn('Could not find public/index.html. Please run "node app.js" to generate it. Aborting build...')
}
if (!grunt.file.exists('public/js/cheatsheet.min.js')) {
grunt.fail.warn('Could not find public/js/cheatsheet.min.js. Please run "lein cljsbuild once cheatsheet-prod" to generate it. Aborting build...')
}
// TODO: check to make sure the ctime on cheatsheet.min.js is pretty fresh
// (< 5 minutes)
grunt.log.writeln('Everything looks ok for a build.')
}
// FIXME: re-write this to be more generic please :)
function hashAssets () {
const unhashedDocsFilename = '00_build/docs.HASHME.json'
const docsFileContents = grunt.file.read(unhashedDocsFilename)
const docsHash = md5(docsFileContents).substr(0, hashLength)
// update cheatsheet.min.js with docs hash
const buildJsFilename = '00_build/js/cheatsheet.min.js'
const jsFileContents1 = grunt.file.read(buildJsFilename)
const jsFileContents2 = jsFileContents1.replace('docs.HASHME.json', 'docs.' + docsHash + '.json')
grunt.file.write(buildJsFilename, jsFileContents2)
// hash css file
const cssFileContents = grunt.file.read('00_build/css/main.min.css')
const cssHash = md5(cssFileContents).substr(0, hashLength)
// hash JS file
const jsHash = md5(jsFileContents2).substr(0, hashLength)
const htmlFile = grunt.file.read('00_build/index.html')
// write the new files
grunt.file.write('00_build/css/main.min.' + cssHash + '.css', cssFileContents)
grunt.file.write('00_build/docs.' + docsHash + '.json', docsFileContents)
grunt.file.write('00_build/js/cheatsheet.min.' + jsHash + '.js', jsFileContents2)
// delete the old files
grunt.file.delete('00_build/css/main.min.css')
grunt.file.delete('00_build/docs.HASHME.json')
grunt.file.delete('00_build/js/cheatsheet.min.js')
// update the HTML file
grunt.file.write('00_build/index.html',
htmlFile.replace('main.min.css', 'main.min.' + cssHash + '.css')
.replace('cheatsheet.min.js', 'cheatsheet.min.' + jsHash + '.js'))
// show some output
grunt.log.writeln('00_build/css/main.min.css → ' +
'00_build/css/main.min.' + cssHash + '.css')
grunt.log.writeln('00_build/docs.HASHME.json → ' +
'00_build/docs.' + docsHash + '.json')
grunt.log.writeln('00_build/js/cheatsheet.min.js → ' +
'00_build/js/cheatsheet.min.' + jsHash + '.js')
}
// ---------------------------------------------------------------------------
// Grunt Config
// ---------------------------------------------------------------------------
grunt.initConfig({
clean: {
options: {
force: true
},
// remove all the files in the 00_build folder
pre: ['00_build'],
// remove the uncompressed CLJS client file
post: ['00_build/js/cheatsheet.js']
},
copy: {
cheatsheet: {
files: [
{ expand: true, cwd: 'public/', src: ['**'], dest: '00_build/' }
]
}
},
less: {
options: {
compress: true
},
watch: {
files: {
'public/css/main.min.css': 'less/000-main.less'
}
}
},
watch: {
options: {
atBegin: true
},
less: {
files: 'less/*.less',
tasks: 'less:watch'
},
docs: {
files: 'docfiles/*.cljsdoc',
tasks: 'docs'
}
}
})
// load tasks from npm
grunt.loadNpmTasks('grunt-contrib-clean')
grunt.loadNpmTasks('grunt-contrib-copy')
grunt.loadNpmTasks('grunt-contrib-less')
grunt.loadNpmTasks('grunt-contrib-watch')
// custom tasks
grunt.registerTask('docs', buildDocs)
grunt.registerTask('pre-build-sanity-check', preBuildSanityCheck)
grunt.registerTask('hash-assets', hashAssets)
grunt.registerTask('build', [
'pre-build-sanity-check',
'clean:pre',
'copy:cheatsheet',
'clean:post',
'hash-assets'
])
grunt.registerTask('default', 'watch')
// end module.exports
}