Let the thread to be managed outside the binding.
[apps/agl-service-can-low-level.git] / CAN-binder / low-can-demo / gulpfile.js
1 // BUG Symlink not working
2
3 var gulp = require('gulp');
4 var debug = require('gulp-debug');
5 var plugins = require('gulp-load-plugins')();
6 var del = require('del');
7 var es = require('event-stream');
8 var bowerFiles = require('main-bower-files');
9 var print = require('gulp-print');
10 var Q = require('q');
11 var imagemin = require('gulp-imagemin'), pngquant = require('imagemin-pngquant');
12 var taskListing = require('gulp-task-listing');
13 var symlink = require('gulp-sym');
14 var rename = require("gulp-rename");
15 var exec = require('child_process').exec
16 var argv = require('yargs').argv;
17
18 // == PATH STRINGS ========
19 var appdir  = "./app/";   // Warning to not forget trailling '/'
20 config=require (appdir + "etc/_Config"); // upload user local preferences if any
21
22 var frontend= appdir + config.FRONTEND;
23
24 var paths = {
25     application : frontend,
26     scripts     : frontend+'/**/*.js',
27     appStyles   : [frontend+'/**/*.scss', '!'+frontend+'/styles/*.scss'],
28     globalStyles: [frontend+'/styles/*.scss'],
29     images      : [
30                 frontend+'/**/*.png',
31                 frontend+'/**/*.jpg',
32                 frontend+'/**/*.jpeg',
33                 frontend+'/**/*.svg',
34                 frontend+'/**/*.ttf',
35                 'bower_components/leaflet/dist/images/*.png'
36         ],
37     index       : frontend+'/index.html',
38     partials    : [frontend + '/**/*.html', '!' + frontend +'/index.html'],
39     distDev     : './dist.dev',
40     distProd    : './dist.prod',
41     sass:  [
42                 frontend+'/styles',
43                 'bower_components/bootstrap-sass/assets/stylesheets'
44         ],
45     fonts: ['bower_components/**/*.woff'],
46     favicon: frontend+'/images/favicon.ico',
47         wgtconfig: 'config.xml'
48 };
49
50 // add bower files to global styles
51 bowerFiles('**/*.css').forEach(function(p) {
52         paths.globalStyles.unshift(p);
53 });
54
55 paths['distAppDev']  = paths.distDev + config.URLBASE;
56 paths['distAppProd'] = paths.distProd + config.URLBASE;
57
58 // Run node in debug mode in developpement mode ?
59 var nodeopts = config.DEBUG !== undefined ? '--debug='+config.DEBUG : ''; 
60
61 // == PIPE SEGMENTS ========
62 var pipes = {};
63
64 pipes.orderedVendorScripts = function() {
65     return plugins.order(['jquery.js', 'bootstrap.js','leaflet-src.js','tween.js','steelseries.js']);
66 };
67
68 pipes.minifiedFileName = function() {
69     return plugins.rename(function (path) {
70         path.extname = '.min' + path.extname;
71     });
72 };
73
74 pipes.validatedAppScripts = function() {
75     return gulp.src(paths.scripts)
76         .pipe(plugins.replace('@@APPNAME@@', config.APPNAME))
77         .pipe(plugins.replace('@@APPVER@@', config.APPVER))
78         .pipe(plugins.jshint())
79         .pipe(plugins.jshint.reporter('jshint-stylish'));
80 };
81
82 pipes.builtAppScriptsDev = function() {
83     return pipes.validatedAppScripts()
84         .pipe(gulp.dest(paths.distAppDev));
85 };
86
87 pipes.builtAppScriptsProd = function() {
88     var scriptedPartials = pipes.scriptedPartials();
89     var validatedAppScripts = pipes.validatedAppScripts();
90     return es.merge(scriptedPartials, validatedAppScripts)
91         .pipe(plugins.sourcemaps.init())
92         .pipe(plugins.concat(config.APPNAME+'.min.js'))
93         .pipe(plugins.uglify({compress: {drop_console: true}}))
94         .pipe(plugins.sourcemaps.write())
95         .pipe(gulp.dest(paths.distAppProd+'/js'));
96 };
97
98 pipes.builtVendorScriptsDev = function() {
99     return gulp.src(bowerFiles('**/*.js'))
100         .pipe(gulp.dest( paths.distDev +'/bower_components'));
101 };
102
103 pipes.builtVendorScriptsProd = function() {
104     return gulp.src(bowerFiles('**/*.js'))
105         .pipe(pipes.orderedVendorScripts())
106         .pipe(plugins.concat('vendor.min.js'))
107         .pipe(plugins.uglify())
108         .pipe(gulp.dest(paths.distProd+ '/bower_components'));
109 };
110
111
112 pipes.validatedPartials = function() {
113     return gulp.src(paths.partials)
114         .pipe(plugins.htmlhint({'doctype-first': false}))
115         .pipe(plugins.htmlhint.reporter());
116 };
117
118 pipes.builtPartialsDev = function() {
119     return pipes.validatedPartials()
120         .pipe(gulp.dest(paths.distAppDev));
121 };
122
123 pipes.scriptedPartials = function() {
124     return pipes.validatedPartials()
125         .pipe(plugins.htmlhint.failReporter())
126         .pipe(plugins.htmlmin({collapseWhitespace: true, removeComments: true}));
127 };
128
129 pipes.builtAppStylesDev = function() {
130     return gulp.src(paths.appStyles)
131         .pipe(plugins.sass({includePaths: paths.sass}))
132         .pipe(gulp.dest(paths.distAppDev + '/styles'));
133 };
134
135 pipes.builtglobalStylesDev = function() {
136     return gulp.src(paths.globalStyles)
137         .pipe(plugins.sass({includePaths: paths.sass}))
138         .pipe(gulp.dest(paths.distDev  + '/global_styles'));
139 };
140
141 pipes.builtAppStylesProd = function() {
142     return gulp.src(paths.appStyles)
143         .pipe(plugins.sourcemaps.init())
144         .pipe(plugins.sass({includePaths: paths.sass}))
145         // .pipe(debug({title: '***** appStyle:'}))
146         .pipe(plugins.cleanCss())
147         .pipe(plugins.concat(config.APPNAME+'.css'))
148         .pipe(plugins.sourcemaps.write())
149         .pipe(pipes.minifiedFileName())
150         .pipe(gulp.dest(paths.distAppProd));
151 };
152
153 pipes.builtglobalStylesProd = function() {
154     return gulp.src(paths.globalStyles)
155         .pipe(plugins.sourcemaps.init())
156         .pipe(plugins.sass({includePaths: paths.sass}))
157         .pipe(plugins.cleanCss())
158         .pipe(plugins.sourcemaps.write())
159         .pipe(pipes.minifiedFileName())
160         .pipe(rename(function (path) {path.dirname="";return path;}))
161         .pipe(plugins.concat('output.min.css'))
162         .pipe(gulp.dest(paths.distProd + '/global_styles'));
163 };
164
165 pipes.processedFontsDev = function() {
166     return gulp.src(paths.fonts)
167         .pipe(rename(function (path) {path.dirname="";return path;}))
168         .pipe(gulp.dest(paths.distDev+'/bower_components'));
169 };
170
171 pipes.processedFontsProd = function() {
172     return gulp.src(paths.fonts)
173         .pipe(rename(function (path) {path.dirname="";return path;}))
174         .pipe(gulp.dest(paths.distProd+'/bower_components'));
175 };
176
177
178 pipes.processedImagesDev = function() {
179     return gulp.src(paths.images)
180                 .pipe(rename(function(path) { path.dirname=""; return path; }))
181         .pipe(gulp.dest(paths.distAppDev+"/images/"));
182 };
183
184 pipes.processedFaviconDev = function() {
185     return gulp.src(paths.favicon)
186         .pipe(gulp.dest(paths.distDev));
187 };
188
189 pipes.processedImagesProd = function() {
190     return gulp.src(paths.images)
191                 .pipe(rename(function(path) { path.dirname=""; return path; }))
192        .pipe(imagemin({
193             progressive: true,
194             svgoPlugins: [{removeViewBox: false}],
195             use: [pngquant()]
196         }))
197         .pipe(gulp.dest(paths.distAppProd+"/images/"));
198 };
199
200 pipes.processedFaviconProd = function() {
201     return gulp.src(paths.favicon)
202         .pipe(gulp.dest(paths.distProd));
203 };
204
205 // Create an Symlink when config.URLBASE exist
206 pipes.createDevSymLink = function() {
207     return gulp.src(paths.distDev).pipe(symlink(paths.distDev+config.URLBASE, {force: true}));
208 };
209
210 pipes.createProdSymLink = function() {
211     return gulp.src(paths.distProd).pipe(symlink(paths.distDev+config.URLBASE,{force: true}));
212 };
213
214 pipes.validatedIndex = function() {
215     return gulp.src(paths.index)       
216         .pipe(plugins.replace('@@APPNAME@@', config.APPNAME))
217         .pipe(plugins.replace('@@APPVER@@', config.APPVER))
218         .pipe(plugins.replace('@@URLBASE@@', config.URLBASE))
219         .pipe(plugins.htmlhint())
220         .pipe(plugins.htmlhint.reporter());
221 };
222
223 pipes.builtIndexDev = function() {
224
225     var orderedVendorScripts = pipes.builtVendorScriptsDev()
226         .pipe(pipes.orderedVendorScripts());
227
228     var orderedAppScripts = pipes.builtAppScriptsDev();
229
230     var appStyles    = pipes.builtAppStylesDev();
231     var globalStyles = pipes.builtglobalStylesDev();
232
233     return pipes.validatedIndex()
234          // Vendor and Global should have absolute path to rootdir application one are relative to BaseURL
235         .pipe(plugins.inject(orderedVendorScripts, {relative: false, ignorePath: "/dist.dev", name: 'bower'}))
236         .pipe(plugins.inject(globalStyles, {relative: false, ignorePath: "/dist.dev", name:'vendor'}))
237         .pipe(gulp.dest(paths.distAppDev)) // write first to get relative path for inject
238         .pipe(plugins.inject(orderedAppScripts, {relative: true}))
239         .pipe(plugins.inject(appStyles, {relative: true, name: 'appli'}))
240         .pipe(gulp.dest(paths.distAppDev));
241 };
242
243 pipes.builtIndexProd = function() {
244
245     var vendorScripts= pipes.builtVendorScriptsProd();
246     var appScripts   = pipes.builtAppScriptsProd();
247     var appStyles    = pipes.builtAppStylesProd();
248     var globalStyles = pipes.builtglobalStylesProd();
249
250     return pipes.validatedIndex()
251          // Vendor and Global should have absolute path to rootdir application one are relative to BaseURL
252         .pipe(plugins.inject(vendorScripts, {relative: false, ignorePath: "/dist.prod", name: 'bower'}))
253         .pipe(plugins.inject(globalStyles, {relative: false, ignorePath: "/dist.prod", name:'vendor'}))
254         .pipe(gulp.dest(paths.distAppProd)) // write first to get relative path for inject
255         .pipe(plugins.inject(appScripts, {relative: true}))
256         .pipe(plugins.inject(appStyles, {relative: true, name:'appli'}))
257         .pipe(plugins.htmlmin({collapseWhitespace: true, removeComments: true}))
258         .pipe(gulp.dest(paths.distAppProd));
259 };
260
261 pipes.builtAppDev = function() {
262     return es.merge(pipes.builtIndexDev(), pipes.builtPartialsDev(), pipes.processedFaviconDev(), pipes.processedImagesDev(), pipes.processedFontsDev() )
263                 .pipe(pipes.doRsync("Dev"));
264 };
265
266 pipes.builtAppProd = function() {
267     return es.merge(pipes.builtIndexProd(), pipes.processedFaviconProd(), pipes.processedImagesProd(), pipes.processedFontsProd())
268                 .pipe(pipes.doRsync("Prod"));
269 };
270
271 pipes.widgetConfig = function(type) {
272         var dst=paths["dist"+type];
273         var content="."+config.URLBASE+"/index.html";
274         content=content.replace(/\/+/g,"/"); 
275         return gulp.src(paths.wgtconfig+".in")
276         .pipe(plugins.replace('@@APPNAME@@', config.APPNAME))
277         .pipe(plugins.replace('@@APPVER@@', config.APPVER))
278         .pipe(plugins.replace('@@CONTENT@@', content))
279         .pipe(plugins.rename("config.xml"))
280                 .pipe(gulp.dest(dst))
281 };
282
283 pipes.widgetPack = function(type,cb) {
284         var dst=paths["dist"+type];
285         var wgtfile=config.APPNAME+"_"+type+".wgt"
286
287         exec(
288                 "wgtpkg-pack -f -o "+wgtfile+" "+dst,
289                 function(err,stdout,stderr) {
290                         console.log(stdout);
291                         console.log(stderr);
292                         cb(err);
293         });
294 };
295
296 pipes.doRsync=function(type) {
297         var dst=paths["dist"+type];
298         if (!argv.host) return plugins.empty();
299
300         return plugins.rsync({
301                 root: dst+"/",
302                 hostname: argv.host,
303                 username: "root",
304                 destination: "/usr/share/afm/applications/"+config.APPNAME+"/"+config.APPVER+"/htdocs/",
305                 archive: true,
306                 compress: true,
307                 recursive: true
308         });
309 }
310
311 // == TASKS ========
312
313 // Add a task to render the output 
314 gulp.task('help', taskListing.withFilters(/-/));
315    
316 // clean, build of production environement
317 gulp.task('build', ['clean-build-app-prod']);
318
319 // removes all compiled dev files
320 gulp.task('clean-dev', function() {
321     var deferred = Q.defer();
322     del(paths.distDev, function() {
323         deferred.resolve();
324     });
325     return deferred.promise;
326 });
327
328 // removes all compiled production files
329 gulp.task('clean-prod', function() {
330     var deferred = Q.defer();
331     del(paths.distProd, function() {
332         deferred.resolve();
333     });
334     return deferred.promise;
335 });
336
337 // checks html source files for syntax errors
338 gulp.task('validate-partials', pipes.validatedPartials);
339
340 // checks index.html for syntax errors
341 gulp.task('validate-index', pipes.validatedIndex);
342
343 // moves html source files into the dev environment
344 gulp.task('build-partials-dev', pipes.builtPartialsDev);
345
346 // converts partials to javascript using html2js
347 gulp.task('convert-partials-to-js', pipes.scriptedPartials);
348
349 // runs jshint on the app scripts
350 gulp.task('validate-app-scripts', pipes.validatedAppScripts);
351
352 // moves app scripts into the dev environment
353 gulp.task('build-app-scripts-dev', pipes.builtAppScriptsDev);
354
355 // concatenates, uglifies, and moves app scripts and partials into the prod environment
356 gulp.task('build-app-scripts-prod', pipes.builtAppScriptsProd);
357
358 // compiles app sass and moves to the dev environment
359 gulp.task('build-app-styles-dev', pipes.builtAppStylesDev);
360
361 // compiles and minifies app sass to css and moves to the prod environment
362 gulp.task('build-app-styles-prod', pipes.builtAppStylesProd);
363
364 // moves vendor scripts into the dev environment
365 gulp.task('build-vendor-scripts-dev', pipes.builtVendorScriptsDev);
366
367 // concatenates, uglifies, and moves vendor scripts into the prod environment
368 gulp.task('build-vendor-scripts-prod', pipes.builtVendorScriptsProd);
369
370 // validates and injects sources into index.html and moves it to the dev environment
371 gulp.task('build-index-dev', pipes.builtIndexDev);
372
373 // validates and injects sources into index.html, minifies and moves it to the dev environment
374 gulp.task('build-index-prod', pipes.builtIndexProd);
375
376 // builds a complete dev environment
377 gulp.task('build-app-dev', pipes.builtAppDev);
378
379 // builds a complete prod environment
380 gulp.task('build-app-prod', pipes.builtAppProd);
381
382 // cleans and builds a complete dev environment
383 gulp.task('clean-build-app-dev', ['clean-dev'], pipes.builtAppDev);
384
385 // cleans and builds a complete prod environment
386 gulp.task('clean-build-app-prod', ['clean-prod'], pipes.builtAppProd);
387
388 // clean, build, and watch live changes to the dev environment
389 gulp.task('watch-dev', ['clean-build-app-dev'], function() {
390
391     // watch index
392     gulp.watch(paths.index, function() {
393         return pipes.builtIndexDev()
394                         .pipe(pipes.doRsync("Dev"))
395             .pipe(plugins.livereload());
396     });
397
398     // watch app scripts
399     gulp.watch(paths.scripts, function() {
400         return pipes.builtAppScriptsDev()
401                         .pipe(pipes.doRsync("Dev"))
402             .pipe(plugins.livereload());
403     });
404
405     // watch html partials
406     gulp.watch(paths.partials, function() {
407         return pipes.builtPartialsDev()
408                         .pipe(pipes.doRsync("Dev"))
409             .pipe(plugins.livereload());
410     });
411     
412     // watch Images
413     gulp.watch(paths.images, function() {
414         return pipes.processedImagesDev()
415                         .pipe(pipes.doRsync("Dev"))
416             .pipe(plugins.livereload());
417     });
418
419     // watch styles
420     gulp.watch(paths.appStyles, function() {
421         return pipes.builtAppStylesDev()
422                         .pipe(pipes.doRsync("Dev"))
423             .pipe(plugins.livereload());
424     });
425     gulp.watch(paths.globalStyles, function() {
426         return pipes.builtglobalStylesDev()
427                         .pipe(pipes.doRsync("Dev"))
428             .pipe(plugins.livereload());
429     });
430
431 });
432
433 // clean, build, and watch live changes to the prod environment
434 gulp.task('watch-prod', ['clean-build-app-prod'], function() {
435
436     // watch index
437     gulp.watch(paths.index, function() {
438         return pipes.builtIndexProd()
439                         .pipe(pipes.doRsync("Prod"))
440             .pipe(plugins.livereload());
441     });
442
443     // watch app scripts
444     gulp.watch(paths.scripts, function() {
445         return pipes.builtAppScriptsProd()
446                         .pipe(pipes.doRsync("Prod"))
447             .pipe(plugins.livereload());
448     });
449
450     // watch hhtml partials
451     gulp.watch(paths.partials, function() {
452         return pipes.builtAppScriptsProd()
453                         .pipe(pipes.doRsync("Prod"))
454             .pipe(plugins.livereload());
455     });
456     
457     // watch Images
458     gulp.watch(paths.images, function() {
459         return pipes.processedImagesProd()
460                         .pipe(pipes.doRsync("Prod"))
461             .pipe(plugins.livereload());
462     });
463
464     // watch styles
465     gulp.watch(paths.appStyles, function() {
466         return pipes.builtAppStylesProd()
467                         .pipe(pipes.doRsync("Prod"))
468             .pipe(plugins.livereload());
469     });
470     gulp.watch(paths.globalStyles, function() {
471         return pipes.builtglobalStylesProd()
472                         .pipe(pipes.doRsync("Prod"))
473             .pipe(plugins.livereload());
474     });
475     
476 });
477
478 gulp.task('widget-config-dev',  ['build-app-dev'],  function() { return pipes.widgetConfig("Dev"); });
479 gulp.task('widget-config-prod', ['build-app-prod'], function() { return pipes.widgetConfig("Prod"); });
480 gulp.task('widget-dev',  ['widget-config-dev'],  function(cb) { return pipes.widgetPack("Dev",cb); });
481 gulp.task('widget-prod', ['widget-config-prod'], function(cb) { return pipes.widgetPack("Prod",cb); });
482
483 // default task builds for prod
484 gulp.task('default', ['widget-prod']);