Search code examples
javascriptecmascript-6gulp

I am trying to transfer the value from one task to another from callback with gulp 4, but have error


Im trying to create git deploy, with gulp 4. But gulp 4 gives an error, and recommends using gulp series. How i can using gulp.series, if i need to get the value from the function response?

In example, im using plugin gulp-confirm. In order for the user to enter the commit text. U can see this in .pipe(confirm({ ... that function return "answer" in property "proceed". That answer must be in ".pipe(git.commit(answer))", how i can do that guys? Im not best in es6...

// deploy system

gulp.task('set-prod-env', function (done) {
  process.env.NODE_ENV = 'production';
  done();
});


function gitCommit() {
  return new Promise(function(resolve, reject) {
    gulp.src('config.rb')
      .pipe(confirm({
        // Static text.
        question: 'Pls write commit text',
        proceed: function(answer) {
          return gulp.src(' ')
            .pipe(git.add({args: '--all'}))
            .pipe(git.commit(answer));
        }
      }))
      .pipe(gulp.dest('./'));
      resolve();
  })
}

function gitPush(done) {
  git.push('origin', 'dev', function (err) {
    if (err) throw err;
  });
  done();
}

gulp.task('deploy', gulp.series('set-prod-env', 'build', gitCommit, gitPush));

Now code is work, but with error, maybe someone can show better example, with Gulp 4, gulp 4 is different form gulp 3.


Solution

  • There are multiple problems with the code:

    1. You stream a single file into confirm and want to prompt for a text
    2. There are multiple issues with handling asynchronous returns / callbacks
    3. What you want to do is not really what you put into code

    So from my understanding, you want to have a commit task, that builds your project, then adds all files and then commits it, based on user input.

    A quick and dirty solution to this might be using readline-sync as you want to wait until commit is finished anyways.

    The following code should be more to the direction you want to go. It's untested though, as I didn't want to create a new repository to test this... :)

    I've added a few comments to show the intention and where I changed something where I saw issues with the original code. Hope this helps!

    // import `readlineSync` to simplify the command line prompt
    // I've never used it myself, there might be better ways to do this!
    const readlineSync = require('readline-sync');
    
    gulp.task('set-prod-env', function (done) {
      process.env.NODE_ENV = 'production';
      done();
      // Actually, you wouldn't need to have `done` as parameter and call it, as this function is synchronous. As soon as the function is at the end, it's done (if it did not return a promise, stream or wants to call the `done` callback.
    });
    
    // Using a single file to create a stream to use some prompt about a stream
    // is a very hacky way to do this and I wouldn't try to do that. To make
    // this simpler, I've changed it to synchronously wait for an answer here
    // before starting / returning the pipeline
    function gitCommit() {
      // this should block gulp completely until you answered the question
      const commitMessage = readlineSync.question('Please write your commit message');
      // this returns the actual action of `gitCommit`
      return gulp.src('.')
        .pipe(git.add({args: '--all'}))
        .pipe(git.commit(commitMessage));
    }
    
    // this function returned before `git.push` is really done.
    // It might not cause issues as "push" is the last action in your pipeline,
    // but you might run into issues if you want to do something AFTER `gitPush`.
    function gitPush(done) {
      git.push('origin', 'dev', function (err) {
        if (err) return done(err); // this will send the error to the caller (gulp), if there was one
        done(); // this should be called when `git.push` is done - i.e. inside of its callback
      });
      // you could simplify this to:
      // git.push('origin', 'dev', done);
    }
    
    gulp.task('deploy', gulp.series('set-prod-env', 'build', gitCommit, gitPush));