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

@schummar/runp

v2.0.3

Published

Neat parallel task execution

Downloads

144

Readme

runp - Neat parallel task execution

Features

  • Run commands in parallel, in series or any combination
  • Reference npm scripts by name with glob support
  • Command outputs will be separated in their own blocks instead of all mixed together
  • Nested runp calls will be merged with indented sub commands
  • CLI and type-safe Node API

Try it on StackBlitz

Getting started

Install

npm i @schummar/runp

Execute commands

runp clean :p "build:*" :s "rm -rf .cache"

Assuming the following package.json:

{
  "scripts": {
    "clean": "rimraf dist",
    "build:esm": "some build command",
    "build:cjs": "another build command",
    "build:type": "tsc --emitDeclarationOnly"
  }
}

Each parameter can be a program, npm script, a flag or a switch. Arguments for programs and scripts can be added by encapsulating them in quotes.

  • clean executes npm run clean

  • :p for "parallel": remaining commands will be executed after the previous and in parallel

  • "build:*" executes all script matching this glob (see minimatch)
    Mind the quotes, otherwise your shell will try to resolve the wildcard!

  • :s for "serial": remaining commands will be execute after the previous and in series

  • "rm -rf .cache" deletes the .cache folder

Options

❯ runp --help
runp v1.5.0

Usage:
  runp [flags...] <commands...>

Flags:
  -f, --forever                       Task will run forever. It won't display a spinner but a different symbol instead
  -h, --help                          Show help
  -k, --keep-output                   Keep output of successful commands visible
  -n, --output-length <number>        Maximum number of lines for each command output (default: 10)
      --version                       Show version

Options can either be used as flags (prefix "-") or switches (prefix ":"). Flags generally apply to all commands while switches can be used to change behavior midway for the remaining commands.

Option: Forever

Flags -f, --forever apply to all commands

Switches :f, :f=false apply for all remaining commands

You might run commands in parallel that are supposed to run indefinitely, like a backend server and a frontend dev server. In this case instead of a spinner, runp can display an arrow icons instead. The effect is purely cosmetic:

Option: Keep output

Flag -k, --keep-output apply to all commands

Switches :k, :k=false apply to remaining commands

Usually a command's output will disappear after is has successfully executed. When --keep-output is set, it will remain visible.

Option: Output length

Flags -n <number>, --output-length <number> apply to all commands

Switches :n=<number> apply to remaining commands

Defines how many lines of output will be visible at maximum for each command.

Option: Parallel and serial execution

Switches :p, :s apply to remaining commands

Commands after the :p switch will first wait for all commands before the switch to finish, then execute in parallel.

Commands after the :s switch will first wait for all commands before the switch to finish, then execute in series.

Both apply to all commands until another :p or :s appears.

It's possible to have multiple :p switches in succession, forming multiple parallel blocks. For example runp :p task1 task2 :p task3 task4 will execute first task1 and task2 in parallel, then task3 and task4 in parallel.

Before the first :p or :s switch appears, all commands will be executed in parallel by default.

Combining switches

Flags and switches can be combined. E.g. -fk or :pfn=10k=false

Error handling

When an error occurs the command will be marked with a red x-symbol and the command output will remain visible. Any parallel tasks are allowed to continue but dependent commands will not be executed.

Nested execution

When runp is executed as child process of another runp instance, it delegates its tasks to the parent instance. Commands will be shown as child commands to the parent instance's command.

That is useful for example for composing npm scripts. Say we have the following package.json:

{
  "scripts": {
    "lint": "eslint",
    "clean": "rimraf dist",
    "build": "build:*",
    "build:esm": "some build command",
    "build:cjs": "another build command",
    "build:type": "tsc --emitDeclarationOnly",
    "prepublishOnly": "runp :s lint build"
  }
}

Running npm publish will now execute the prepublishOnly script, which in turn has runp execute the lint and build scripts. The build script executes another instance of runp with its build:* commands. The output however looks seamless:

Node API

import { runp } from '@schummar/runp';

runp({
  keepOutput: true,
  outputLength: 10,

  commands: [
    {
      cmd: 'clean',
      name: 'Clean',
      keepOutput: false,
    },

    ':p',

    {
      cmd: 'build:*',
      cwd: 'src',
    },

    ':s',

    {
      cmd: 'rm',
      args: ['-rf', '.cache'],
    },
  ],
});

The Node API allows running runp programmatically with all the same options, plus a bit more fine grained control.

commands.cmd

The executable or npm script to run.

commands.args

Arguments to pass to executable or npm script.

commands.cwd

Execute command in different working directory

commands.id

Give a task an id that can be referenced as dependency.

commands.depdendsOn

Command will only start once all dependencies have finished.