source: Dev/trunk/Gruntfile.js @ 531

Last change on this file since 531 was 531, checked in by hendrikvanantwerpen, 11 years ago
  • Return to using truly ISO formatted dates, including milliseconds.
  • Also set constraint on surveyrun dates when value is initially set.
  • Separate runs & results from surveys and questions.
  • Moved date & email format to schema itself.
File size: 11.8 KB
RevLine 
[464]1/** Gruntfile - control build and deploy tasks
[453]2 */
[443]3
[469]4var _ = require('underscore');
5
[443]6module.exports = function(grunt) {
7
[469]8    // TASKS
9
[517]10    // default task
[469]11    grunt.registerTask('default', ['compile']);
[517]12    // development
[518]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'
[522]33                       ,'foreman:run-src']);
[518]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'
[522]45                       ,'foreman:run-build']);
[518]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'
[522]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']);
[517]60    // database management
61    grunt.registerTask('db-backup-cloud-to-dated-local',
[518]62                       "Backup the Heroku database to a timestamped local database.",
[517]63                       ['path-check:heroku'
64                       ,'heroku-config'
65                       ,'http:db-backup-cloud-to-dated-local']);
66    grunt.registerTask('db-pull-cloud-to-local',
[518]67                       "Synchronize local database with the Heroku database (pull changes).",
[517]68                       ['path-check:heroku'
69                       ,'heroku-config'
70                       ,'http:db-pull-cloud-to-local']);
71    grunt.registerTask('db-push-local-to-cloud',
[518]72                       "Synchronize the Heroku database with the local database (push changes).",
[517]73                       ['path-check:heroku'
74                       ,'heroku-config'
75                       ,'http:db-push-local-to-cloud']);
[531]76    grunt.registerTask('cloudant-url',
77                       "Print the Cloudant URL to the console.",
78                       ['path-check:heroku'
79                       ,'heroku-config'
80                       ,'print:herokuConfig.CLOUDANT_URL:CLOUDANT_URL'
81                       ]);
[518]82    grunt.registerTask('#',
83                       "---\nTASKS BELOW ARE INTERNAL AND SHOULD NOT USUALLY BE CALLED FROM THE COMMAND-LINE\n---",
84                       []);
[469]85
86    // FILES AND FOLDERS
87   
[464]88    var srcDir   = 'src/';
[463]89    var buildDir = 'build/';
[469]90    var coffeeMap = grunt.file.expandMapping(
91        [ 'client/qed-client/**/*.coffee', 'server/**/*.coffee' ],
92        srcDir,
93        { cwd: srcDir, ext: '.js' });
94    var lessMap = grunt.file.expandMapping(
95        [ 'client/qed-client/css/qed.less' ],
96        srcDir,
97        { cwd: srcDir, ext: '.css' });
[453]98
[519]99    var mode = process.env.QED_ENV || 'dev';
100    var dbNames = {
101        dev: 'qed-dev',
102        production: 'qed'
103    };
104    if ( !( mode in dbNames ) ) {
105        throw new Error("Unknown mode "+mode+" specified.");
106    }
107
[469]108    // TASK CONFIG
[517]109
[443]110    grunt.initConfig({
[517]111        localDbURL: "http://localhost:5984",
[519]112        dbName: dbNames[mode],
[517]113        timestamp: "<%= grunt.template.today(\"UTC:yyyymmdd't'HHMMss'z'\") %>",
114
[469]115        'amd-check': {
116            files: [ srcDir+'client/qed-client/**/*.js' ]
117        },
[458]118        clean: {
[469]119            build: { src: [buildDir] }
[458]120        },
[463]121        coffee: {
[469]122            options: { bare: true },
123            compile: { files: coffeeMap }
[453]124        },
[466]125        coffeelint: {
[469]126            lint: { options: require('./'+srcDir+'.coffeelint.json'),
127                    files: coffeeMap }
[466]128        },
[463]129        copy: {
[469]130            build: { files: [{ expand: true,
131                               cwd: srcDir,
132                               src: ['**', '!client/*/**' ],
133                               dest: buildDir }]}
[458]134        },
[453]135        dojo: {
[469]136            build: { options: { dojo: srcDir+'client/dojo/dojo.js',
137                                profile: srcDir+'client/client.profile.js',
[471]138                                releaseDir: '../../'+buildDir }}
[453]139        },
[517]140        foreman: {
[522]141            'run-src': {
[517]142                options: {
143                    cwd: srcDir
144                }
145            },
[522]146            'run-build': {
[517]147                options: {
148                    cwd: buildDir
149                }
150            }
151        },
[516]152        git_deploy: {
[522]153            'deploy-build': {
[516]154                options: {
155                    url: 'git@heroku.com:quod-erat.git',
156                    branch: 'master',
[522]157                    message: "Build deployment of revision <%= svninfo.rev %> on <%= grunt.template.today() %>."
[516]158                },
159                src: buildDir
[522]160            },
161           
162            'deploy-src': {
163                options: {
164                    url: 'git@heroku.com:quod-erat.git',
165                    branch: 'master',
166                    message: "Source deployment of revision <%= svninfo.rev %> on <%= grunt.template.today() %>."
167                },
168                src: srcDir
[516]169            }
170        },
[517]171        'heroku-config': {
172            options: {
173                app: 'quod-erat',
174                keys: ['CLOUDANT_URL']
175            }
176        },
[453]177        htmlhint: {
[469]178            options: { htmlhintrc: srcDir+".htmlhintrc" },
179            lint: { files: [{ expand: true,
180                              cwd: srcDir,
181                              src: ['client/*.html', 'client/qed-client/**/*.html'] }]}
[443]182        },
[517]183        http: {
184            'db-backup-cloud-to-dated-local': {
185                options: {
186                    url: "<%= localDbURL %>/_replicate",
187                    method: 'POST',
188                    body: {
[519]189                        source: "<%= herokuConfig.CLOUDANT_URL %>/<%= dbName %>",
190                        target: "<%= dbName %>-<%= timestamp %>",
[517]191                        create_target: true
192                    },
193                    json: true
194                }
195            },
196            'db-pull-cloud-to-local': {
197                options: {
198                    url: "<%= localDbURL %>/_replicate",
199                    method: 'POST',
200                    body: {
[519]201                        source: "<%= herokuConfig.CLOUDANT_URL %>/<%= dbName %>",
[520]202                        target: "<%= dbName %>",
203                        create_target: true
[517]204                    },
205                    json: true
206                }
207            },
208            'db-push-local-to-cloud': {
209                options: {
210                    url: "<%= localDbURL %>/_replicate",
211                    method: 'POST',
212                    body: {
[519]213                        source: "<%= dbName %>",
[520]214                        target: "<%= herokuConfig.CLOUDANT_URL %>/<%= dbName %>",
215                        create_target: true
[517]216                    },
217                    json: true
218                }
219            }
220        },
[443]221        jshint: {
[469]222            'lint-sources': { options: { jshintrc: srcDir+".jshintrc" },
[505]223                              files: { src: [ srcDir+'client/qed-client/**/*.js', srcDir+'server/**/*.js' ].concat(exclude(dest(coffeeMap))) } },
[469]224            'lint-generated': { options: { jshintrc: srcDir+".jshintrc-generated" },
[505]225                                files: { src: dest(coffeeMap) } }
[443]226        },
[505]227        jsonlint: {
[516]228            'lint': { files: { src: [ srcDir+'client/qed-client/**/*.json', srcDir+'server/**/*.json' ] } }
[505]229        },
[453]230        less: {
[469]231            options: { strictImports: false,
232                       dumpLineNumbers: "all" },
233            compile: { files: lessMap }
234        },
[516]235        'path-check': {
[517]236            'heroku': {
237                src: ['heroku']
238            },
239            'foreman': {
240                src: ['foreman']
241            },
242            'svn': {
243                src: ['svn']
244            },
245            'git': {
246                src: ['git']
[516]247            }
248        },
[469]249        requirejs: {
250            basePath: srcDir+'client/',
251            packages: [
252                { name: "dojo", location: "dojo" },
253                { name: "dijit", location: "dijit" },
254                { name: "dojox", location: "dojox" },
255                { name: "qed-client", location: "qed-client" }
256            ]
257        },
[474]258        'svn-ignore': {
259            compile: {
260                files: { src: dest(coffeeMap).concat(dest(lessMap)) }
261            }
262        },
263        'svn-ignore-clean': {
264            clean: {
265                files: [{
266                    expand: true,
267                    cwd: srcDir,
268                    src: ['**', '!node_modules/**', '!client/dojo/**', '!client/dijit/**', '!client/dojox/**', '!client/util/**'],
269                    filter: 'isDirectory'
270                }]
271            }
272        },
[487]273        tv4: {
274            lint: {
275                options: {
276                    root: grunt.file.readJSON('json-schema-draft-04.json'),
277                    multi: true
278                },
279                src: [srcDir+'server/config/couchdb-schema.json']
280            }
281        },
[469]282        usebanner: {
283            'generated-css': { options: { position: 'top',
284                                          banner: '/* This CSS file is generated. All edits will be lost on recompile. */'},
285                               files: { src: dest(lessMap) }},
286            'generated-js': { options: { position: 'top',
287                                         banner: '/* This JS file is generated, All edits will be lost on recompile. */'},
288                               files: { src: dest(coffeeMap) }}
[443]289        }
290    });
291
[469]292    // LOAD TASKS
293
294    grunt.loadNpmTasks('grunt-amd-check');
295    grunt.loadNpmTasks('grunt-banner');
[466]296    grunt.loadNpmTasks('grunt-coffeelint');
[458]297    grunt.loadNpmTasks('grunt-contrib-clean');
[463]298    grunt.loadNpmTasks('grunt-contrib-coffee');
[453]299    grunt.loadNpmTasks('grunt-contrib-copy');
300    grunt.loadNpmTasks('grunt-contrib-jshint');
[443]301    grunt.loadNpmTasks('grunt-contrib-less');
[453]302    grunt.loadNpmTasks('grunt-dojo');
[516]303    grunt.loadNpmTasks('grunt-git-deploy');
[443]304    grunt.loadNpmTasks('grunt-htmlhint');
[517]305    grunt.loadNpmTasks('grunt-http');
[505]306    grunt.loadNpmTasks('grunt-jsonlint');
[516]307    grunt.loadNpmTasks('grunt-path-check');
308    grunt.loadNpmTasks('grunt-svninfo');
[487]309    grunt.loadNpmTasks('grunt-tv4');
[469]310    grunt.loadTasks('./grunt-tasks');
[443]311
[531]312    grunt.registerTask('print',"Print a variable.",
313                       function(varname,name) {
314                            grunt.log.write(grunt.template.process((name||varname)+"=<%= "+varname+" %>"));
315                       });
316
[469]317    // UTIL FUNCTIONS
[464]318
[469]319    function dest(files) {
320        return _.chain(files)
321            .map(function(item){ return item.dest; })
322            .flatten()
323            .value();
324    }
[464]325
[469]326    function exclude(dest) {
327        return _.map(dest, function(dest){ return '!'+dest; });
328    }
329   
[443]330};
Note: See TracBrowser for help on using the repository browser.