npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

command-queue

v0.1.5

Published

A flexible API for executing groups of commands synchronously or asynchronously.

Downloads

16

Readme

CommandQueue

CommandQueue provides a flexible API for executing groups of commands synchronously or asynchronously. It was originally created to provide an alternative to using the scripts field in package.json for executing commands. By using CommandQueue, you can easily execute commands from a JavaScript file instead, which is better suited for managing complex build steps.

Table of Contents

Features

  • Supports different combinations of synchronous and asynchronous command execution.
  • Allows full customization of child_process parameters for executing a command.

Installation

To install the package:

npm install command-queue

To require the package:

var CommandQueue = require("command-queue");

Usage

Synchronous Execution

To specify the commands to run synchronously, use the .sync() method:

// Update the PATH if necessary.
process.env.PATH += ':./node_modules/.bin';

new CommandQueue()
    .sync(
        'rimraf dist/',
        'mkdir dist/'
    )
    .run();

Asynchronous Execution

To specify the commands to run asynchronously, use the .async() method:

new CommandQueue()
    .async(
        'karma start',
        'webpack-dev-server --hot'
    )
    .run();

Parallel Execution

To specify the commands to run in parallel, use the .parallel() method:

new CommandQueue()
    .parallel(
        'karma start',
        'webpack-dev-server --hot'
    )
    .run();

Parallel execution runs the commands asynchronously, but if one fails, the remaining commands are terminated using SIGTERM.

Note: This functionality is inspired by Parallel Shell.

Nested Execution

CommandQueue itself can be used as a command:

new CommandQueue()
    .sync(
        'command B1',
        new CommandQueue().async(
            'command B2a',
            'command B2b',
            'command B2c' 
        ),
        'command B3'
    )
    .run();

Batched Execution

Each call to an .async(), .sync(), or .parallel() method creates a new batch of commands. CommandQueue waits for the current batch of commands to complete before executing the next batch of commands.

In the following example, CommandQueue waits for the A commands to complete before executing the B commands, and waits for the B commands to complete before executing the C commands.

new CommandQueue()
    .async(
        'command A1',
        'command A2',
        'command A3'
    )
    .parallel(
        'command B1',
        'command B2',
        'command B3'
    )
    .sync(
        'command C1',
        'command C2',
        'command C3'
    )
    .run();

Run

To start command execution, use the .run() method. The .run() method returns a deferred promise which is resolved when the commands have completed or a command has terminated with an error.

new CommandQueue()
    .sync('command 1')
    .run()
    .then(
        function() {
            console.log('done');
        },
        function() {
            console.log('a command failed');
        }
    );

Close

To terminate currently running commands, use the .close() method. It will send a SIGTERM to those commands.

var queue = new CommandQueue();

queue
    .async(
        'command 1',
        'command 2',
        'command 3'
    )
    .run()
    .then(    
        function() {
            console.log('success');
        },
        function() {
            console.log('failure');
            
            // Close any remaining commands.
            queue.close();
        }
    );

Posix or Win32

By default CommandQueue will detect the current platform and use the appropriate shell for executing the commands. However, you can force CommandQueue to use a specific platform's shell by using either the .posix() method, or the .win32() method.

new CommandQueue()
    .posix()
    .sync(...)    
    .run();    
new CommandQueue()
    .win32()
    .sync(...)    
    .run();    

Run Command Customization

To customize how a command is run, replace or override the CommandQueue.prototype.runCommand() method.

Here is the default method:

/*
 * Runs a command. This function is intended to be user replaceable
 * to allow customization of the child creation process.
 *
 * @param {string} cmd The user provided command to run.
 * @param {string} shell The shell commmand.
 * @param {string} shellFlag The shell flag.
 * @param {'sync'|'async'|'parallel'} runType
 * @returns {object} The child process.
 */
CommandQueue.prototype.runCommand = function(cmd, shell, shellFlag, runType) {
    var args = [shellFlag, cmd];

    var childProcess = spawn(shell, args, {
        cwd: process.cwd,
        env: process.env,
        stdio: ['pipe', process.stdout, process.stderr]
    });

    return childProcess;
};

By customizing the runCommand() method, you can also change the types of user arguments that can be passed into the .async(), .sync(), and .parallel() methods.

The following example shows how the runCommand() method is changed to accept a command that is an object rather than a string, and how the .sync() method can now be passed such an object.

var queue = new CommandQueue();

queue.runCommand = function(cmd, shell, shellFlag, runType) {
    console.log(runType + ':' + cmd.message);
    
    var args = [shellFlag, cmd.nodeCmd];
    
    var childProcess =  spawn(shell, args, ...);
    
    ...
};

queue.sync({
    message: 'hello',
    nodeCmd: 'node foobar.js'
});

queue.run();