Search code examples
javascriptasynchronouscommand-line-interfaceyeoman

Running a script asynchronous


I am making a Yeoman generator to install CraftCMS with some custom settings and files preloaded for faster development.

I've got the to point where the script does a composer create-project craftcms/craft. For me, the next logical step would be to cd into the folder and run the craft installer craft install.

I just can't figure out how to let the lines of code run synchronous. At the moment it is running everything at the same time, which of course will run into errors.

This is my code:

'use strict';
const generator = require('yeoman-generator');
const chalk = require('chalk');
const yosay = require('yosay');
let init;
module.exports = class extends generator {
    async initializing() {
        this.log(yosay(chalk.blue('Hey!') + '\n' + 'Welcome to the Visited Installer!' + '\n\n' + 'Let\'s start a project together!'));
        init = await this.prompt([{
            type: 'input',
            name: 'name',
            message: 'What is the name of your new project?',
        }]);
        this.log(yosay(chalk.blue(init.name) + ', Great!' + '\n\n' + 'Let\'s start by downloading the latest version of CraftCMS.'));
    }
    install() {
        this.spawnCommand('composer', ['create-project', 'craftcms/craft', init.name]);
        this.log(yosay(chalk.blue('Done!') + '\n\n' + 'The next step is installing CraftCMS, Don\'t worry, I\'ve got this!'));
        this.spawnCommand('cd', [init.name]);
        this.spawnCommand('craft', ['install']);
    }
};

I have tried reading about asynchronous and synchronous programming in JS, but due to the fact that I am not a native english speaker, and the fact that I don't do a lot with JS (I mostly use PHP) make it hard for me to understand the logic behind it.

Update: I changed my post, I mixed up async and sync in my head. Problem remains that everything within my install() function runs at the same time: this.log does not wait for this.spawnCommand to be done downloading and setting up the files..


Solution

  • The problem is that spawnCommand is inherently asynchronous and it doesn't provide you with any means of waiting until the command finishes. It does not take a callback argument, nor does it return a promise.

    However there is another command: spawnCommandSync, which promises to do its work synchronously. Give it a try.