Compare commits

..

No commits in common. "master" and "1.1.2" have entirely different histories.

9 changed files with 89 additions and 538 deletions

2
.gitattributes vendored
View file

@ -1,2 +0,0 @@
# Force LF
* text eol=lf

View file

@ -1,41 +0,0 @@
<?php
declare(strict_types=1);
return [
'type' => [
'lengthMin' => 3,
'lengthMax' => 8,
'acceptExtra' => false,
'values' => [
'feat',
'fix',
'docs',
'chore',
'test',
'refactor',
'revert',
'ci',
]
],
'scope' => [
'lengthMin' => 0,
'lengthMax' => 10,
'acceptExtra' => true,
'values' => [],
],
'description' => [
'lengthMin' => 1,
'lengthMax' => 47,
],
'subject' => [
'lengthMin' => 1,
'lengthMax' => 69,
],
'body' => [
'wrap' => 72,
],
'footer' => [
'wrap' => 72,
],
];

View file

@ -1,59 +0,0 @@
<?php
declare(strict_types=1);
$header = <<<EOF
This file is part of the "PHP Helpers: Command-line Functions" repository.
Copyright 2019-2021 Alannah Kearney <hi@alannahkearney.com>
For the full copyright and license information, please view the LICENCE
file that was distributed with this source code.
EOF;
return (new PhpCsFixer\Config())
->setUsingCache(true)
->setRiskyAllowed(true)
->setFinder(
(new PhpCsFixer\Finder())
->files()
->name('*.php')
->in(__DIR__)
->exclude(__DIR__.'/vendor')
)
->setRules([
'@PSR2' => true,
'@Symfony' => true,
'is_null' => true,
'blank_line_before_statement' => ['statements' => ['continue', 'declare', 'return', 'throw', 'try']],
'cast_spaces' => ['space' => 'single'],
'header_comment' => ['header' => $header],
'include' => true,
'class_attributes_separation' => ['elements' => ['const' => 'one', 'method' => 'one', 'property' => 'one']],
'no_blank_lines_after_class_opening' => true,
'no_blank_lines_after_phpdoc' => true,
'no_empty_statement' => true,
'no_extra_blank_lines' => true,
'no_leading_import_slash' => true,
'no_leading_namespace_whitespace' => true,
'no_trailing_comma_in_singleline_array' => true,
'no_unused_imports' => true,
'no_whitespace_in_blank_line' => true,
'object_operator_without_whitespace' => true,
'phpdoc_align' => true,
'phpdoc_indent' => true,
'phpdoc_no_access' => true,
'phpdoc_no_package' => true,
'phpdoc_order' => true,
'phpdoc_scalar' => true,
'phpdoc_trim' => true,
'phpdoc_types' => true,
'psr_autoloading' => true,
'array_syntax' => ['syntax' => 'short'],
'declare_strict_types' => true,
'single_blank_line_before_namespace' => true,
'standardize_not_equals' => true,
'ternary_operator_spaces' => true,
'trailing_comma_in_multiline' => true,
])
;

View file

@ -3,48 +3,7 @@
All notable changes to this project will be documented in this file.
This project adheres to [Semantic Versioning](http://semver.org/).
## [1.1.10][]
#### Added
- Added `which()` function
#### Changed
- Refactor of `run_command()` function to return an exit code
## [1.1.9][]
#### Added
- Added `run_command()` function
- Added `RunCommandFailedException` exception
- Added `pointybeard/helpers-exceptions-readabletrace` package
## [1.1.8][]
#### Changed
- Updated `manpage()` to work with `pointybeard/helpers-cli-input` 1.2
- Using v1.2.x of `pointybeard/helpers-cli-input`
- Updated version constraints in `composer.json`
## [1.1.7][]
#### Added
- Added `pointybeard/helpers-functions-debug` package
#### Changed
- Using `readable_debug_backtrace()` (provided by `pointybeard/helpers-functions-debug`) in `display_error_and_exit()` to produce a trace if one is provided
## [1.1.6][]
#### Added
- Added `display_error_and_exit` function
## [1.1.5][]
#### Changed
- Updated to work with `pointybeard/helpers-cli-input` v1.1.x
## [1.1.4][]
#### Changed
- Refactoring of `manpage()` to hide 'Options' and/or 'Arguments' if there are none to show
## [1.1.3][]
#### Changed
- Updated `manpage()` to include `foregroundColour`, `headingColour`, and `additional` arguments. Removed `example` argument in favour of including it inside `additional`
- Added `pointybeard/helpers-cli-colour` composer package
**View all [Unreleased][] changes here**
## [1.1.2][]
#### Changed
@ -66,13 +25,6 @@ This project adheres to [Semantic Versioning](http://semver.org/).
#### Added
- Initial release
[1.1.9]: https://github.com/pointybeard/helpers-functions-cli/compare/1.1.8...1.1.9
[1.1.8]: https://github.com/pointybeard/helpers-functions-cli/compare/1.1.7...1.1.8
[1.1.7]: https://github.com/pointybeard/helpers-functions-cli/compare/1.1.6...1.1.7
[1.1.6]: https://github.com/pointybeard/helpers-functions-cli/compare/1.1.5...1.1.6
[1.1.5]: https://github.com/pointybeard/helpers-functions-cli/compare/1.1.4...1.1.5
[1.1.4]: https://github.com/pointybeard/helpers-functions-cli/compare/1.1.3...1.1.4
[1.1.3]: https://github.com/pointybeard/helpers-functions-cli/compare/1.1.2...1.1.3
[1.1.2]: https://github.com/pointybeard/helpers-functions-cli/compare/1.1.1...1.1.2
[Unreleased]: https://github.com/pointybeard/helpers-functions-cli/compare/1.1.1...integration
[1.1.1]: https://github.com/pointybeard/helpers-functions-cli/compare/1.1.0...1.1.1
[1.1.0]: https://github.com/pointybeard/helpers-functions-cli/compare/1.0.0...1.1.0

View file

@ -3,7 +3,7 @@ unless otherwise specified, released under the MIT licence as follows:
----- begin license block -----
Copyright 2019-2021 Alannah Kearney
Copyright 2019 Alannah Kearney
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

120
README.md
View file

@ -1,7 +1,7 @@
# PHP Helpers: Command-line Functions
- Version: v1.1.10
- Date: July 29 2021
- Version: v1.1.2
- Date: May 23 2019
- [Release notes](https://github.com/pointybeard/helpers-functions-cli/blob/master/CHANGELOG.md)
- [GitHub repository](https://github.com/pointybeard/helpers-functions-cli)
@ -18,9 +18,9 @@ And run composer to update your dependencies:
### Requirements
This library makes use of the [PHP Helpers: Command-line Input and Input Type Handlers](https://github.com/pointybeard/helpers-cli-input), [PHP Helpers: Flag Functions](https://github.com/pointybeard/helpers-functions-flags) (`pointybeard/helpers-functions-flags`), [PHP Helpers: Command-line Colour](https://github.com/pointybeard/helpers-cli-colours) (`pointybeard/helpers-cli-colours`) and [PHP Helpers: String Functions](https://github.com/pointybeard/helpers-functions-strings) packages. They are installed automatically via composer.
This library makes use of the [PHP Helpers: Command-line Input and Input Type Handlers](https://github.com/pointybeard/helpers-cli-input), [PHP Helpers: Flag Functions](https://github.com/pointybeard/helpers-functions-flags) (`pointybeard/helpers-functions-flags`) and [PHP Helpers: String Functions](https://github.com/pointybeard/helpers-functions-strings) packages. They are installed automatically via composer.
To include all the [PHP Helpers](https://github.com/pointybeard/helpers) packages on your project, use `composer require pointybeard/helpers` or add `"pointybeard/helpers": "~1"` to your composer file.
To include all the [PHP Helpers](https://github.com/pointybeard/helpers) packages on your project, use `composer require pointybeard/helpers` or add `"pointybeard/helpers": "~1.1"` to your composer file.
## Usage
@ -28,15 +28,11 @@ This library is a collection convenience function for command-line tasks. They a
The following functions are provided:
- `run_command()`
- `which()`
- `can_invoke_bash()`
- `is_su()`
- `run_command()`
- `usage()`
- `manpage()`
- `get_window_size()`
- `display_error_and_exit()`
- `can_invoke_bash() : bool`
- `is_su() : bool`
- `usage(string $name, Cli\Input\InputCollection $collection) : string`
- `manpage(string $name, string $version, string $description, string $example, Cli\Input\InputCollection $collection): string`
- `get_window_size(): array`
Example usage:
@ -47,12 +43,8 @@ declare(strict_types=1);
include __DIR__.'/vendor/autoload.php';
use pointybeard\Helpers\Cli\Input;
use pointybeard\Helpers\Cli\Colour\Colour;
use pointybeard\Helpers\Functions\Cli;
var_dump(Cli\which("ls"));
// string(11) "/usr/bin/ls"
var_dump(Cli\can_invoke_bash());
// bool(true)
@ -65,89 +57,55 @@ var_dump(Cli\get_window_size());
// 'lines' => string(2) "68"
// }
Cli\run_command("date", $out);
var_dump($out);
// string(29) "Mon 6 Apr 17:20:29 AEST 2020"
try{
Cli\run_command("not -a --command", $out, $err);
} catch(Cli\Exceptions\RunCommandFailedException $ex) {
var_dump($ex->getMessage(), $ex->getCommand(), $ex->getError());
}
// string(54) "Failed to run command. Returned: sh: 1: not: not found"
// string(16) "not -a --command"
// string(21) "sh: 1: not: not found"
echo Cli\manpage(
'test',
'1.0.2',
'A simple test command with a really long description. This is an intentionally very long argument description so we can check that word wrapping is working correctly. It should wrap to the window',
'1.0.0',
'A simple test command',
'php -f test.php -- import -vvv -d test.json',
(new Input\InputCollection())
->add(
Input\InputTypeFactory::build('Argument')
->name('action')
->flags(Input\AbstractInputType::FLAG_REQUIRED)
->description('The name of the action to perform. This is an intentionally very long argument description so we can check that word wrapping is working correctly')
)
->add(
Input\InputTypeFactory::build('IncrementingFlag')
->name('v')
->flags(Input\AbstractInputType::FLAG_OPTIONAL | Input\AbstractInputType::FLAG_TYPE_INCREMENTING)
->description('verbosity level. -v (errors only), -vv (warnings and errors), -vvv (everything).')
->validator(new Input\Validator(
function (Input\AbstractInputType $input, Input\AbstractInputHandler $context) {
// Make sure verbosity level never goes above 3
return min(3, (int) $context->find('v'));
}
->append(new Input\Types\Argument(
'action',
Input\AbstractInputType::FLAG_REQUIRED,
'The name of the action to perform'
))
->append(new Input\Types\Option(
'v',
null,
Input\AbstractInputType::FLAG_OPTIONAL | Input\AbstractInputType::FLAG_TYPE_INCREMENTING,
'verbosity level. -v (errors only), -vv (warnings and errors), -vvv (everything).',
null,
0
))
->append(new Input\Types\Option(
'd',
'data',
Input\AbstractInputType::FLAG_OPTIONAL | Input\AbstractInputType::FLAG_VALUE_REQUIRED,
'Path to the input JSON data'
))
)
->add(
Input\InputTypeFactory::build('Option')
->name('P')
->flags(Input\AbstractInputType::FLAG_OPTIONAL | Input\AbstractInputType::FLAG_VALUE_OPTIONAL)
->description('Port to use for all connections.')
->default('3306')
)
->add(
Input\InputTypeFactory::build('LongOption')
->name('data')
->short('d')
->flags(Input\AbstractInputType::FLAG_OPTIONAL | Input\AbstractInputType::FLAG_VALUE_REQUIRED)
->description('Path to the input JSON data.')
),
Colour::FG_GREEN,
Colour::FG_WHITE,
[
'Examples' => 'php -f test.php -- import -vvv -d test.json',
]
).PHP_EOL;
// test 1.0.2, A simple test command with a really long description. This is an intentionally very long argument description so we can check that word wrapping is working correctly. It should wrap to the window
// test 1.0.0, A simple test command
// Usage: test [OPTIONS]... ACTION...
//
// Mandatory values for long options are mandatory for short options too.
//
// Arguments:
// ACTION The name of the action to perform. This is an intentionally very
// long argument description so we can check that word wrapping is
// working correctly
// ACTION The name of the action to perform
//
// Options:
// -v verbosity level. -v (errors only), -vv (warnings and errors),
// -vvv (everything).
// -P Port to use for all connections.
// -d, --data=VALUE Path to the input JSON data.
// -v verbosity level. -v (errors only), -vv (warnings
// and errors), -vvv (everything).
// -d, --data=VALUE Path to the input JSON data
//
// Examples:
// php -f test.php -- import -vvv -d test.json
Cli\display_error_and_exit('Looks like something went wrong!', 'Fatal Error');
// Fatal Error
// Looks like something went wrong!
```
## Support
If you believe you have found a bug, please report it using the [GitHub issue tracker](https://github.com/pointybeard/helpers-functions-cli/issues), or better yet, fork the library and submit a pull request.
If you believe you have found a bug, please report it using the [GitHub issue tracker](https://github.com/pointybeard/helpers-functions-cli/issues),
or better yet, fork the library and submit a pull request.
## Contributing

View file

@ -1,13 +1,9 @@
{
"name": "pointybeard/helpers-functions-cli",
"version": "1.1.2",
"description": "A collection of functions relating to the command-line",
"homepage": "https://github.com/pointybeard/helpers-functions-cli",
"license": "MIT",
"minimum-stability": "stable",
"support": {
"issues": "https://github.com/pointybeard/helpers-functions-cli/issues",
"wiki": "https://github.com/pointybeard/helpers-functions-cli/wiki"
},
"authors": [
{
"name": "Alannah Kearney",
@ -18,34 +14,21 @@
],
"require": {
"php": ">=7.2",
"pointybeard/helpers-cli-input": "~1.2.0",
"pointybeard/helpers-cli-colour": "~1.0",
"pointybeard/helpers-cli-input": "~1.0",
"pointybeard/helpers-functions-strings": "~1.1",
"pointybeard/helpers-functions-flags": "~1.0",
"pointybeard/helpers-functions-arrays": "~1.0",
"pointybeard/helpers-functions-debug": "~1.0",
"pointybeard/helpers-exceptions-readabletrace": "~1.0.0"
"pointybeard/helpers-functions-flags": "~1.0"
},
"require-dev": {
"friendsofphp/php-cs-fixer": "^3.0",
"squizlabs/php_codesniffer": "^3.0",
"damianopetrungaro/php-commitizen": "^0.1.0",
"php-parallel-lint/php-parallel-lint": "^1.0",
"php-parallel-lint/php-console-highlighter": "^0.5.0"
"phpunit/phpunit": "^8"
},
"support": {
"issues": "https://github.com/pointybeard/helpers-functions-cli/issues",
"wiki": "https://github.com/pointybeard/helpers-functions-cli/wiki"
},
"minimum-stability": "stable",
"autoload": {
"psr-4": {
"pointybeard\\Helpers\\Functions\\": "src/"
},
"files": [
"src/Cli/Cli.php"
]
},
"scripts": {
"tidy": "php-cs-fixer fix -v --using-cache=no",
"tidyDry": "@tidy --dry-run",
"test": [
"parallel-lint . --exclude vendor"
]
}
}

View file

@ -2,117 +2,12 @@
declare(strict_types=1);
/*
* This file is part of the "PHP Helpers: Command-line Functions" repository.
*
* Copyright 2019-2021 Alannah Kearney <hi@alannahkearney.com>
*
* For the full copyright and license information, please view the LICENCE
* file that was distributed with this source code.
*/
namespace pointybeard\Helpers\Functions\Cli;
use Exception;
use pointybeard\Helpers\Cli\Colour;
use pointybeard\Helpers\Cli\Input;
use pointybeard\Helpers\Functions\Arrays;
use pointybeard\Helpers\Functions\Debug;
use pointybeard\Helpers\Functions\Flags;
use pointybeard\Helpers\Functions\Strings;
/*
* Uses proc_open() to run a command on the shell. Output and errors are captured
* and returned. If the command "fails" to run (i.e. return code is != 0), this
* function will throw an exception.
*
* Note that some commands will return a non-zero status code to signify, for
* example, no results found. This function is unable to tell the difference and
* will trigger an exception regardless. In this instance, It is advised to trap
* that exception and inspect both $stderr and $stdout to decide if it was
* actually due to failed command execution.
*
* @param string $command the full bash command to run
* @param string $stdout (optional) reference to capture output from STDOUT
* @param string $stderr (optional) reference to capture output from STDERR
* #param string $exitCode (options) reference to capture the command exit code
*
* @throws RunCommandFailedException
*/
if (!function_exists(__NAMESPACE__.'\run_command')) {
function run_command(string $command, string &$stdout = null, string &$stderr = null, int &$exitCode = null): void
{
$pipes = null;
$exitCode = null;
$proc = proc_open(
"{$command};echo $? >&3",
[
0 => ['pipe', 'r'], // STDIN
1 => ['pipe', 'w'], // STDOUT
2 => ['pipe', 'w'], // STDERR
3 => ['pipe', 'w'], // Used to capture the exit code
],
$pipes,
getcwd(),
null
);
// Close STDIN stream
fclose($pipes[0]);
// (guard) proc_open failed to return a resource
if (false == is_resource($proc)) {
throw new Exceptions\RunCommandFailedException($command, 'proc_open() returned FALSE.');
}
// Get contents of STDOUT and close stream
$stdout = trim(stream_get_contents($pipes[1]));
fclose($pipes[1]);
// Get contents od STDERR and close stream
$stderr = trim(stream_get_contents($pipes[2]));
fclose($pipes[2]);
// Grab the exit code then close the stream
if (false == feof($pipes[3])) {
$exitCode = (int) trim(stream_get_contents($pipes[3]));
}
fclose($pipes[3]);
// Close the process we created
proc_close($proc);
// (guard) proc_close return indiciated a failure
if (0 != $exitCode) {
// There was some kind of error. Throw an exception.
// If STDERR is empty, in effort to give back something
// meaningful, grab contents of STDOUT instead
throw new Exceptions\RunCommandFailedException($command, true == empty(trim($stderr)) ? $stdout : $stderr);
}
}
}
/*
* Returns the pathname for a specified command (or null if it cannot be found)
*
* @params $command the name of the command to look for
*
* @returns string|null
*/
if (!function_exists(__NAMESPACE__.'\which')) {
function which(string $command): ?string
{
try {
run_command("which {$command}", $output);
} catch (Exception $ex) {
$output = null;
}
return $output;
}
}
/*
* Checks if bash can be invoked.
*
@ -142,25 +37,11 @@ if (!function_exists(__NAMESPACE__.'is_su')) {
}
}
/*
* Uses tput to find out the size of the window (columns and lines)
* @return array an array containing exactly 2 items: 'cols' and 'lines'
*/
if (!function_exists(__NAMESPACE__.'get_window_size')) {
function get_window_size(): array
{
return [
'cols' => exec('tput cols'),
'lines' => exec('tput lines'),
];
}
}
if (!function_exists(__NAMESPACE__.'usage')) {
function usage(string $name, Input\InputCollection $collection): string
{
$arguments = [];
foreach ($collection->getItemsByType('Argument') as $a) {
foreach ($collection->getArguments() as $a) {
$arguments[] = strtoupper(
// Wrap with square brackets if it's not required
Flags\is_flag_set(Input\AbstractInputType::FLAG_OPTIONAL, $a->flags()) ||
@ -169,7 +50,7 @@ if (!function_exists(__NAMESPACE__.'usage')) {
: $a->name()
);
}
$arguments = trim(implode(' ', $arguments));
$arguments = trim(implode($arguments, ' '));
return sprintf(
'Usage: %s [OPTIONS]... %s%s',
@ -181,134 +62,53 @@ if (!function_exists(__NAMESPACE__.'usage')) {
}
if (!function_exists(__NAMESPACE__.'manpage')) {
function manpage(string $name, string $version, string $description, Input\InputCollection $collection, $foregroundColour = Colour\Colour::FG_DEFAULT, $headingColour = Colour\Colour::FG_WHITE, array $additionalSections = []): string
function manpage(string $name, string $version, string $description, string $example, Input\InputCollection $collection): string
{
// Convienence function for wrapping a heading with colour
$heading = function (string $input) use ($headingColour) {
return Colour\Colour::colourise($input, $headingColour);
};
$arguments = $options = [];
// Convienence function for wrapping input in a specified colour
$colourise = function (string $input) use ($foregroundColour) {
return Colour\Colour::colourise($input, $foregroundColour);
};
$sections = [
$colourise(sprintf(
"%s %s, %s\r\n%s\r\n",
$name,
$version,
$description,
usage($name, $collection)
)),
];
$arguments = [];
$options = [];
foreach ($collection->getItemsByType('Argument') as $a) {
foreach ($collection->getArguments() as $a) {
$arguments[] = (string) $a;
}
foreach ($collection->getItemsExcludeByType('Argument') as $o) {
foreach ($collection->getOptions() as $o) {
$options[] = (string) $o;
}
// Add the arguments, if there are any.
if (false === empty($arguments)) {
$sections[] = $heading('Arguments:');
$sections[] = $colourise(implode(PHP_EOL, $arguments)).PHP_EOL;
}
$arguments = implode($arguments, PHP_EOL.' ');
$options = implode($options, PHP_EOL.' ');
// Add the options, if there are any.
if (false === empty($options)) {
$sections[] = $heading('Options:');
$sections[] = $colourise(implode(PHP_EOL, $options)).PHP_EOL;
}
return sprintf(
'%s %s, %s
%s
// Iterate over all additional items and add them as new sections
foreach ($additionalSections as $name => $contents) {
$sections[] = $heading("{$name}:");
$sections[] = $colourise($contents).PHP_EOL;
}
Mandatory values for long options are mandatory for short options too.
return implode(PHP_EOL, $sections);
Arguments:
%s
Options:
%s
Examples:
%s
',
$name,
$version,
Strings\utf8_wordwrap($description),
usage($name, $collection),
$arguments,
$options,
$example
);
}
}
if (!function_exists(__NAMESPACE__."\display_error_and_exit")) {
function display_error_and_exit($message, $heading = 'Error', $background = Colour\Colour::BG_RED, ?array $trace = null): void
if (!function_exists(__NAMESPACE__.'get_window_size')) {
function get_window_size(): array
{
$padCharacter = ' ';
$paddingBufferSize = 0.15; // 15%
$minimumWindowWidth = 40;
$edgePaddingLength = 5;
$edgePadding = str_repeat($padCharacter, $edgePaddingLength);
// Convenience function for adding the background to a line.
$add_background = function (string $string, bool $bold = false) use ($edgePadding, $background): string {
$string = $edgePadding.$string.$edgePadding;
return Colour\Colour::colourise(
$string,
(
true == $bold
? Colour\Colour::FG_WHITE
: Colour\Colour::FG_DEFAULT
),
$background
);
};
// Get the window dimensions but restrict width to minimum
// of $minimumWindowWidth
$window = get_window_size();
$window['cols'] = max($minimumWindowWidth, $window['cols']);
// This shrinks the total line length (derived by the window width) by
// $paddingBufferSize
$paddingBuffer = (int) ceil($window['cols'] * $paddingBufferSize);
$lineLength = $window['cols'] - (2 * $edgePaddingLength) - $paddingBuffer;
$emptyLine = $add_background(str_repeat($padCharacter, $lineLength), true);
$heading = Strings\mb_str_pad(trim($heading), $lineLength, $padCharacter, \STR_PAD_RIGHT);
$message = Strings\utf8_wordwrap_array($message, $lineLength, PHP_EOL, true);
// Remove surrounding whitespace
$message = array_map('trim', $message);
// Remove empty elements from the array
$message = Arrays\array_remove_empty($message);
// Reset array indicies
$message = array_values($message);
// Wrap everything in red
for ($ii = 0; $ii < count($message); ++$ii) {
$message[$ii] = $add_background(Strings\mb_str_pad(
$message[$ii],
mb_strlen($heading),
$padCharacter,
\STR_PAD_RIGHT
));
}
// Add an empty red line at the end
array_push($message, $emptyLine);
// Print the error message, starting with an empty red line
printf(
"\r\n%s\r\n%s\r\n%s\r\n%s",
$emptyLine,
$add_background($heading, true),
implode(PHP_EOL, $message),
!empty($trace) && count($trace) > 0
? PHP_EOL.sprintf("Trace\r\n==========\r\n%s\r\n", Debug\readable_debug_backtrace($trace))
: ''
);
exit(1);
return [
'cols' => exec('tput cols'),
'lines' => exec('tput lines'),
];
}
}

View file

@ -1,40 +0,0 @@
<?php
declare(strict_types=1);
/*
* This file is part of the "PHP Helpers: Command-line Functions" repository.
*
* Copyright 2019-2021 Alannah Kearney <hi@alannahkearney.com>
*
* For the full copyright and license information, please view the LICENCE
* file that was distributed with this source code.
*/
namespace pointybeard\Helpers\Functions\Cli\Exceptions;
use pointybeard\Helpers\Exceptions\ReadableTrace;
class RunCommandFailedException extends ReadableTrace\ReadableTraceException
{
private $command;
private $error;
public function __construct(string $command, string $error, int $code = 0, \Exception $previous = null)
{
$this->command = $command;
$this->error = $error;
parent::__construct("Failed to run command. Returned: {$error}", $code, $previous);
}
public function getCommand(): string
{
return $this->command;
}
public function getError(): string
{
return $this->error;
}
}