UNPKG

runok

Version:

NPM scripts on steroids! Replace your scripts with pure JS

548 lines (364 loc) • 11.8 kB
# šŸŒ… runok šŸ„‹ No BASH-fu is required anymore! ## šŸ’” Write your shell scripts in JavaScript! * * * <p align="center"> <img src="https://user-images.githubusercontent.com/220264/95273180-0a1a5780-084b-11eb-95ae-73e5f4af3ebb.png" align="center" /> </p> * * * Everyone ā¤ļø npm scripts. However, when you need to use conditionals, loops, regexp and parsers in yout scripts, you end up writing JavaScript. **runok gives you a tool to transform your JavaScript scripts into CLI commands**. Each exported function will be a command which can be executed from CLI. You can use full power of JavaScript & bundled tasks like: - exec - git - npmRun - npx - ...and others ## šŸŽ Showcase Write a CommonJS module that exports commands per function. - Each argument of function will be an argument of a command - If you provide `options` argument, with default value of an object, this will declate options. ```js #!/usr/bin/env node const { tasks: { git, exec, npx }, runok } = require('runok'); module.exports = { async deploy(env = 'prod') { await this.test(); await git(cmd => { cmd.add('-A'); cmd.commit('releasing'); cmd.pull(); cmd.push(); }); await exec(`ansible-playbook deploy.yml -i hosts ${env}`); } async test() { await npx('mocha'); }, } if (require.main === module) runok(module.exports); ``` - Run `./runok` to list all available commands - Run `./runok deploy` to run a deploy script - Run `./runok deploy staging` to run a deploy script to staging ## šŸš€ Installation npm i runok --save Create a new `runok` scripts file: npx runok init Each exported function of this file will be command. ## ⌨ Usage When file is created execute runok script to see all available commands: ./runok.js Edit `runok.js` file. 1. Add async function to `module.exports` 2. Name a function, function name will be transformed for CLI format: myFunctionName => my:function-name 3. Define function parameters: - function arguments will be used as command arguments - the last argument with object type will is set of options: ```js // function definition: async runMe(arg1, arg1, { print: false, retries: 3 }) ``` šŸ‘‡ ```bash ./runok.js run:me value1 value2 --print --retries 1 ``` 4. Add a description of a command as the first comment in a function ```js async runMe() { // executes very important command } ``` šŸ‘‡ ```bash āžœ ./runok.js Usage: <command> [options] Options: -V, --version output the version number -h, --help output usage information Commands: run:me executes very important command ``` 5. Import required [tasks](#tasks) from `runok` package. 6. Implement your script! ## Export to NPM Scripts Export your runok scripts into your current package.json: ./runok export:npm ## 🧰 Tasks Runok has a set of built-in tasks. They can be imported in runio script via `tasks` property of `runok`: ```js const { tasks: { exec, writeToFile, npm } } = require('runok'); ``` ### Tasks API <!-- Generated by documentation.js. Update this documentation by updating the source code. --> ##### Table of Contents - [npmRun](#npmrun) - [Parameters](#parameters) - [npx](#npx) - [Parameters](#parameters-1) - [copy](#copy) - [Parameters](#parameters-2) - [git](#git) - [Commands API](#commands-api) - [Parameters](#parameters-3) - [exec](#exec) - [Parameters](#parameters-4) - [writeToFile](#writetofile) - [Config API](#config-api) - [Parameters](#parameters-5) - [GitConfig](#gitconfig) - [tag](#tag) - [Parameters](#parameters-6) - [commit](#commit) - [Parameters](#parameters-7) - [pull](#pull) - [Parameters](#parameters-8) - [init](#init) - [add](#add) - [Parameters](#parameters-9) - [clone](#clone) - [Parameters](#parameters-10) - [branch](#branch) - [Parameters](#parameters-11) - [checkout](#checkout) - [Parameters](#parameters-12) #### npmRun Executes npm script ```js await npmRun('deploy'); ``` ##### Parameters - `command` - `config` **ExecConfig** Returns **[Promise](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)&lt;Result>** #### npx Executes npx script ```js await npx('create-codeceptjs .'); ``` ##### Parameters - `command` - `config` **ExecConfig** Returns **[Promise](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)&lt;Result>** #### copy Copies file or directory. copySync from 'fs-extra' is used. ```js copy('src/', 'dst/'); ``` ##### Parameters - `from` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** - `to` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** - `options` **[object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)?** #### git Provides flexible interface to running multiple git commands: ```js await git(cmd => { cmd.pull(); cmd.commit('-m updated'); cmd.push(); }) ``` ##### Commands API - `cmd.init` - `cmd.tag` - `cmd.branch` - `cmd.commit` - `cmd.pull` - `cmd.push` - `cmd.add` - `cmd.clone` - `cmd.cloneShallow` ##### Parameters - `configFn` **gitConfigType** Returns **[Promise](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)&lt;Result>** #### exec Executes shell command and returns a promise. ```js await exec('ls -ll'); ``` A second parameter can be used to pass in [ExecOptions](https://nodejs.org/api/child_process.html#child_process_child_process_exec_command_options_callback) from "child_process" module: ```js await exec('rails s', { env: { RAILS_ENV: 'production' } }) ``` To hide output pass in `output: false`: ```js await exec('docker build', { output: false }); ``` ##### Parameters - `command` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** - `config` **execConfigType?** Returns **[Promise](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)&lt;Result>** #### writeToFile Writes a data to file. Takes file name as first argument and config function as second. ```js writeToFile('blog-post.md', cfg => { cfg.line('---'); cfg.line('title: My blogpost'); cfg.line('---'); cfg.line(); cfg.textFromFile('blog-post.txt'); cfg.text += '// copyright by me'; }); ``` A second argument is a config function that passes in an object for text manipulation. ##### Config API - `cfg.text` - string to be written to file - `cfg.textFromFile(file)` - loads a file and append its context to text - `cfg.line(text)` - appends a string to a text with "\\n" after - `cfg.append(text)` - appends a string to a text ##### Parameters - `file` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** - `configFn` **writeToFileCallback** Returns **Result** #### GitConfig **Extends TaskConfig** Git Config Class ##### tag ###### Parameters - `tag` ##### commit Commit params ###### Parameters - `message` (optional, default `''`) ##### pull ###### Parameters - `branch` (optional, default `''`) ##### init Initialize git repository ##### add ###### Parameters - `params` (optional, default `''`) ##### clone ###### Parameters - `url` - `path` ##### branch ###### Parameters - `command` ##### checkout ###### Parameters - `params` ### npmRun Executes npm script ```js await npmRun('deploy'); ``` #### Parameters - `command` - `config` **ExecConfig** Returns **[Promise](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)&lt;Result>** ### npx Executes npx script ```js await npx('create-codeceptjs .'); ``` #### Parameters - `command` - `config` **ExecConfig** Returns **[Promise](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)&lt;Result>** ### copy Copies file or directory. copySync from 'fs-extra' is used. ```js copy('src/', 'dst/'); ``` #### Parameters - `from` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** - `to` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** - `options` **[object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)?** ### writeToFile Writes a data to file. Takes file name as first argument and config function as second. ```js writeToFile('blog-post.md', cfg => { cfg.line('---'); cfg.line('title: My blogpost'); cfg.line('---'); cfg.line(); cfg.textFromFile('blog-post.txt'); cfg.text += '// copyright by me'; }); ``` A second argument is a config function that passes in an object for text manipulation. #### Config API - `cfg.text` - string to be written to file - `cfg.textFromFile(file)` - loads a file and append its context to text - `cfg.line(text)` - appends a string to a text with "\\n" after - `cfg.append(text)` - appends a string to a text #### Parameters - `file` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** - `configFn` **writeToFileCallback** Returns **Result** ## Adding Custom Tasks Tasks in runok use similar API and must follow conventions to match the output: - task must be a function - task must return [Result](https://github.com/runok-js/runok/blob/master/src/result.ts) instance (or Promise<Result>) - `Result.start` must be called in the beginning of a function, to create result object - `result.success` must be called on finish - `result.error(err)` must be called on failure ```js const { Result } = require('runok'); module.exports = myTask(arg1, options) { const result = Result.start("Task Name", `argument: ${arg1}`); try { // do something } catch (err) { return result.error(err); } return result.success(); } ``` ## Extending Custom Tasks If you want to extend current task, for instamce add custom wrapper to `exec` command you can check [npx](https://github.com/runok-js/runok/blob/master/src/tasks/npx.ts) command as an example. Similar way you can create a task for running Docker scripts: ```ts const { tasks: { exec } } = require('runok'); module.exports = (command, config) => { return exec(command, baseCfg => { baseCfg.TASK = 'docker'; // name of task baseCfg.prefix('docker'); // prefix to an executed command baseCfg.apply(config); }); } ``` ## Helpers <!-- Generated by documentation.js. Update this documentation by updating the source code. --> ### chdir Changes directory for commands executed in callback function. ```js // copy file in "base" directory chdir('./base', () => copy('a.txt', 'b.txt'))); ``` #### Parameters - `workDir` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** - `callback` **CallableFunction** Returns **[Promise](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)&lt;any>** ### stopOnFail Prevents execution of next tasks on fail: ```js stopOnFail(); ``` Ignore failures and continue: ```js stopOnFail(false); ``` #### Parameters - `stop` **[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** (optional, default `true`) ## Credits Created by Michael Bodnarchuk @davertmik. Inspired by [Robo PHP Task Runner](https://robo.li) ## LICENSE MIT