1 | module.exports = function (grunt) {
|
2 | var webpackConfig = require('./webpack.config.js');
|
3 | var webpackDevConfig = require('./webpack.dev.config.js');
|
4 | var webpackTestConfig = require('./webpack.test.config.js');
|
5 | var fs = require('fs');
|
6 | var path = require('path');
|
7 | var testDir = 'test';
|
8 | var testHost = 'http://localhost:8000/';
|
9 | var pkg = grunt.file.readJSON('package.json');
|
10 | var repo = 'github.com/koalyptus/TableFilter';
|
11 | var styleDirDist = 'dist/tablefilter/style/';
|
12 |
|
13 | grunt.initConfig({
|
14 |
|
15 | eslint: {
|
16 | options: {
|
17 | configFile: '.eslintrc'
|
18 | },
|
19 | target: [
|
20 | 'Gruntfile.js',
|
21 | 'webpack.config.js',
|
22 | 'webpack.dev.config.js',
|
23 | 'webpack.test.config.js',
|
24 | 'src/**/*.js',
|
25 | 'test/*.js'
|
26 | ]
|
27 | },
|
28 |
|
29 | qunit: {
|
30 | options: {
|
31 | '--web-security': 'no',
|
32 | coverage: {
|
33 | disposeCollector: true,
|
34 | src: ['dist/tablefilter/*.js'],
|
35 | instrumentedFiles: 'temp/',
|
36 | htmlReport: 'report/coverage',
|
37 | coberturaReport: 'report/',
|
38 | lcovReport: 'report/',
|
39 | jsonReport: 'report',
|
40 | linesThresholdPct: 80
|
41 | }
|
42 | },
|
43 | all: {
|
44 | options: {
|
45 | urls: getTestFiles(testDir, testHost)
|
46 | }
|
47 | },
|
48 | only: {
|
49 | options: {
|
50 | urls: []
|
51 | }
|
52 | }
|
53 | },
|
54 |
|
55 | connect: {
|
56 | server: {
|
57 | options: {
|
58 | port: 8000,
|
59 | base: '.'
|
60 | }
|
61 | }
|
62 | },
|
63 |
|
64 | copy: {
|
65 | dist: {
|
66 | src: [
|
67 | '**',
|
68 | '!**/*.styl',
|
69 | '!**/extensions/**',
|
70 | '!**/mixins/**'
|
71 | ],
|
72 | cwd: 'static/style',
|
73 | dest: 'dist/tablefilter/style',
|
74 | expand: true
|
75 | },
|
76 | templates: {
|
77 | src: ['**'],
|
78 | cwd: 'static/templates',
|
79 | dest: 'demos',
|
80 | expand: true
|
81 | },
|
82 | assets: {
|
83 | src: ['**'],
|
84 | cwd: 'static/demos-assets',
|
85 | dest: 'demos/assets',
|
86 | expand: true
|
87 | },
|
88 | starter: {
|
89 | src: ['demos/starter.html'],
|
90 | dest: 'dist/starter.html'
|
91 | }
|
92 | },
|
93 |
|
94 | 'string-replace': {
|
95 | demos: {
|
96 | files: { 'demos/': 'demos/*.html' },
|
97 | options: {
|
98 | replacements: [
|
99 | {
|
100 | pattern: /{NAME}/ig,
|
101 | replacement: pkg.name
|
102 | }, {
|
103 | pattern: /{VERSION}/ig,
|
104 | replacement: pkg.version
|
105 | }, {
|
106 | pattern: /{EZEDITTABLE_LINK}/ig,
|
107 | replacement: '<a href="http://edittable.free.fr/' +
|
108 | 'zip.php?f=ezEditTable.zip&p=1"' +
|
109 | 'target="_blank" title="ezEditTable is a ' +
|
110 | 'javascript code aimed at enhancing regular ' +
|
111 | 'HTML tables by adding features such as ' +
|
112 | 'inline editing components, advanced ' +
|
113 | 'selection and keyboard navigation ' +
|
114 | '- Developed by ' + pkg.author.name + '">' +
|
115 | 'ezEditTable</a>'
|
116 | }, {
|
117 | pattern: /<!-- @import (.*?) -->/ig,
|
118 | replacement: function (match, p1) {
|
119 | return grunt.file.read('static/' + p1);
|
120 | }
|
121 | }
|
122 | ]
|
123 | }
|
124 | }
|
125 | },
|
126 |
|
127 | clean: ['demos/starter.html'],
|
128 |
|
129 | 'webpack-dev-server': {
|
130 | options: {
|
131 | webpack: webpackDevConfig,
|
132 | publicPath: '/dist/'
|
133 | },
|
134 | start: {
|
135 | webpack: {
|
136 | devtool: 'eval'
|
137 | }
|
138 | }
|
139 | },
|
140 |
|
141 | webpack: {
|
142 | build: webpackConfig,
|
143 | dev: webpackDevConfig,
|
144 | test: webpackTestConfig
|
145 | },
|
146 |
|
147 | watch: {
|
148 | app: {
|
149 | files: ['src/**/*', 'static/style/**/*'],
|
150 | tasks: ['dev'],
|
151 | options: {
|
152 | spawn: false
|
153 | }
|
154 | },
|
155 | templates: {
|
156 | files: ['static/templates/**/*', 'static/partials/**/*'],
|
157 | tasks: ['build-demos'],
|
158 | options: {
|
159 | spawn: false
|
160 | }
|
161 | }
|
162 | },
|
163 |
|
164 | babel: {
|
165 | options: {
|
166 | sourceMap: true,
|
167 | modules: 'amd',
|
168 | compact: false,
|
169 | presets: ['es2015']
|
170 | },
|
171 | dist: {
|
172 | files: [{
|
173 | expand: true,
|
174 | cwd: 'src',
|
175 | src: ['**/*.js'],
|
176 | dest: 'dist/tablefilter'
|
177 | }]
|
178 | }
|
179 | },
|
180 |
|
181 | esdoc: {
|
182 | dist: {
|
183 | options: {
|
184 | source: 'src',
|
185 | destination: 'docs/docs',
|
186 | title: pkg.name + ' v' + pkg.version
|
187 | }
|
188 | }
|
189 | },
|
190 |
|
191 | stylus: {
|
192 | compile: {
|
193 | options: {
|
194 | banner: '/** \n' +
|
195 | ' *\t ' + pkg.name + ' v' + pkg.version +
|
196 | ' by ' + pkg.author.name + ' \n' +
|
197 | ' *\t build date: ' + new Date().toISOString() + ' \n' +
|
198 | ' *\t MIT License \n' +
|
199 | ' */ \n'
|
200 | },
|
201 | files: [
|
202 | {
|
203 | src: ['static/style/*.styl'],
|
204 | dest: styleDirDist + 'tablefilter.css'
|
205 | }, {
|
206 | src: ['static/style/extensions/colsVisibility.styl'],
|
207 | dest: styleDirDist + 'colsVisibility.css'
|
208 | }, {
|
209 | src: ['static/style/extensions/filtersVisibility.styl'],
|
210 | dest: styleDirDist + 'filtersVisibility.css'
|
211 | }, {
|
212 | src: ['static/style/themes/default/*.styl'],
|
213 | dest: styleDirDist + 'themes/default/default.css'
|
214 | }, {
|
215 | src: ['static/style/themes/mytheme/*.styl'],
|
216 | dest: styleDirDist + 'themes/mytheme/mytheme.css'
|
217 | }, {
|
218 | src: ['static/style/themes/skyblue/*.styl'],
|
219 | dest: styleDirDist + 'themes/skyblue/skyblue.css'
|
220 | }, {
|
221 | src: ['static/style/themes/transparent/*.styl'],
|
222 | dest:
|
223 | styleDirDist + 'themes/transparent/transparent.css'
|
224 | }
|
225 | ]
|
226 | }
|
227 | },
|
228 |
|
229 | 'gh-pages': {
|
230 | options: {
|
231 | branch: 'gh-pages',
|
232 | add: true
|
233 | },
|
234 | 'publish-lib': {
|
235 | options: {
|
236 | base: 'dist',
|
237 | repo: 'https://' + repo,
|
238 | message: 'publish TableFilter lib to gh-pages (cli)'
|
239 | },
|
240 | src: ['**/*']
|
241 | },
|
242 | 'publish-readme': {
|
243 | options: {
|
244 | base: './',
|
245 | repo: 'https://' + repo,
|
246 | message: 'publish README and LICENSE to gh-pages (cli)'
|
247 | },
|
248 | src: ['README.md', 'LICENSE']
|
249 | },
|
250 | 'publish-docs': {
|
251 | options: {
|
252 | base: 'docs',
|
253 | repo: 'https://' + repo,
|
254 | message: 'publish Docs to gh-pages (cli)'
|
255 | },
|
256 | src: ['**/*']
|
257 | },
|
258 | 'deploy-lib': {
|
259 | options: {
|
260 | user: {
|
261 | name: 'koalyptus'
|
262 | },
|
263 | base: 'dist',
|
264 | repo: 'https://' + process.env.GH_TOKEN + '@' + repo,
|
265 | message: 'publish TableFilter to gh-pages (auto)' +
|
266 | getDeployMessage(),
|
267 | silent: true
|
268 | },
|
269 | src: ['**/*']
|
270 | },
|
271 | 'deploy-readme': {
|
272 | options: {
|
273 | user: {
|
274 | name: 'koalyptus'
|
275 | },
|
276 | base: './',
|
277 | repo: 'https://' + process.env.GH_TOKEN + '@' + repo,
|
278 | message: 'publish README to gh-pages (auto)' +
|
279 | getDeployMessage(),
|
280 | silent: true
|
281 | },
|
282 | src: ['README.md', 'LICENSE']
|
283 | },
|
284 | 'deploy-docs': {
|
285 | options: {
|
286 | user: {
|
287 | name: 'koalyptus'
|
288 | },
|
289 | base: 'docs',
|
290 | repo: 'https://' + process.env.GH_TOKEN + '@' + repo,
|
291 | message: 'publish Docs to gh-pages (auto)' +
|
292 | getDeployMessage(),
|
293 | silent: true
|
294 | },
|
295 | src: ['**/*']
|
296 | }
|
297 | }
|
298 |
|
299 | });
|
300 |
|
301 | grunt.loadNpmTasks('grunt-eslint');
|
302 | grunt.loadNpmTasks('grunt-contrib-copy');
|
303 | grunt.loadNpmTasks('grunt-contrib-clean');
|
304 | grunt.loadNpmTasks('grunt-contrib-watch');
|
305 | grunt.loadNpmTasks('grunt-string-replace');
|
306 | grunt.loadNpmTasks('grunt-contrib-connect');
|
307 | grunt.loadNpmTasks('grunt-webpack');
|
308 | grunt.loadNpmTasks('grunt-babel');
|
309 | grunt.loadNpmTasks('grunt-esdoc');
|
310 | grunt.loadNpmTasks('grunt-qunit-istanbul');
|
311 | grunt.loadNpmTasks('grunt-contrib-stylus');
|
312 | grunt.loadNpmTasks('grunt-gh-pages');
|
313 |
|
314 | grunt.registerTask('default', ['test', 'build', 'build-demos']);
|
315 |
|
316 |
|
317 | grunt.registerTask('server', ['webpack-dev-server:start']);
|
318 |
|
319 |
|
320 | grunt.registerTask('dev',
|
321 | ['eslint', 'webpack:dev', 'copy:dist', 'stylus:compile', 'watch:app']);
|
322 |
|
323 |
|
324 | grunt.registerTask('build',
|
325 | ['eslint', 'webpack:build', 'copy:dist', 'stylus:compile']);
|
326 |
|
327 |
|
328 | grunt.registerTask('dev-demos', ['build-demos', 'watch:templates']);
|
329 | grunt.registerTask('build-demos', ['copy:templates', 'copy:assets',
|
330 | 'string-replace:demos', 'copy:starter', 'clean']);
|
331 |
|
332 |
|
333 | grunt.registerTask('build-test',
|
334 | ['eslint', 'webpack:test', 'copy:dist', 'stylus:compile']);
|
335 |
|
336 |
|
337 | grunt.registerTask('dev-modules', ['babel', 'copy:dist']);
|
338 |
|
339 |
|
340 | grunt.registerTask('test', ['build-test', 'connect', 'qunit:all']);
|
341 |
|
342 |
|
343 | grunt.registerTask('publish', 'Publish from CLI', [
|
344 | 'build', 'build-demos', 'esdoc', 'gh-pages:publish-lib',
|
345 | 'gh-pages:publish-readme', 'gh-pages:publish-docs'
|
346 | ]);
|
347 |
|
348 |
|
349 | grunt.registerTask('deploy', 'Publish from Travis', [
|
350 | 'build', 'esdoc', 'check-deploy'
|
351 | ]);
|
352 |
|
353 |
|
354 |
|
355 | grunt.registerTask('test-only',
|
356 | 'A task that runs only specified tests.',
|
357 | function (tests) {
|
358 | if (!tests) {
|
359 | return;
|
360 | }
|
361 | tests = tests.split(',');
|
362 | var res = [];
|
363 |
|
364 | tests.forEach(function (itm) {
|
365 | var filePath = path.resolve(testDir, itm);
|
366 | var parts = filePath.split(path.sep);
|
367 | res.push(buildTestUrl(testHost, testDir, parts));
|
368 | });
|
369 |
|
370 | grunt.task.run('connect');
|
371 | grunt.config('qunit.only.options.urls', res);
|
372 | grunt.task.run('qunit:only');
|
373 | }
|
374 | );
|
375 |
|
376 | function isTestFile(pth) {
|
377 | var allowedExts = ['.html', '.htm'];
|
378 | for (var i = 0, len = allowedExts.length; i < len; i++) {
|
379 | var ext = allowedExts[i];
|
380 | if (pth.indexOf(ext) !== -1) {
|
381 | return true;
|
382 | }
|
383 | }
|
384 | return false;
|
385 | }
|
386 |
|
387 | function buildTestUrl(host, testDir, parts) {
|
388 | var idx = parts.indexOf(testDir);
|
389 | var fileIdx = parts.length;
|
390 | var relParts = parts.slice(idx, fileIdx);
|
391 | return host.concat(relParts.join('/'));
|
392 | }
|
393 |
|
394 |
|
395 | function getTestFiles(testDir, host) {
|
396 | var getFiles = function (dir, host) {
|
397 | var res = [];
|
398 | var items = fs.readdirSync(dir);
|
399 |
|
400 | items.forEach(function (itm) {
|
401 | var fileOrDir = path.resolve(dir, itm);
|
402 | if (isTestFile(fileOrDir)) {
|
403 | var parts = fileOrDir.split(path.sep);
|
404 | res.push(buildTestUrl(host, testDir, parts));
|
405 | } else {
|
406 | if (fs.lstatSync(fileOrDir).isDirectory()) {
|
407 | res = res.concat(getFiles(fileOrDir, host));
|
408 | }
|
409 | }
|
410 | });
|
411 |
|
412 | return res;
|
413 | };
|
414 |
|
415 | return getFiles(testDir, host);
|
416 | }
|
417 |
|
418 | grunt.registerTask('check-deploy', function () {
|
419 | var env = process.env;
|
420 |
|
421 | this.requires(['build', 'esdoc']);
|
422 |
|
423 |
|
424 | if (env.TRAVIS === 'true' &&
|
425 | env.TRAVIS_SECURE_ENV_VARS === 'true' &&
|
426 | env.TRAVIS_PULL_REQUEST === 'false') {
|
427 | grunt.log.writeln('executing deployment');
|
428 |
|
429 | grunt.task.run([
|
430 | 'gh-pages:deploy-lib',
|
431 | 'gh-pages:deploy-readme',
|
432 | 'gh-pages:deploy-docs'
|
433 | ]);
|
434 | } else {
|
435 | grunt.log.writeln('skipped deployment');
|
436 | }
|
437 | });
|
438 |
|
439 |
|
440 |
|
441 | function getDeployMessage() {
|
442 | var ret = '\n\n';
|
443 | var env = process.env;
|
444 | if (env.TRAVIS !== 'true') {
|
445 | ret += 'missing env vars for travis-ci';
|
446 | return ret;
|
447 | }
|
448 | ret += 'branch: ' + env.TRAVIS_BRANCH + '\n';
|
449 | ret += 'SHA: ' + env.TRAVIS_COMMIT + '\n';
|
450 | ret += 'range SHA: ' + env.TRAVIS_COMMIT_RANGE + '\n';
|
451 | ret += 'build id: ' + env.TRAVIS_BUILD_ID + '\n';
|
452 | ret += 'build number: ' + env.TRAVIS_BUILD_NUMBER + '\n';
|
453 | return ret;
|
454 | }
|
455 |
|
456 | };
|