Execute gulp task only if flag is passed? - gulp

Current Code:
var open = require('open');
var gulp = require("gulp");
var pkg = require("../../package.json");
//opens the launchpage with default browser
gulp.task("open", function () {
open('http://localhost:' + pkg.webServerPort + '/commonclient/launchpage.html');
});
Right now, running the gulp command starts the server and does a bunch of other compilation tasks. How to modify this to run the "open" task only if I type in gulp -o or something like that in command line?

You can do this by inspecting process.argv, or simply looking for an ENV flag on process.env
gulp.task("open", function () {
if (process.argv.indexOf('-o') > -1) {
open('http://localhost:' + pkg.webServerPort + '/commonclient/launchpage.html');
}
});
Or with an env variable
gulp.task("open", function () {
if (processs.env.USE_OPEN) {
open('http://localhost:' + pkg.webServerPort + '/commonclient/launchpage.html');
}
});

Related

Gulp default task unable to compress after copy

At first I thought this was related to dependency of tasks so I went with run-sequence and even tried defining dependencies within tasks themselves. But I cannot get the compress task to run after copy. Or, even if it says it did finish the compress task, the compression only works if I run compress in the task runner inside visual studio by itself. What else can I try to get it to compress after copy?
/// <binding BeforeBuild='default' />
/*
This file is the main entry point for defining Gulp tasks and using Gulp plugins.
Click here to learn more. https://go.microsoft.com/fwlink/?LinkId=518007
*/
var gulp = require("gulp");
var debug = require("gulp-debug");
var del = require("del");
var uglify = require("gulp-uglify");
var pump = require("pump");
var runSequence = require("run-sequence");
var paths = {
bower: "./bower_components/",
lib: "./Lib/"
};
var modules = {
"store-js": ["store-js/dist/store.legacy.js"],
"bootstrap-select": [
"bootstrap-select/dist/css/bootstrap-select.css",
"bootstrap-select/dist/js/bootstrap-select.js",
"bootstrap-select/dist/js/i18n/*.min.js"
]
}
gulp.task("default", function (cb) {
runSequence("clean", ["copy", "compress"], cb);
});
gulp.task("clean",
function () {
return del.sync(["Lib/**", "!Lib", "!Lib/ReadMe.md"]);
});
gulp.task("compress",
function (cb) {
pump([
gulp.src(paths.lib + "**/*.js"),
uglify(),
gulp.dest(paths.lib)
], cb);
});
gulp.task("copy",
function (cb) {
prefixPathToModules();
copyModules();
cb();
});
function prefixPathToModules() {
for (var moduleIndex in modules) {
for (var fileIndex in modules[moduleIndex]) {
modules[moduleIndex][fileIndex] = paths.bower + modules[moduleIndex][fileIndex];
}
}
}
function copyModules() {
for (var files in modules) {
gulp.src(modules[files], { base: paths.bower })
.pipe(gulp.dest(paths.lib));
}
}
You use run-sequence and your code
runSequence("clean", ["copy", "compress"], cb);
run in such order
clean
copy and compress in parallel // that's why your code compresses nothing, because you have not copied files yet
cb
Write like this and compress will be after copy
runSequence("clean", "copy", "compress", cb);
I am not familiar with runSequence. But why don't you try the following. By this way your default task depends on compress and compress depends on copy. So, 'copy' will run first and then 'compress'
gulp.task('default', ['copy','compress'], function(cb){});
gulp.task('compress',['copy'], function(cb){});
Gulp returns a steam , since you are calling it in a for loop the stream is returned during the first iteration itself.
Update your copyModule to the following and you can try either runSequence like posted by Kirill or follow my approach
function copyModules() {
var inputFileArr = [];
for (var files in modules) {
inputFileArr = inputFileArr.concat(modules[files]);
};
return gulp.src(inputFileArr, { base: paths.bower })
.pipe(gulp.dest(paths.lib));
}

gulp protractor sets argv.baseur

gulp.task(
'protractor', function () { console.log("xx4");
var configObj = {
configFile: config.test + 'protractor.conf.js'
};
configObj['args'] =[];//to be able to add multiple parameters
if (argv.suite) {
configObj['args'].push (
'--suite',
argv.suite
);
}
if (argv.env) {
configObj['args'].push (
'--env',
argv.env
);
}
argv.baseUrl = produrl;
console.log("devurl",produrl);
configObj['args'].push (
'--baseUrl',
argv.baseUrl
);
console.log("argv.baseUrl",argv.baseUrl);
return gulp.src([])
.pipe(plumber({errorHandler: handleErrors}))
.pipe(protractor(configObj))
.on(
'error', function () {
gutil.log('E2E Tests failed');
process.exit(1);
}
);
}
);
var qaurl = require('./env-config/qa-baseurl');
var produrl = require('./env-config/prod-baseurl');
var localurl = require('./env-config/local-baseurl');
gulp.task('qa', function () {
console.log("argv.baseUrl",argv.baseUrl);
});
gulp.task('local', function () {
console.log("xx3");
return process.env.NODE_ENV = 'development';
});
when i run
gulp protractor
or
gulp protractor qa
it should make argv.baseurl for qa url and it should push to configobj. but configobj is in protractor.
ReferenceError: configObj is not defined
this is erro.r.
gulp.task(
'protractor', ['env'],function () { console.log("xx4");
i can do something like this but it wont push again. Also i cant get qa or local to parameter to put firstly task?
for that
gulp.task(
'protractor', ['env']
i mean here, first go to env (env means qa or prod or local)
when i run from
gulp protractor local
how i can get local to that env?
How can i make it push and so that i can use in protractor
this is localurl
module.exports = "localhost:8080";
only url
i cam use setbaseurl task [setbaseurl] but how wiil i get local in
gulp protractor local?
for pushing data in array:
var configObj = {'configFile': 'protractor.conf.js',
'arg':''};
configObj['arg'] = [];
for(var i = 0; i<5; i++){
configObj['arg'].push('value of i::' + i);
}
console.log(a);
Output:
Object {configFile: "protractor.conf.js", arg: Array[5]}
where arg is:
0:"value of i::0"
1:"value of i::1"
2:"value of i::2"
3:"value of i::3"
4:"value of i::4"
For gulp task:
var gulp = require('gulp');
var taskName = '';
gulp.task(
'protractor', function () {
taskName = process.argv[3];
}, taskName.toString());
gulp.task('qa', function () {
console.log("qa task executing");
});
gulp.task('local', function () {
console.log("local task executing");
});
command used:
gulp protractor qa
Output on console:
$ gulp protractor qa
[13:18:52] Using gulpfile ~\Desktop\sample file\gulpfile.js
[13:18:52] Starting 'protractor'...
[13:18:52] Finished 'protractor' after 55 μs
[13:18:52] Starting 'qa'...
qa task executing
[13:18:52] Finished 'qa' after 21 μs
If you want to use this configObj in conf.js file then in the args section, pass ['--params.configObj', configObj]
where "--params.configObj" is defined in conf.js
params: {
configObj: ''
}
To add self reference you can use like:
configObj['--params.configObj'] = configObj;

Check if user specifies a flag?

Is it possible to check if a user has specified a flag eg.
gulp --test=yes
I'd get the flag via:
yargs.argv.test;
And if they have not halt the gulp script and output an error message?
If it's a global flag that is required for every task you can just check it first thing in your gulpfile and exit() if it hasn't been provided:
var gulp = require('gulp');
var yargs = require('yargs');
if (!yargs.argv.test) {
console.error('You need to provide the --test flag!');
process.exit(1);
}
gulp.task('someTask', function() {
console.log('Value of --test flag is :' + yargs.argv.test);
});
gulp.task('default', function() {
console.log('Value of --test flag is :' + yargs.argv.test);
});
If the flag is only valid for a certain task just check it in that particular task:
var gulp = require('gulp');
var yargs = require('yargs');
gulp.task('someTask', function() {
if (!yargs.argv.test) {
console.error('You need to provide the --test flag for someTask!');
process.exit(1);
}
console.log('Value of --test flag is :' + yargs.argv.test);
});
gulp.task('default', function() {
console.log('This task does not need the --test flag!');
});

Using gulp-minify-html and gulp-html-replace together

I am using Gulp with gulp-minify-html and gulp-html-replace:
var minifyhtml = require('gulp-minify-html');
var htmlreplace = require('gulp-html-replace');
var dev_paths = {
HTML: dev + '/**/*.html'
};
var prod_paths = {
RELATIVE_CSS: ['css/bootstrap.css', 'css/font-awesome.css', 'css/c3.css', 'css/main.css'],
};
//Compress HTML
gulp.task('minify-html', function () {
var opts = {
empty: true,
comments: true
};
return gulp.src(dev_paths.HTML)
.pipe(minifyhtml(opts))
.pipe(gulp.dest(prod + '/'));
});
//Add call to the JS and CSS in the HTML files
gulp.task('replace-files', function() {
gulp.src(dev_paths.HTML)
.pipe(htmlreplace({
'css': prod_paths.RELATIVE_CSS,
'js': 'js/script.js'
}))
.pipe(gulp.dest('public/prod/'));
});
gulp.task('prod',['replace-files','minify-html'], function(){
})
However, the HTML doesn't replace the CSS and JS files I specified with task replace-files. When I run gulp without the task minify-html, it works fine though.
Does anyone knows why using both tasks replace-files and minify-html together is not working?
Thank you.
As the tasks run in parallel it is likely the 'minify-html' task is running before the 'replace-files' task is complete.
Try using run-sequence to ensure the tasks run in the required order.

How to detect css theme and work only with this theme?

I have a project in which there are about 30 css themes. It means I have the next css files structure:
src/
themes/
default/
a.scss
b.scss
rockStar/
a.scss
b.scss
oneMoreTheme/
a.scss
b.scss
dist/
themes/
default/
styles.css
rockStar/
styles.css
oneMoreTheme/
styles.css
Here is just example of gulpfile:
var gulp = require('gulp'),
glob = require('glob'),
path = require('path'),
_ = require('underscore'),
$ = require('gulp-load-plugins')(),
options = {};
options.themes = [
'default',
'rockStar',
'oneMoreTheme'
];
gulp.task('styles', function () {
_.each(options.themes, function(themeName, themeKey) {
gulp.src('src/themes/' + themeName + '/**/*.scss')
.pipe($.concat('styles.scss'))
.pipe($.sass())
.pipe(gulp.dest('dist/themes/' + themeName + '/'));
});
});
gulp.task('watch', function () {
gulp.watch('src/**/*.*', ['styles']);
});
In my gulp file I have a task "styles", which compiles scss files from each theme and puts compiled files to dist folder.
And I have task "watch" which run "styles" task when any scss file form any source theme changes. It works, but it takes much time because of lots of themes!
How can my task "watch" detect from which theme files changes and run task "styles" only for this changed theme?
That is indeed a tough one, but here is a solution. Please refer to the comments in the code for an explanation.
version 1
var gulp = require('gulp');
var merge = require('merge2');
var $ = require('gulp-load-plugins')();
var path = require('path');
var options = {};
options.themes = [
'default',
'rockStar',
'oneMoreTheme'
];
// we extract the task itself to a new function
// this allows us to reuse it
var styleTask = function(themeName) {
return gulp.src('src/themes/' + themeName + '/**/*.scss')
.pipe($.concat('styles.scss'))
.pipe($.sass())
.pipe(gulp.dest('dist/themes/' + themeName + '/'));
}
// we adapt the style task to use that function
// please note that I switched _.each for merge
// this allows you to work with streams!
gulp.task('styles', function() {
var tasks = themes.map(styleTask);
return merge(tasks);
});
// here we set up a new watcher. Instead of running 'styles'
// we filter the theme directory from the file that has changed
// and run the styleTask function
gulp.task('default', function() {
var watcher = gulp.watch('src/themes/**/*.scss', function(e) {
var theme = path
.relative(__dirname, e.path)
.substr('src/themes/'.length)
.split('/')[0];
console.log('rebuilding ' + theme);
return styleTask('theme');
});
});
version 2
// same as above except the default task. we save the theme
// we want to build in a file
var singleTheme;
// and call the styleTask function should it be set
gulp.task('single-style', function(done) {
if(singleTheme) {
return styleTask(singleTheme);
} else {
done();
}
});
// here we have a watcher that calls single-style, but before calling
// it gets the right themename.
gulp.task('default', function() {
var watcher = gulp.watch('src/themes/**/*.scss', 'single-style');
watcher.on('change', function(e) {
singleTheme = path
.relative(__dirname, e.path)
.substr('src/themes/'.length)
.split('/')[0];
console.log('rebuilding ' + theme);
})
})
I hope this helped.
Update If you want to run more tasks and have a status call on if they ended, please go for version 2. Than you can add all the tasks you want to run in
gulp.task('default', function() {
var watcher = gulp.watch('src/themes/**/*.scss', ['single-style', 'another-task']);
watcher.on('change', function(e) {
singleTheme = path
.relative(__dirname, e.path)
.substr('src/themes/'.length)
.split('/')[0];
console.log('rebuilding ' + theme);
})
})
Instead of gulp.run you can use gulp.start.