2017 © Pedro Peláez
 

library cmdwrap

Wraps command line access into a builder and provides argument escaping

image

treffynnon/cmdwrap

Wraps command line access into a builder and provides argument escaping

  • Thursday, December 15, 2016
  • by Treffynnon
  • Repository
  • 1 Watchers
  • 3 Stars
  • 18 Installations
  • PHP
  • 2 Dependents
  • 0 Suggesters
  • 0 Forks
  • 0 Open issues
  • 3 Versions
  • 0 % Grown

The README.md

Command Wrap

A PHP library to wrap the command line/terminal/shell. It provides a clean builder that escapes arguments and commands - you can extract a command string to run as you please or pass the builder to a runner., (*1)

Installation

composer require treffynnon/command-wrap

Example

$bld = new Builder();
$bld->addEnvVar('JAVA_BIN', '/usr/bin/java')
    ->addEnvVar('TMP_DIR', '/tmp')
    ->addCommand('foo')
    ->addFlag('f')
    ->addFlag('t', 'xml')
    ->addCommand('src/')
    ->addArgument('verbose')
    ->addArgument('results-log', '/tmp/results.log')
    ->addRaw('> /dev/null 2>&1');
$sp = new SymfonyProcess();
$response = $sp->run($bld);
// JAVA_BIN='/usr/bin/java' TMP_DIR='/tmp' foo -f -t='xml' src/ --verbose --results-log='/tmp/results.log' > /dev/null 2>&1

Using a callback to process output

Each line of the command's output can be processed by a callback/anonymous/lambda function. You can of course pass in a closure too!, (*2)

$bld = new Builder();
$bld->addEnvVar('JAVA_BIN', '/usr/bin/java')
    ->addEnvVar('TMP_DIR', '/tmp')
    ->addCommand('foo')
    ->addFlag('f')
    ->addFlag('t', 'xml')
    ->addCommand('src/')
    ->addArgument('verbose')
    ->addArgument('results-log', '/tmp/results.log')
    ->addRaw('> /dev/null 2>&1');
$sp = new SymfonyProcess();
$response = $sp->run($bld, function ($line) {
    return str_replace("\t", '    ', $line);
});
// JAVA_BIN='/usr/bin/java' TMP_DIR='/tmp' foo -f -t='xml' src/ --verbose --results-log='/tmp/results.log' > /dev/null 2>&1

This would replace all tabs with four (4) spaces in each line of output from the command. Note that the new value must be returned from your lambda., (*3)

You can then get the output in the usual way by calling $response->getOutput()., (*4)

If you want to have updates in real time from long running command then you need to use the SymfonyProcess runner and log/echo from your custom callback function., (*5)

$response = $sp->run($bld, function ($line) use ($logger) {
    $logger->push("New line added: $line");
    return str_replace("\t", '    ', $line);
});

Getting a command as a string

$bld = new Builder();
$bld->addEnvVar('JAVA_BIN', '/usr/bin/java')
    ->addEnvVar('TMP_DIR', '/tmp')
    ->addCommand('hint&&hint')
    ->addCommand('foo')
    ->addFlag('f')
    ->addFlag('t', 'xml')
    ->addCommand('src/')
    ->addArgument('verbose')
    ->addArgument('results-log', '/tmp/results.log')
    ->addRaw('> /dev/null 2>&1');
$cmd = $bld->getCommandAssembler()
           ->getCommandString();
// JAVA_BIN='/usr/bin/java' TMP_DIR='/tmp' foo -f -t='xml' src/ --verbose --results-log='/tmp/results.log' > /dev/null 2>&1

Available command line types

Type Builder method Example final output
Command addCommand('ls'); ls
Flag addFlag('-t'); -t
Flag addFlag('-t', '/tmp'); -t='/tmp'
Argument addArgument('results'); --results
Argument addArgument('results', '/tmp/results.log'); --results='/tmp/results.log'
Parameter addParameter('parameter'); 'parameter'
EnvVar addEnvVar('MY_ENV_VAR', 'value'); MY_ENV_VAR='value'
Raw addRaw('> /dev/null 2>&1') > /dev/null 2>&1

Note: As the name implies Raw does not perform any escaping - use with appropriate caution., (*6)

Available runners

  • Symfony Process (Treffynnon\CommandWrap\Runners\SymfonyProcess) recommended
  • exec() (Treffynnon\CommandWrap\Runners\Exec)
  • passthru() (Treffynnon\CommandWrap\Runners\Passthru)
  • system() (Treffynnon\CommandWrap\Runners\System)

By implementing Treffynnon\CommandWrap\Runners\RunnerInterface you can also provide your own custom runner., (*7)

When a command is executed via a runner it will return an instance of \Treffynnon\CommandWrap\Response containing the response from STDOUT and STDERR if available., (*8)

Command combinators

POSIX commands can be combined with a few characters such as:, (*9)

  • && (Treffynnon\CommandWrap\Combinators\AndAnd)
  • | (Treffynnon\CommandWrap\Combinators\Pipe)
  • ; (Treffynnon\CommandWrap\Combinators\Semicolon)

These have been wrapped up into objects that you can use to combine commands/builders. You can also combine combinators too!, (*10)

$combinator = new AndAnd(
    $builder,
    $builder2
);
$combinator2 = new Semicolon(
    $combinator,
    $builder3,
    $builder4
);

These can then be passed to a runner just like any builder can be:, (*11)

$Exec = new Exec();
$Exec->run($combinator2);

Command assemblers

When a command is being converted into a string an assembler will be used by default it will use the ChronoAssembler, but you can also use OrderedAssembler or even provide your own by implementing AssemblerInterface., (*12)

ChronoAssembler compiles a command in the order it was added to the builder (chronologically). OrderedAssembler combines into a specified order - see the class for details., (*13)

To specify the assembler to use you provide an instance of it to the Builder object., (*14)

$bld = new Builder(new OrderedAssembler());
$bld->addEnvVar('JAVA_BIN', '/usr/bin/java')
    ->addCommand('hint&&hint')
    ->addCommand('foo')
    ->addFlag('f')
    ->addFlag('t', 'xml')
    ->addCommand('src/')
    ->addArgument('verbose')
    ->addArgument('results-log', '/tmp/results.log');

Custom command collection

It is also possible to provide your own command collection class as the second parameter to your Builder instance., (*15)

$bld = new Builder(new ChronoAssembler(), new MyCommandCollection());
$bld->addEnvVar('JAVA_BIN', '/usr/bin/java')
    ->addCommand('hint&&hint')
    ->addCommand('foo')
    ->addFlag('f')
    ->addFlag('t', 'xml')
    ->addCommand('src/')
    ->addArgument('verbose')
    ->addArgument('results-log', '/tmp/results.log');

Again implement the CommandCollectionInterface., (*16)

Tests

Unit testing is completed with phpspec, integration testing with phpunit and the code is also linted with php -l, phpcs and phpcpd. To run the tests you can use the following composer command:, (*17)

composer test

Licence

BSD 3 clause licence - see LICENCE.md., (*18)

The Versions

15/12 2016

dev-dev

dev-dev https://github.com/treffynnon/command-wrap

Wraps command line access into a builder and provides argument escaping

  Sources   Download

BSD

The Requires

 

The Development Requires

command console wrapper command line shell

13/12 2016

dev-master

9999999-dev https://github.com/treffynnon/command-wrap

Wraps command line access into a builder and provides argument escaping

  Sources   Download

BSD

The Requires

 

The Development Requires

command console wrapper command line shell

14/03 2016

v1.0.0

1.0.0.0 https://github.com/treffynnon/CmdWrap

Wraps command line access into a builder and provides argument escaping

  Sources   Download

BSD

The Requires

 

The Development Requires

command console wrapper command line shell