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