Determining if Gulp task called from another task - gulp

Is there a way to find out if a task been invoked directly or from another task?
runSequence = require 'run-sequence'
gulp.task 'build', ->
....
gulp.task 'run', ->
runSequence 'build', -> gulp.start('server')
I need an if case in build task that says:
if it was called directly - (gulp build) then do something;
or if it was invoked from run task then do something else

This might be an X/Y problem. What are you actually trying to accomplish?
But to answer the question; I think the only way is to look at the call stack trace and make sure only Gulp touches the task. I wrote a function that finds who orchestrated the task. You can just put the function inline with your gulpfile.js and use it like boolean.
The following code relies on npm parse-stack so make sure to npm install parse-stack
Usage: if(wasGulpTaskCalledDirectly()) { /*...*/ }
function wasGulpTaskCalledDirectly()
{
var parseStack = require("parse-stack");
var stack = parseStack(new Error());
// Find the index in the call stack where the task was started
var stackTaskStartIndex = -1;
for(var i = 0; i < stack.length; i++)
{
if(stack[i].name == 'Gulp.Orchestrator.start')
{
stackTaskStartIndex = i;
break;
}
}
// Once we find where the orchestrator started the task
// Find who called the orchestrator (one level up)
var taskStarterIndex = stackTaskStartIndex+1;
var isValidIndex = taskStarterIndex > 0 && taskStarterIndex < stack.length;
if(isValidIndex && /gulp\.js$/.test((stack[taskStarterIndex].filepath || "")))
{
return true;
}
return false;
}
You can find my full gulpfile.js used for testing below:
// This is a test for this SE question: http://stackoverflow.com/q/25928170/796832
// Figure out how to detect `gulp` vs `gulp build`
// Include gulp
var gulp = require('gulp');
var runSequence = require('run-sequence');
// Add this in from the above code block in the answer
//function wasGulpTaskCalledDirectly()
// ...
gulp.task('build', function() {
//console.log(wasGulpTaskCalledDirectly());
if(wasGulpTaskCalledDirectly())
{
// Do stuff here
}
else
{
// Do other stuff here
}
return gulp.src('./index.html', {base: './'})
.pipe(gulp.dest('./dist'));
});
// This does nothing
gulp.task('start-server', function() {
return gulp.src('./index.html', {base: './'});
});
// Default Task
gulp.task('default', function(callback) {
runSequence('build',
['start-server'],
callback
);
});

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;

elixir.queueTask is undefined

I am fairly new to Laravel 5.2 and Elixir/gulp but I have an issue with queueTask being undefined when I run gulp from the command line.
What I want to do is to extend elixir to delete some files (according to all the documentation I can find, that's what I need to do), so I have this:
var gulp = require('gulp');
var elixir = require("laravel-elixir");
var del = require('del');
elixir.extend("remove", function(path) {
gulp.task("removeFiles", function() {
return del(path);
});
return this.queueTask("removeFiles");
});
and then in my mix I have:
.remove([
"path/to/file1/filename1",
"path/to/file2/filename2"
])
When I run gulp in the command line, I get:
return this.queueTask("removeFiles");
^
TypeError: undefined is not a function
can anyone throw some light on what I am doing wrong please?
API has changed again since Elixir v3.0.0. So for v4.0.0 you must do this:
var elixir = require('laravel-elixir');
var del = require('del');
var Task = elixir.Task;
elixir.extend('remove', function (path) {
new Task('remove', function () {
return del(path);
});
});
And then you can call it within your pipeline like this:
mix.remove([
"path/to/file1/filename1",
"path/to/file2/filename2"
]);
The difference seems to be calling elixir.extend as opposed to elixir.Task.extend. And then returning a new elixir.Task.
API was changed in Elixir v3.0.0.
You no longer need to call Gulp.task(). Elixir will handle that, instead you have to create a new Task.
var Elixir = require('laravel-elixir');
var del = require('del');
Elixir.Task.extend('remove', function (path) {
new Task('remove', function () {
return del(path);
});
});

Gulp and glob-stream task finishing too soon

I have a Gulp task that uses glob-stream to recursively loop through directories and files to perform a task, similar to below, but far more elaborate:
var gs = require('glob-stream');
var config = {
PATH: 'some/path/*.*'
}
function doSomething(filePath) {
var stream = gs.create(filePath);
// Do something
return gs.on('data', doSomething);
}
gulp.task('compile', function() {
var filePath = config.PATH;
return doSomething(filePath);
});
I can have the task achieve the results and compile what I need, but unfortunately Gulp believes the task has finished while it's still running, causing issues in my build process - How can I avoid this? I'm already using run-sequence but to no effect.
Why are you manually walking the directory tree with a recursive function? Why not just let glob-stream do the work for you? Then you only have to take care of the //Do something part:
var config = {
PATH: 'some/path/**' //glob pattern for all subfolder and files
};
function doSomething(filePath) {
//Do something
}
gulp.task('compile', function() {
var stream = gs.create(config.PATH);
stream.on('data', doSomething);
return stream;
});
gulp.task('secondTask', function() {
console.log('secondTask');
});
gulp.task('default', function() {
runSequence('compile', 'secondTask');
});
The some/path/** glob pattern creates a stream of all folders and files below some/path/, so you don't have to implement the recursive tree walk yourself.
Note that the compile task returns the stream. Otherwise gulp can't tell when the compile task has completed and starts running secondTask before compile has finished.

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.