source: Dev/trunk/Gruntfile.js @ 529

Last change on this file since 529 was 522, checked in by hendrikvanantwerpen, 11 years ago
  • Add option to deploy source to Heroku (for debugging).
  • Rewrite xhr so requests are not serialized anymore.
  • Give more sane errors on request errors to Couch (like network errors and such).
File size: 11.3 KB
Line 
1/** Gruntfile - control build and deploy tasks
2 */
3
4var _ = require('underscore');
5
6module.exports = function(grunt) {
7
8    // TASKS
9
10    // default task
11    grunt.registerTask('default', ['compile']);
12    // development
13    grunt.registerTask('compile',
14                       "Lint all sources and compile Coffee and LESS sources.",
15                       ['path-check:svn'
16                       ,'svn-ignore:compile'
17                       ,'jshint:lint-sources'
18                       ,'htmlhint:lint'
19                       ,'coffeelint:lint'
20                       ,'jsonlint:lint'
21                     //,'tv4:lint'
22                       ,'less:compile'
23                       ,'usebanner:generated-css'
24                       ,'coffee:compile'
25                       ,'usebanner:generated-js'
26                       ,'jshint:lint-generated'
27                     //,'amd-check' // too smart about plugins, r.js can't find them
28                       ]);
29    grunt.registerTask('run',
30                       "Compile and start the server locally with foreman.",
31                       ['path-check:foreman'
32                       ,'compile'
33                       ,'foreman:run-src']);
34    grunt.registerTask('build',
35                       "Compile and make a Dojo build of the client (compress sources).",
36                       ['compile'
37                       ,'clean:build'
38                       ,'copy:build'
39                       ,'dojo:build'
40                       ]);
41    grunt.registerTask('run-build',
42                       "Make a build and start server from build locally with foreman.",
43                       ['path-check:foreman'
44                       ,'build'
45                       ,'foreman:run-build']);
46    grunt.registerTask('deploy',
47                       "Make a build and deploy it to Heroku.",
48                       ['path-check:svn'
49                       ,'path-check:git'
50                       ,'svninfo'
51                       ,'build'
52                       ,'git_deploy:deploy-build']);
53    grunt.registerTask('deploy-src',
54                       "Deploy sources to Heroku (FOR DEBUGGING ONLY).",
55                       ['path-check:svn'
56                       ,'path-check:git'
57                       ,'svninfo'
58                       ,'compile'
59                       ,'git_deploy:deploy-src']);
60    // database management
61    grunt.registerTask('db-backup-cloud-to-dated-local',
62                       "Backup the Heroku database to a timestamped local database.",
63                       ['path-check:heroku'
64                       ,'heroku-config'
65                       ,'http:db-backup-cloud-to-dated-local']);
66    grunt.registerTask('db-pull-cloud-to-local',
67                       "Synchronize local database with the Heroku database (pull changes).",
68                       ['path-check:heroku'
69                       ,'heroku-config'
70                       ,'http:db-pull-cloud-to-local']);
71    grunt.registerTask('db-push-local-to-cloud',
72                       "Synchronize the Heroku database with the local database (push changes).",
73                       ['path-check:heroku'
74                       ,'heroku-config'
75                       ,'http:db-push-local-to-cloud']);
76    grunt.registerTask('#',
77                       "---\nTASKS BELOW ARE INTERNAL AND SHOULD NOT USUALLY BE CALLED FROM THE COMMAND-LINE\n---",
78                       []);
79
80    // FILES AND FOLDERS
81   
82    var srcDir   = 'src/';
83    var buildDir = 'build/';
84    var coffeeMap = grunt.file.expandMapping(
85        [ 'client/qed-client/**/*.coffee', 'server/**/*.coffee' ],
86        srcDir,
87        { cwd: srcDir, ext: '.js' });
88    var lessMap = grunt.file.expandMapping(
89        [ 'client/qed-client/css/qed.less' ],
90        srcDir,
91        { cwd: srcDir, ext: '.css' });
92
93    var mode = process.env.QED_ENV || 'dev';
94    var dbNames = {
95        dev: 'qed-dev',
96        production: 'qed'
97    };
98    if ( !( mode in dbNames ) ) {
99        throw new Error("Unknown mode "+mode+" specified.");
100    }
101
102    // TASK CONFIG
103
104    grunt.initConfig({
105        localDbURL: "http://localhost:5984",
106        dbName: dbNames[mode],
107        timestamp: "<%= grunt.template.today(\"UTC:yyyymmdd't'HHMMss'z'\") %>",
108
109        'amd-check': {
110            files: [ srcDir+'client/qed-client/**/*.js' ]
111        },
112        clean: {
113            build: { src: [buildDir] }
114        },
115        coffee: {
116            options: { bare: true },
117            compile: { files: coffeeMap }
118        },
119        coffeelint: {
120            lint: { options: require('./'+srcDir+'.coffeelint.json'),
121                    files: coffeeMap }
122        },
123        copy: {
124            build: { files: [{ expand: true,
125                               cwd: srcDir,
126                               src: ['**', '!client/*/**' ],
127                               dest: buildDir }]}
128        },
129        dojo: {
130            build: { options: { dojo: srcDir+'client/dojo/dojo.js',
131                                profile: srcDir+'client/client.profile.js',
132                                releaseDir: '../../'+buildDir }}
133        },
134        foreman: {
135            'run-src': {
136                options: {
137                    cwd: srcDir
138                }
139            },
140            'run-build': {
141                options: {
142                    cwd: buildDir
143                }
144            }
145        },
146        git_deploy: {
147            'deploy-build': {
148                options: {
149                    url: 'git@heroku.com:quod-erat.git',
150                    branch: 'master',
151                    message: "Build deployment of revision <%= svninfo.rev %> on <%= grunt.template.today() %>."
152                },
153                src: buildDir
154            },
155           
156            'deploy-src': {
157                options: {
158                    url: 'git@heroku.com:quod-erat.git',
159                    branch: 'master',
160                    message: "Source deployment of revision <%= svninfo.rev %> on <%= grunt.template.today() %>."
161                },
162                src: srcDir
163            }
164        },
165        'heroku-config': {
166            options: {
167                app: 'quod-erat',
168                keys: ['CLOUDANT_URL']
169            }
170        },
171        htmlhint: {
172            options: { htmlhintrc: srcDir+".htmlhintrc" },
173            lint: { files: [{ expand: true,
174                              cwd: srcDir,
175                              src: ['client/*.html', 'client/qed-client/**/*.html'] }]}
176        },
177        http: {
178            'db-backup-cloud-to-dated-local': {
179                options: {
180                    url: "<%= localDbURL %>/_replicate",
181                    method: 'POST',
182                    body: {
183                        source: "<%= herokuConfig.CLOUDANT_URL %>/<%= dbName %>",
184                        target: "<%= dbName %>-<%= timestamp %>",
185                        create_target: true
186                    },
187                    json: true
188                }
189            },
190            'db-pull-cloud-to-local': {
191                options: {
192                    url: "<%= localDbURL %>/_replicate",
193                    method: 'POST',
194                    body: {
195                        source: "<%= herokuConfig.CLOUDANT_URL %>/<%= dbName %>",
196                        target: "<%= dbName %>",
197                        create_target: true
198                    },
199                    json: true
200                }
201            },
202            'db-push-local-to-cloud': {
203                options: {
204                    url: "<%= localDbURL %>/_replicate",
205                    method: 'POST',
206                    body: {
207                        source: "<%= dbName %>",
208                        target: "<%= herokuConfig.CLOUDANT_URL %>/<%= dbName %>",
209                        create_target: true
210                    },
211                    json: true
212                }
213            }
214        },
215        jshint: {
216            'lint-sources': { options: { jshintrc: srcDir+".jshintrc" },
217                              files: { src: [ srcDir+'client/qed-client/**/*.js', srcDir+'server/**/*.js' ].concat(exclude(dest(coffeeMap))) } },
218            'lint-generated': { options: { jshintrc: srcDir+".jshintrc-generated" },
219                                files: { src: dest(coffeeMap) } }
220        },
221        jsonlint: {
222            'lint': { files: { src: [ srcDir+'client/qed-client/**/*.json', srcDir+'server/**/*.json' ] } }
223        },
224        less: {
225            options: { strictImports: false,
226                       dumpLineNumbers: "all" },
227            compile: { files: lessMap }
228        },
229        'path-check': {
230            'heroku': {
231                src: ['heroku']
232            },
233            'foreman': {
234                src: ['foreman']
235            },
236            'svn': {
237                src: ['svn']
238            },
239            'git': {
240                src: ['git']
241            }
242        },
243        requirejs: {
244            basePath: srcDir+'client/',
245            packages: [
246                { name: "dojo", location: "dojo" },
247                { name: "dijit", location: "dijit" },
248                { name: "dojox", location: "dojox" },
249                { name: "qed-client", location: "qed-client" }
250            ]
251        },
252        'svn-ignore': {
253            compile: {
254                files: { src: dest(coffeeMap).concat(dest(lessMap)) }
255            }
256        },
257        'svn-ignore-clean': {
258            clean: {
259                files: [{
260                    expand: true,
261                    cwd: srcDir,
262                    src: ['**', '!node_modules/**', '!client/dojo/**', '!client/dijit/**', '!client/dojox/**', '!client/util/**'],
263                    filter: 'isDirectory'
264                }]
265            }
266        },
267        tv4: {
268            lint: {
269                options: {
270                    root: grunt.file.readJSON('json-schema-draft-04.json'),
271                    multi: true
272                },
273                src: [srcDir+'server/config/couchdb-schema.json']
274            }
275        },
276        usebanner: {
277            'generated-css': { options: { position: 'top',
278                                          banner: '/* This CSS file is generated. All edits will be lost on recompile. */'},
279                               files: { src: dest(lessMap) }},
280            'generated-js': { options: { position: 'top',
281                                         banner: '/* This JS file is generated, All edits will be lost on recompile. */'},
282                               files: { src: dest(coffeeMap) }}
283        }
284    });
285
286    // LOAD TASKS
287
288    grunt.loadNpmTasks('grunt-amd-check');
289    grunt.loadNpmTasks('grunt-banner');
290    grunt.loadNpmTasks('grunt-coffeelint');
291    grunt.loadNpmTasks('grunt-contrib-clean');
292    grunt.loadNpmTasks('grunt-contrib-coffee');
293    grunt.loadNpmTasks('grunt-contrib-copy');
294    grunt.loadNpmTasks('grunt-contrib-jshint');
295    grunt.loadNpmTasks('grunt-contrib-less');
296    grunt.loadNpmTasks('grunt-dojo');
297    grunt.loadNpmTasks('grunt-git-deploy');
298    grunt.loadNpmTasks('grunt-htmlhint');
299    grunt.loadNpmTasks('grunt-http');
300    grunt.loadNpmTasks('grunt-jsonlint');
301    grunt.loadNpmTasks('grunt-path-check');
302    grunt.loadNpmTasks('grunt-svninfo');
303    grunt.loadNpmTasks('grunt-tv4');
304    grunt.loadTasks('./grunt-tasks');
305
306    // UTIL FUNCTIONS
307
308    function dest(files) {
309        return _.chain(files)
310            .map(function(item){ return item.dest; })
311            .flatten()
312            .value();
313    }
314
315    function exclude(dest) {
316        return _.map(dest, function(dest){ return '!'+dest; });
317    }
318   
319};
Note: See TracBrowser for help on using the repository browser.