8000 GitHub - testdouble/scripty at power-assert
[go: up one dir, main page]

Skip to content
This repository was archived by the owner on Mar 21, 2025. It is now read-only.

testdouble/scripty

 
 

Repository files navigation

scripty

Unix Build Status Windows Build Status npmjs

What is?

Using npm-scripts has become a popular way of maintaining the various build tasks needed to develop Node.js modules. People like npm-scripts because it's simple! This is a common refrain:

Don't bother with grunt, gulp, or broccoli, just add a little script to your package.json and run it with npm run name:of:script

Indeed, this is much simpler, but it can quickly become a mess. Take a look at what happened to our testdouble.js library's package.json. Using npm-scripts for everything is simple to start with, but it can't hope to guard against the complexity that naturally accumulates over the life of a project.

We wrote scripty to help us extract our npm scripts—particularly the gnarly ones—into their own files without changing the command we use to run them. To see how to do this yourself, read on!

Install

$ npm install --save-dev scripty

Usage

  1. From your module's root, create a scripts directory
  2. If you want to define an npm script named "foo:bar", write an executable file at scripts/foo/bar
  3. Feel a liberating breeze roll over your knuckles as your script is free to roam within its own file, beyond the stuffy confines of a quote-escaped string inside a pile of JSON
  4. Declare your "foo:bar" script in "scripts" in your package.json:
"scripts": {
  "foo:bar": "scripty"
}

From this point on, you can run npm run foo:bar and scripty will use npm's built-in npm_lifecycle_event environment variable to look up scripts/foo/bar and execute it for you.

This pattern is great for extracting scripts that are starting to become unwieldy inside your package.json, while still explicitly calling out the scripts that your package supports (though where to take that aspect from here is up for debate).

Advanced Usage

Ready to take things to the next level? Check this stuff out:

Passing command-line args

To pass command-line args when you're running an npm script, set them after -- and npm will forward them to your script (and scripty will do its part by forwarding them along).

For example, if you had a script in scripts/echo/hello:

#!/usr/bin/env sh

echo Hello, "$1"!

Then you can run npm run echo:hello -- WORLD and see your script print "Hello, WORLD!".

Batching "sub-scripts"

Let's say you have two test tasks in scripts/test/unit and scripts/test/integration:

"scripts": {
  "test:unit": "scripty",
  "test:integration": "scripty"
}

And you want npm test to simply run all of them, regardless of order. In that case, just add a "test" entry to your package.json like so:

"scripts": {
  "test:unit": "scripty",
  "test:integration": "scripty",
  "test": "scripty"

}

And from then on, running npm test will result in scripty running all the executable files it can find in scripts/test/*.

Defining an explicit parent script

Suppose in the example above, it becomes important for us to run our scripts in a particular order. Or, perhaps, when running npm test we need to do some other custom scripting as well. Fear, not!

Without changing the JSON from the previous example:

"scripts": {
  "test:unit": "scripty",
  "test:integration": "scripty",
  "test": "scripty"

}

Defining a script named scripts/test/index will cause scripty to only run that index script, as opposed to globbing for all the scripts it finds in scripts/test/*.

Windows support

Windows support is provided by Scripty in two ways:

  1. If everything in your scripts directory can be safely executed by Windows, no action is needed (this is only likely if you don't have collaborators on Unix-like platforms)
  2. If your project needs to run scripts in both Windows & Unix, then you may define a scripts-win/ directory with a symmetrical set of scripts to whatever Unix scripts might be found in scripts/

To illustrate the above, suppose you have this bash script configured as "test/unit" in your package.json file and this bash script defined in scripts/test/unit:

#!/usr/bin/env bash

teenytest --helper test/unit-helper.js "lib/**/*.test.js"

In order to add Windows support, you could define scripts-win/test/unit.cmd with this script:

@ECHO OFF

teenytest --helper test\unit-helper.js "lib\**\*.test.js"

With a configuration like the above, if npm run test:unit is run from a Unix platform, the initial bash script in scripts/ will run. If the same CLI command is run from Windows, however, the batch script in scripts-win/ will be run.

Likely questions

  • Is this black magic? - Nope! For once, instilling some convention didn't require any clever metaprogramming, just environment variables npm already sets; try running printenv from a script some time!
  • Why isn't my script executing? - If your script isn't executing, make sure it's executable! In UNIX, this can be accomplished by running chmod +x scripts/path/to/my/script

About

Because no one should be shell-scripting inside a JSON file.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors 17

Languages

0