scripty

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

  • 所有者: testdouble/scripty
  • 平台:
  • 许可证: MIT License
  • 分类:
  • 主题:
  • 喜欢:
    0
      比较:

Github星跟踪图

scripty

Unix Build Status
Windows Build Status
npmjs
Test Coverage

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/*.

Running scripts in parallel

If you have a certain command that will match mutiple child scripts (for
instance, if npm run watch matches scripts/watch/js and
scripts/watch/css), then you can tell scripty to run the sub-scripts in
parallel by setting a SCRIPTY_PARALLEL env variable to 'true'. This may
be used to similar effect as the
npm-run-all module.

To illustrate, to run a scripty script in parallel, you might:

$ SCRIPTY_PARALLEL=true npm run watch

Or, if that particular script should always be run in parallel, you can set the
variable in your package.json:

"scripts": {
  "watch": "SCRIPTY_PARALLEL=true scripty"
}

Which will run any sub-scripts in parallel whenever you run npm run watch.

Finally, if you always want to run scripts in parallel, any option can be
set in your package.json under a "scripty" entry:

"scripty": {
  "parallel": true
}

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.

Specifying custom script directories

By default, scripty will search for scripts in scripts/ relative to your
module root (and if you're running windows, it'll check scripts-win/ first).
If you'd like to customize the base directories scripty uses to search for your
scripts, add a "scripty" object property to your package.json like so:

"scripty": {
  "path": "../core/scripts",
  "windowsPath": "../core/scripts-win"
}

You can configure either or both of "path" and "windowsPath" to custom
locations of your choosing. This may be handy in situations where multiple
projects share the same set of scripts.

Sharing scripts via node modules

You can configure scripty to include certain node modules into its executable
search space. This is beneficial if you would like to create a centralized place
for your scripts and then share them across multiple projects. To include modules
add a "scripty" object property, modules, to your package.json like so:

"scripty": {
  "modules": ["packageA", "packageB"]
}

Each node module must contain a scripts directory. Below is an example directory
structure:

root/
  scripts/
    foo
  node_modules/
    packageA/
      scripts/
        foo
        bar
    packageB/
      scripts/
        bar
        baz

In the above example the resolution of foo would resolve to root.scripts.foo. Local scripts
take priority over ones defined in modules. The resolution of bar would resolve to
root.node_modules.packageA.scripts.bar as packageA was the first module defined
in the scripty.modules config.

Dry runs

To perform a dry run of your scripts—something that's handy to check which
scripts will run from a particular command without actually executing potentially
destructive scripts, you can set an environment variable like so:

$ SCRIPTY_DRY_RUN=true npm run publish:danger:stuff

This will print the path and contents of each script the command would execute in
the order they would be executed if you were to run the command normally.

Worth mentioning, like all options this can be set in package.json under a
"scripty" entry:

"scripty": {
  "dryRun": true
}

Log output

Scripty is now quieter by default.
The output can be configured to a level of verbose, info, warn, or error.
Any logs equal to or higher than the setting are shown.
All logs are printed to STDERR (to aid in redirection and piping).

$ SCRIPTY_LOG_LEVEL=verbose npm run publish:danger:stuff

This will print the path and contents of each script the command executes.

If you always want scripty to run your scripts at a certain level,
you can set it in your package.json under a "scripty" entry:

"scripty": {
  "logLevel": "warn"
}

SCRIPTY_SILENT and SCRIPTY_QUIET are aliases for SCRIPTY_LOG_LEVEL=silent
SCRIPTY_VERBOSE is an alias for SCRIPTY_LOG_LEVEL=verbose
(also "silent": true, etc in package.json#scripty)

SCRIPTY_DRY_RUN=true implies log level info

Explicit setting from logLevel takes precedence; otherwise,
conflicting values between silent/verbose/dryRun will respect the highest level.
If no setting is provided, scripty will infer its log level from npm's log level.

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 (permissions will also be stored in git)

  • How can I expect my users to understand what this does? Documenting your
    project's use of scripty in the README is probably a good idea. Here's
    some copy pasta if you don't feel like writing it up yourself:

    npm scripts

    MyProject uses scripty to organize
    npm scripts. The scripts are defined in the scripts directory.
    In package.json you'll see the word scripty as opposed to the script
    content you'd expect. For more info, see
    scripty's GitHub.

    {{ insert table containing script names and what they do, e.g.
    this }}

Code of Conduct

This project follows Test Double's code of conduct for all community interactions, including (but not limited to) one-on-one communications, public posts/comments, code reviews, pull requests, and GitHub issues. If violations occur, Test Double will take any action they deem appropriate for the infraction, up to and including blocking a user from the organization's repositories.

主要指标

概览
名称与所有者testdouble/scripty
主编程语言JavaScript
编程语言JavaScript (语言数: 3)
平台
许可证MIT License
所有者活动
创建于2016-04-05 21:22:15
推送于2025-02-19 02:03:54
最后一次提交
发布数26
最新版本名称v3.0.0 (发布于 2025-02-18 20:59:39)
第一版名称v0.0.1 (发布于 )
用户参与
星数1k
关注者数57
派生数24
提交数293
已启用问题?
问题数54
打开的问题数21
拉请求数52
打开的拉请求数3
关闭的拉请求数12
项目设置
已启用Wiki?
已存档?
是复刻?
已锁定?
是镜像?
是私有?