0.1.6 • Published 10 years ago

supershell v0.1.6

Weekly downloads
82
License
-
Repository
github
Last release
10 years ago

SuperShell

Simple utility to easily manipulate shell commands. The most important thing about this API is that is fully asynchronous and stream/events based.

It's very easy-to-use, but it also provides some powerful features.

// it can be used very easily:
var cmd = sh('ls | wc -l');

// or if you prefere
var cmd = sh('ls').pipe('wc -l')

// and you can get the output through events:
cmd.on('finish', function (output, code) {
  console.log(code ? 'failed' : 'succeed', 'with output:', output);
});

Installation

$ npm install supershell

Command

The main supershell's feature is the command utiliy. It allow to easily chain commands though a simple asynchronous and chained js API.

Methods

MethodDescription
pipepipe the output of the command into another one, or into a parser
andexecute the given command if the previous one succeed
orexecute the given command if the previous one failed
thenexecute the given command anyway

Events

NameDescription
finishthe command is finished
successthe command is finished successfuly
failthe command has failed

Examples

var sh = require('supershell');

sh('ls', ['-l'])

  // if succeed then
  .and('echo', ['ls succeed!'])

  // trim the output
  .pipe(sh.parsers.trim())

  // catch the output on success
  .on('success', function (output, cmd) {
    console.log("command:", cmd);
    console.log("output:", output);
  });

// Test with errors
sh('ls file_not_found')

  .pipe(sh.parsers.trim())

  // wont be triggered
  .on('success', function (output) {
    console.log('never called');
  })

  // will be triggered
  .on('fail', function (output, name, code) {
    console.log('fail: ', name, code, output);
  })

  // will be triggered
  .on('finish', function (output, name, code) {
    console.log('finish: ', name, code, output);
  })

  .or(new sh.Command('ls').pipe(sh.parsers.list()))

  .on('success', function (output) {
    console.log('files: ', output);
  });

Create a parser

You can easily create your own parser as a closure or a simple function callback:

// create parsers

function upperCase(output) {
  return output.toUpperCase();
}

function replace(source, dest) {
  return function (output) {
    return output.replace(source, dest);
  }
}

// use it
var sh = require('supershell');

sh('ls')
  .pipe(upperCase)
  .pipe(replace('a', 'b'))
  .on('success', function (output) {
    console.log(output);
  });

History

An history of your commands will be saved within supershell module. You can access it through the config that way:

var sh = require('supershell');

sh('ls').on('success', function () {
  // print the current history
  console.log(sh.config.history);
  // clean the history
  console.log(sh.config.cleanHistory());
});

Alias

SuperShell provides a tool to register and use aliases on shell commands.

var sh = require('supershell');

// register your alias via `setAlias` method
sh.config.setAlias('lsHidden', 'ls', ['-a']);
sh.config.setAlias('lsFull', sh.cmd('ls', ['-l']));

// then use it like any other command
sh('lsHidden').on('success', function (output) {
    console.assert(output.indexOf('..') !== -1);
});

// or
sh('lsFull').pipe(sh.parsers.list()).on('success', function (output) {
  console.log(output);
});

// even add custom parameters
sh('lsHidden', ['-l']).on('success', function (output) {
    console.assert(output.indexOf('..') !== -1);
});

Context

A Context instance is an object which has its own scope and commands. It's useful if you want to gather commands which are related. It also allow to easily refresh scope from commands or execute commands under specific conditions (for a real use case, look at lib/context/git/index.js).

Simple example:

var sh = require('supershell');

// Define your context
var workspace = new sh.Context();

workspace.scope.path = '$HOME/Work';
workspace.scope.list = [];

workspace.command('init', function (e) {
  sh('mkdir', ['-p', this.scope.path])
    .on('success', function () {
      e.emit('success');
    })
    .on('fail', function (output) {
      e.emit('fail', output);
    });
});

workspace.command('create', function (e, name) {
  var _this = this;
  if (this.scope.list.indexOf(name) !== -1)
    e.emit('fail', 'Project ' + name + 'already exists.', 'create');
  else {
    sh('mkdir', [this.scope.path + '/' + name])
      .on('success', function (output) {
        e.emit('success', output);
      })
      .on('fail', function (output) {
        e.emit('fail', output);
      });
  }
});

workspace.command('list', function (e) {
  var _this = this;
  sh('ls', [_this.scope.path])
    .pipe(sh.parsers.trim())
    .pipe(sh.parsers.list())
    .on('success', function (output) {
      _this.scope.list = output;
      e.emit('success');
    })
    .on('fail', function (output) {
      e.emit('fail', output);
    });
});

// Use it:

workspace.on('refresh', function () {
  console.log('Refresh workspace...');
});

workspace.refresh(0.5, 'list');

workspace.exec('create', 'test')
  .on('success', function () {
    console.log('Create ok.');
  })
  .on('fail', function (output) {
    console.log('failed: ' + output);
  });

TODO

  • handle pipes in json serialization
  • on progress event.
  • globing
  • env
  • scripts
  • redirection << >> < >
  • cd command
  • exists command
0.1.6

10 years ago

0.1.5

10 years ago

0.1.4

10 years ago

0.1.3

10 years ago

0.1.2

10 years ago

0.1.1

10 years ago

0.1.0

10 years ago

0.0.9

10 years ago

0.0.8

10 years ago

0.0.7

10 years ago

0.0.6

10 years ago

0.0.5

10 years ago

0.0.4

10 years ago

0.0.3

10 years ago

0.0.2

10 years ago

0.0.1

10 years ago