From 4c519dd3bce62d072ae0e64c657967f5629e1553 Mon Sep 17 00:00:00 2001 From: Jakub Turek Date: Sat, 7 Mar 2015 23:08:52 +0100 Subject: [PATCH 01/12] Add command help option --- Mage/Command/AbstractCommand.php | 65 +++++++ .../MageTest/Command/AbstractCommandTest.php | 171 ++++++++++++++++++ 2 files changed, 236 insertions(+) diff --git a/Mage/Command/AbstractCommand.php b/Mage/Command/AbstractCommand.php index f69b0ef..bc020dc 100644 --- a/Mage/Command/AbstractCommand.php +++ b/Mage/Command/AbstractCommand.php @@ -26,6 +26,10 @@ abstract class AbstractCommand */ protected $config = null; + private $helpMessage; + private $usageExamples = []; + private $syntaxMessage; + /** * Runs the Command * @return integer exit code @@ -52,4 +56,65 @@ abstract class AbstractCommand { return $this->config; } + + public function setHelpMessage($message) + { + $this->helpMessage = $message; + + return $this; + } + + public function addUsageExample($snippet, $description = '') + { + array_push($this->usageExamples, [$snippet, $description]); + + return $this; + } + + public function setSyntaxMessage($message) + { + $this->syntaxMessage = $message; + + return $this; + } + + public function getInfoMessage() + { + $indent = str_repeat(" ", 4); + + $output = ""; + + if (!empty($this->helpMessage)) { + $output .= "\n"; + $output .= $this->helpMessage . "\n"; + } + + if (!empty($this->syntaxMessage)) { + $output .= "\n"; + $output .= "Syntax:\n"; + $output .= $indent; + $output .= $this->syntaxMessage; + $output .= "\n"; + } + + if (!empty($this->usageExamples)) { + $output .= "\n"; + $output .= "Usage examples:\n"; + foreach ($this->usageExamples as $example) { + $snippet = $example[0]; + $description = $example[1]; + $output .= "$indent* "; + if (!empty($description)) { + $description = rtrim($description, ': ') . ":"; + $output .= $description; + $output .= "\n$indent$indent"; + } + + $output .= $snippet; + $output .= "\n"; + } + } + + return $output; + } } diff --git a/tests/MageTest/Command/AbstractCommandTest.php b/tests/MageTest/Command/AbstractCommandTest.php index fed7df5..22a73f6 100644 --- a/tests/MageTest/Command/AbstractCommandTest.php +++ b/tests/MageTest/Command/AbstractCommandTest.php @@ -44,4 +44,175 @@ class AbstractCommandTest extends BaseTest $configMock = $this->getMock('Mage\Config'); $this->doTestGetter($this->abstractCommand, 'config', $configMock); } + + public function infoMessageProvider() + { + return [ + 'happy_path' => [ + 'helpMessage' => 'This command does everything you want to', + 'examples' => [ + [ + 'snippet' => 'mage example', + 'description' => 'Default command' + ], + [ + 'snippet' => 'mage example light', + 'description' => 'Runs the command with lights' + ] + ], + 'syntax' => 'mage example [light]', + 'output' => "\n" + . "This command does everything you want to\n" + . "\n" + . "Syntax:\n" + . " mage example [light]\n" + . "\n" + . "Usage examples:\n" + . " * Default command:\n" + . " mage example\n" + . " * Runs the command with lights:\n" + . " mage example light\n" + ], + 'no_help_message' => [ + 'helpMessage' => '', + 'examples' => [ + [ + 'snippet' => 'mage example', + 'description' => 'Default command' + ], + [ + 'snippet' => 'mage example light', + 'description' => 'Runs the command with lights' + ] + ], + 'syntax' => 'mage example [light]', + 'output' => "\n" + . "Syntax:\n" + . " mage example [light]\n" + . "\n" + . "Usage examples:\n" + . " * Default command:\n" + . " mage example\n" + . " * Runs the command with lights:\n" + . " mage example light\n" + ], + 'no_examples' => [ + 'helpMessage' => 'This command does everything you want to', + 'examples' => [], + 'syntax' => 'mage example [light]', + 'output' => "\n" + . "This command does everything you want to\n" + . "\n" + . "Syntax:\n" + . " mage example [light]\n" + ], + "no_syntax" => [ + 'helpMessage' => 'This command does everything you want to', + 'examples' => [ + [ + 'snippet' => 'mage example', + 'description' => 'Default command' + ], + [ + 'snippet' => 'mage example light', + 'description' => 'Runs the command with lights' + ] + ], + 'syntax' => '', + 'output' => "\n" + . "This command does everything you want to\n" + . "\n" + . "Usage examples:\n" + . " * Default command:\n" + . " mage example\n" + . " * Runs the command with lights:\n" + . " mage example light\n" + ], + "stripping_colons" => [ + 'helpMessage' => 'This command does everything you want to', + 'examples' => [ + [ + 'snippet' => 'mage example', + 'description' => 'Default command:' + ], + [ + 'snippet' => 'mage example light', + 'description' => 'Runs the command with lights:' + ] + ], + 'syntax' => 'mage example [light]', + 'output' => "\n" + . "This command does everything you want to\n" + . "\n" + . "Syntax:\n" + . " mage example [light]\n" + . "\n" + . "Usage examples:\n" + . " * Default command:\n" + . " mage example\n" + . " * Runs the command with lights:\n" + . " mage example light\n" + ], + "only_help" => [ + 'helpMessage' => 'This command does everything you want to', + 'examples' => [], + 'syntax' => '', + 'output' => "\n" + . "This command does everything you want to\n" + ], + "only_examples" => [ + 'helpMessage' => '', + 'examples' => [ + [ + 'snippet' => 'mage example', + 'description' => 'Default command' + ], + [ + 'snippet' => 'mage example light', + 'description' => 'Runs the command with lights' + ] + ], + 'syntax' => '', + 'output' => "\n" + . "Usage examples:\n" + . " * Default command:\n" + . " mage example\n" + . " * Runs the command with lights:\n" + . " mage example light\n" + ], + "only_syntax" => [ + 'helpMessage' => '', + 'examples' => [], + 'syntax' => 'mage example [light]', + 'output' => "\n" + . "Syntax:\n" + . " mage example [light]\n" + ] + ]; + } + + /** + * @covers ::getInfoMessage + * @covers ::setHelpMessage + * @covers ::addUsageExample + * @covers ::setSyntaxMessage + * + * @dataProvider infoMessageProvider + */ + public function testGetInfoMessage($helpMessage, $examples, $syntax, $expectedMessage) + { + /** @var AbstractCommand $command */ + $command = $this->getMockForAbstractClass('Mage\Command\AbstractCommand'); + + foreach ($examples as $example) { + $command->addUsageExample($example['snippet'], $example['description']); + } + + $command->setHelpMessage($helpMessage); + $command->setSyntaxMessage($syntax); + + $actualMessage = $command->getInfoMessage(); + $this->assertEquals($expectedMessage, $actualMessage); + + } } From 94d301f66fdb4f9c2c1834afc9e7bafae61891da Mon Sep 17 00:00:00 2001 From: Jakub Turek Date: Sat, 7 Mar 2015 23:36:31 +0100 Subject: [PATCH 02/12] Add console colours to command info output --- Mage/Command/AbstractCommand.php | 11 ++-- .../MageTest/Command/AbstractCommandTest.php | 60 +++++++++---------- 2 files changed, 35 insertions(+), 36 deletions(-) diff --git a/Mage/Command/AbstractCommand.php b/Mage/Command/AbstractCommand.php index bc020dc..403b7db 100644 --- a/Mage/Command/AbstractCommand.php +++ b/Mage/Command/AbstractCommand.php @@ -86,20 +86,19 @@ abstract class AbstractCommand if (!empty($this->helpMessage)) { $output .= "\n"; - $output .= $this->helpMessage . "\n"; + $output .= "{$this->helpMessage}\n"; } if (!empty($this->syntaxMessage)) { $output .= "\n"; - $output .= "Syntax:\n"; - $output .= $indent; - $output .= $this->syntaxMessage; + $output .= "Syntax:\n"; + $output .= "$indent{$this->syntaxMessage}"; $output .= "\n"; } if (!empty($this->usageExamples)) { $output .= "\n"; - $output .= "Usage examples:\n"; + $output .= "Usage examples:\n"; foreach ($this->usageExamples as $example) { $snippet = $example[0]; $description = $example[1]; @@ -110,7 +109,7 @@ abstract class AbstractCommand $output .= "\n$indent$indent"; } - $output .= $snippet; + $output .= "$snippet"; $output .= "\n"; } } diff --git a/tests/MageTest/Command/AbstractCommandTest.php b/tests/MageTest/Command/AbstractCommandTest.php index 22a73f6..ebf5af7 100644 --- a/tests/MageTest/Command/AbstractCommandTest.php +++ b/tests/MageTest/Command/AbstractCommandTest.php @@ -62,16 +62,16 @@ class AbstractCommandTest extends BaseTest ], 'syntax' => 'mage example [light]', 'output' => "\n" - . "This command does everything you want to\n" + . "This command does everything you want to\n" . "\n" - . "Syntax:\n" - . " mage example [light]\n" + . "Syntax:\n" + . " mage example [light]\n" . "\n" - . "Usage examples:\n" + . "Usage examples:\n" . " * Default command:\n" - . " mage example\n" + . " mage example\n" . " * Runs the command with lights:\n" - . " mage example light\n" + . " mage example light\n" ], 'no_help_message' => [ 'helpMessage' => '', @@ -87,24 +87,24 @@ class AbstractCommandTest extends BaseTest ], 'syntax' => 'mage example [light]', 'output' => "\n" - . "Syntax:\n" - . " mage example [light]\n" + . "Syntax:\n" + . " mage example [light]\n" . "\n" - . "Usage examples:\n" + . "Usage examples:\n" . " * Default command:\n" - . " mage example\n" + . " mage example\n" . " * Runs the command with lights:\n" - . " mage example light\n" + . " mage example light\n" ], 'no_examples' => [ 'helpMessage' => 'This command does everything you want to', 'examples' => [], 'syntax' => 'mage example [light]', 'output' => "\n" - . "This command does everything you want to\n" + . "This command does everything you want to\n" . "\n" - . "Syntax:\n" - . " mage example [light]\n" + . "Syntax:\n" + . " mage example [light]\n" ], "no_syntax" => [ 'helpMessage' => 'This command does everything you want to', @@ -120,13 +120,13 @@ class AbstractCommandTest extends BaseTest ], 'syntax' => '', 'output' => "\n" - . "This command does everything you want to\n" + . "This command does everything you want to\n" . "\n" - . "Usage examples:\n" + . "Usage examples:\n" . " * Default command:\n" - . " mage example\n" + . " mage example\n" . " * Runs the command with lights:\n" - . " mage example light\n" + . " mage example light\n" ], "stripping_colons" => [ 'helpMessage' => 'This command does everything you want to', @@ -142,23 +142,23 @@ class AbstractCommandTest extends BaseTest ], 'syntax' => 'mage example [light]', 'output' => "\n" - . "This command does everything you want to\n" + . "This command does everything you want to\n" . "\n" - . "Syntax:\n" - . " mage example [light]\n" + . "Syntax:\n" + . " mage example [light]\n" . "\n" - . "Usage examples:\n" + . "Usage examples:\n" . " * Default command:\n" - . " mage example\n" + . " mage example\n" . " * Runs the command with lights:\n" - . " mage example light\n" + . " mage example light\n" ], "only_help" => [ 'helpMessage' => 'This command does everything you want to', 'examples' => [], 'syntax' => '', 'output' => "\n" - . "This command does everything you want to\n" + . "This command does everything you want to\n" ], "only_examples" => [ 'helpMessage' => '', @@ -174,19 +174,19 @@ class AbstractCommandTest extends BaseTest ], 'syntax' => '', 'output' => "\n" - . "Usage examples:\n" + . "Usage examples:\n" . " * Default command:\n" - . " mage example\n" + . " mage example\n" . " * Runs the command with lights:\n" - . " mage example light\n" + . " mage example light\n" ], "only_syntax" => [ 'helpMessage' => '', 'examples' => [], 'syntax' => 'mage example [light]', 'output' => "\n" - . "Syntax:\n" - . " mage example [light]\n" + . "Syntax:\n" + . " mage example [light]\n" ] ]; } From 4e18ae1f8c40f736b9e568be7f2592e87109ead5 Mon Sep 17 00:00:00 2001 From: Jakub Turek Date: Sun, 8 Mar 2015 12:23:42 +0100 Subject: [PATCH 03/12] Add command name as an option --- Mage/Command/AbstractCommand.php | 15 ++++- .../MageTest/Command/AbstractCommandTest.php | 60 ++++++++++++++++--- 2 files changed, 66 insertions(+), 9 deletions(-) diff --git a/Mage/Command/AbstractCommand.php b/Mage/Command/AbstractCommand.php index 403b7db..800dd09 100644 --- a/Mage/Command/AbstractCommand.php +++ b/Mage/Command/AbstractCommand.php @@ -29,6 +29,7 @@ abstract class AbstractCommand private $helpMessage; private $usageExamples = []; private $syntaxMessage; + private $name; /** * Runs the Command @@ -57,6 +58,13 @@ abstract class AbstractCommand return $this->config; } + public function setName($name) + { + $this->name = $name; + + return $this; + } + public function setHelpMessage($message) { $this->helpMessage = $message; @@ -83,10 +91,15 @@ abstract class AbstractCommand $indent = str_repeat(" ", 4); $output = ""; + if (!empty($this->name)) { + $output .= "\n"; + $output .= "Command: "; + $output .= $this->name; + } if (!empty($this->helpMessage)) { $output .= "\n"; - $output .= "{$this->helpMessage}\n"; + $output .= "{$this->helpMessage}\n"; } if (!empty($this->syntaxMessage)) { diff --git a/tests/MageTest/Command/AbstractCommandTest.php b/tests/MageTest/Command/AbstractCommandTest.php index ebf5af7..877dfae 100644 --- a/tests/MageTest/Command/AbstractCommandTest.php +++ b/tests/MageTest/Command/AbstractCommandTest.php @@ -49,6 +49,7 @@ class AbstractCommandTest extends BaseTest { return [ 'happy_path' => [ + 'name' => 'Example command', 'helpMessage' => 'This command does everything you want to', 'examples' => [ [ @@ -62,7 +63,8 @@ class AbstractCommandTest extends BaseTest ], 'syntax' => 'mage example [light]', 'output' => "\n" - . "This command does everything you want to\n" + . "Command: Example command\n" + . "This command does everything you want to\n" . "\n" . "Syntax:\n" . " mage example [light]\n" @@ -74,6 +76,7 @@ class AbstractCommandTest extends BaseTest . " mage example light\n" ], 'no_help_message' => [ + 'name' => 'Example command', 'helpMessage' => '', 'examples' => [ [ @@ -87,6 +90,7 @@ class AbstractCommandTest extends BaseTest ], 'syntax' => 'mage example [light]', 'output' => "\n" + . "Command: Example command\n" . "Syntax:\n" . " mage example [light]\n" . "\n" @@ -97,16 +101,19 @@ class AbstractCommandTest extends BaseTest . " mage example light\n" ], 'no_examples' => [ + 'name' => 'Example command', 'helpMessage' => 'This command does everything you want to', 'examples' => [], 'syntax' => 'mage example [light]', 'output' => "\n" - . "This command does everything you want to\n" + . "Command: Example command\n" + . "This command does everything you want to\n" . "\n" . "Syntax:\n" . " mage example [light]\n" ], "no_syntax" => [ + 'name' => 'Example command', 'helpMessage' => 'This command does everything you want to', 'examples' => [ [ @@ -120,7 +127,8 @@ class AbstractCommandTest extends BaseTest ], 'syntax' => '', 'output' => "\n" - . "This command does everything you want to\n" + . "Command: Example command\n" + . "This command does everything you want to\n" . "\n" . "Usage examples:\n" . " * Default command:\n" @@ -129,20 +137,22 @@ class AbstractCommandTest extends BaseTest . " mage example light\n" ], "stripping_colons" => [ + 'name' => 'Example command', 'helpMessage' => 'This command does everything you want to', 'examples' => [ [ 'snippet' => 'mage example', - 'description' => 'Default command:' + 'description' => 'Default command : ' ], [ 'snippet' => 'mage example light', - 'description' => 'Runs the command with lights:' + 'description' => 'Runs the command with lights: ' ] ], 'syntax' => 'mage example [light]', 'output' => "\n" - . "This command does everything you want to\n" + . "Command: Example command\n" + . "This command does everything you want to\n" . "\n" . "Syntax:\n" . " mage example [light]\n" @@ -154,13 +164,16 @@ class AbstractCommandTest extends BaseTest . " mage example light\n" ], "only_help" => [ + 'name' => 'Example command', 'helpMessage' => 'This command does everything you want to', 'examples' => [], 'syntax' => '', 'output' => "\n" - . "This command does everything you want to\n" + . "Command: Example command\n" + . "This command does everything you want to\n" ], "only_examples" => [ + 'name' => 'Example command', 'helpMessage' => '', 'examples' => [ [ @@ -174,6 +187,7 @@ class AbstractCommandTest extends BaseTest ], 'syntax' => '', 'output' => "\n" + . "Command: Example command\n" . "Usage examples:\n" . " * Default command:\n" . " mage example\n" @@ -181,12 +195,40 @@ class AbstractCommandTest extends BaseTest . " mage example light\n" ], "only_syntax" => [ + 'name' => 'Example command', 'helpMessage' => '', 'examples' => [], 'syntax' => 'mage example [light]', 'output' => "\n" + . "Command: Example command\n" . "Syntax:\n" . " mage example [light]\n" + ], + "no_name" => [ + 'name' => '', + 'helpMessage' => 'This command does everything you want to', + 'examples' => [ + [ + 'snippet' => 'mage example', + 'description' => 'Default command' + ], + [ + 'snippet' => 'mage example light', + 'description' => 'Runs the command with lights' + ] + ], + 'syntax' => 'mage example [light]', + 'output' => "\n" + . "This command does everything you want to\n" + . "\n" + . "Syntax:\n" + . " mage example [light]\n" + . "\n" + . "Usage examples:\n" + . " * Default command:\n" + . " mage example\n" + . " * Runs the command with lights:\n" + . " mage example light\n" ] ]; } @@ -199,11 +241,13 @@ class AbstractCommandTest extends BaseTest * * @dataProvider infoMessageProvider */ - public function testGetInfoMessage($helpMessage, $examples, $syntax, $expectedMessage) + public function testGetInfoMessage($name, $helpMessage, $examples, $syntax, $expectedMessage) { /** @var AbstractCommand $command */ $command = $this->getMockForAbstractClass('Mage\Command\AbstractCommand'); + $command->setName($name); + foreach ($examples as $example) { $command->addUsageExample($example['snippet'], $example['description']); } From 08a93389c47df121a8258746dd14b677d158bdd5 Mon Sep 17 00:00:00 2001 From: Jakub Turek Date: Sun, 8 Mar 2015 12:24:21 +0100 Subject: [PATCH 04/12] Convert arrays to traditional syntax --- .../MageTest/Command/AbstractCommandTest.php | 118 +++++++++--------- 1 file changed, 59 insertions(+), 59 deletions(-) diff --git a/tests/MageTest/Command/AbstractCommandTest.php b/tests/MageTest/Command/AbstractCommandTest.php index 877dfae..b903f7c 100644 --- a/tests/MageTest/Command/AbstractCommandTest.php +++ b/tests/MageTest/Command/AbstractCommandTest.php @@ -47,20 +47,20 @@ class AbstractCommandTest extends BaseTest public function infoMessageProvider() { - return [ - 'happy_path' => [ + return array( + 'happy_path' => array( 'name' => 'Example command', 'helpMessage' => 'This command does everything you want to', - 'examples' => [ - [ + 'examples' => array( + array( 'snippet' => 'mage example', 'description' => 'Default command' - ], - [ + ), + array( 'snippet' => 'mage example light', 'description' => 'Runs the command with lights' - ] - ], + ) + ), 'syntax' => 'mage example [light]', 'output' => "\n" . "Command: Example command\n" @@ -74,20 +74,20 @@ class AbstractCommandTest extends BaseTest . " mage example\n" . " * Runs the command with lights:\n" . " mage example light\n" - ], - 'no_help_message' => [ + ), + 'no_help_message' => array( 'name' => 'Example command', 'helpMessage' => '', - 'examples' => [ - [ + 'examples' => array( + array( 'snippet' => 'mage example', 'description' => 'Default command' - ], - [ + ), + array( 'snippet' => 'mage example light', 'description' => 'Runs the command with lights' - ] - ], + ) + ), 'syntax' => 'mage example [light]', 'output' => "\n" . "Command: Example command\n" @@ -99,11 +99,11 @@ class AbstractCommandTest extends BaseTest . " mage example\n" . " * Runs the command with lights:\n" . " mage example light\n" - ], - 'no_examples' => [ + ), + 'no_examples' => array( 'name' => 'Example command', 'helpMessage' => 'This command does everything you want to', - 'examples' => [], + 'examples' => array(), 'syntax' => 'mage example [light]', 'output' => "\n" . "Command: Example command\n" @@ -111,20 +111,20 @@ class AbstractCommandTest extends BaseTest . "\n" . "Syntax:\n" . " mage example [light]\n" - ], - "no_syntax" => [ + ), + "no_syntax" => array( 'name' => 'Example command', 'helpMessage' => 'This command does everything you want to', - 'examples' => [ - [ + 'examples' => array( + array( 'snippet' => 'mage example', 'description' => 'Default command' - ], - [ + ), + array( 'snippet' => 'mage example light', 'description' => 'Runs the command with lights' - ] - ], + ) + ), 'syntax' => '', 'output' => "\n" . "Command: Example command\n" @@ -135,20 +135,20 @@ class AbstractCommandTest extends BaseTest . " mage example\n" . " * Runs the command with lights:\n" . " mage example light\n" - ], - "stripping_colons" => [ + ), + "stripping_colons" => array( 'name' => 'Example command', 'helpMessage' => 'This command does everything you want to', - 'examples' => [ - [ + 'examples' => array( + array( 'snippet' => 'mage example', 'description' => 'Default command : ' - ], - [ + ), + array( 'snippet' => 'mage example light', 'description' => 'Runs the command with lights: ' - ] - ], + ) + ), 'syntax' => 'mage example [light]', 'output' => "\n" . "Command: Example command\n" @@ -162,29 +162,29 @@ class AbstractCommandTest extends BaseTest . " mage example\n" . " * Runs the command with lights:\n" . " mage example light\n" - ], - "only_help" => [ + ), + "only_help" => array( 'name' => 'Example command', 'helpMessage' => 'This command does everything you want to', - 'examples' => [], + 'examples' => array(), 'syntax' => '', 'output' => "\n" . "Command: Example command\n" . "This command does everything you want to\n" - ], - "only_examples" => [ + ), + "only_examples" => array( 'name' => 'Example command', 'helpMessage' => '', - 'examples' => [ - [ + 'examples' => array( + array( 'snippet' => 'mage example', 'description' => 'Default command' - ], - [ + ), + array( 'snippet' => 'mage example light', 'description' => 'Runs the command with lights' - ] - ], + ) + ), 'syntax' => '', 'output' => "\n" . "Command: Example command\n" @@ -193,30 +193,30 @@ class AbstractCommandTest extends BaseTest . " mage example\n" . " * Runs the command with lights:\n" . " mage example light\n" - ], - "only_syntax" => [ + ), + "only_syntax" => array( 'name' => 'Example command', 'helpMessage' => '', - 'examples' => [], + 'examples' => array(), 'syntax' => 'mage example [light]', 'output' => "\n" . "Command: Example command\n" . "Syntax:\n" . " mage example [light]\n" - ], - "no_name" => [ + ), + "no_name" => array( 'name' => '', 'helpMessage' => 'This command does everything you want to', - 'examples' => [ - [ + 'examples' => array( + array( 'snippet' => 'mage example', 'description' => 'Default command' - ], - [ + ), + array( 'snippet' => 'mage example light', 'description' => 'Runs the command with lights' - ] - ], + ) + ), 'syntax' => 'mage example [light]', 'output' => "\n" . "This command does everything you want to\n" @@ -229,8 +229,8 @@ class AbstractCommandTest extends BaseTest . " mage example\n" . " * Runs the command with lights:\n" . " mage example light\n" - ] - ]; + ) + ); } /** From e4bab08d3f8098f889cc3ae45e7b34ae77480e99 Mon Sep 17 00:00:00 2001 From: Jakub Turek Date: Sun, 8 Mar 2015 12:28:22 +0100 Subject: [PATCH 05/12] Add some PHPDoc notes to AbstractCommand --- Mage/Command/AbstractCommand.php | 55 +++++++++++++++++++++++++++++++- 1 file changed, 54 insertions(+), 1 deletion(-) diff --git a/Mage/Command/AbstractCommand.php b/Mage/Command/AbstractCommand.php index 800dd09..8a0e561 100644 --- a/Mage/Command/AbstractCommand.php +++ b/Mage/Command/AbstractCommand.php @@ -26,9 +26,32 @@ abstract class AbstractCommand */ protected $config = null; + /** + * Command's help message + * + * @var string + */ private $helpMessage; - private $usageExamples = []; + + /** + * Usage examples. + * + * @var array + */ + private $usageExamples = array(); + + /** + * Command's syntax message + * + * @var string + */ private $syntaxMessage; + + /** + * Command name + * + * @var string + */ private $name; /** @@ -58,6 +81,12 @@ abstract class AbstractCommand return $this->config; } + /** + * Sets command name + * + * @param string $name Command name + * @return $this + */ public function setName($name) { $this->name = $name; @@ -65,6 +94,12 @@ abstract class AbstractCommand return $this; } + /** + * Sets command's help message + * + * @param string $message Command's help message + * @return $this + */ public function setHelpMessage($message) { $this->helpMessage = $message; @@ -72,6 +107,13 @@ abstract class AbstractCommand return $this; } + /** + * Adds command's usage example + * + * @param string $snippet Example's snippet + * @param string $description Example's description + * @return $this + */ public function addUsageExample($snippet, $description = '') { array_push($this->usageExamples, [$snippet, $description]); @@ -79,6 +121,12 @@ abstract class AbstractCommand return $this; } + /** + * Sets command's syntax message + * + * @param string $message Syntax message + * @return $this + */ public function setSyntaxMessage($message) { $this->syntaxMessage = $message; @@ -86,6 +134,11 @@ abstract class AbstractCommand return $this; } + /** + * Returns formatted command info + * + * @return string + */ public function getInfoMessage() { $indent = str_repeat(" ", 4); From 342a46821403b3b5bbe99f50e05a1acd8803ecca Mon Sep 17 00:00:00 2001 From: Jakub Turek Date: Sun, 8 Mar 2015 12:32:36 +0100 Subject: [PATCH 06/12] Add info about no help information for the command --- Mage/Command/AbstractCommand.php | 6 ++++++ tests/MageTest/Command/AbstractCommandTest.php | 8 ++++++++ 2 files changed, 14 insertions(+) diff --git a/Mage/Command/AbstractCommand.php b/Mage/Command/AbstractCommand.php index 8a0e561..18d045a 100644 --- a/Mage/Command/AbstractCommand.php +++ b/Mage/Command/AbstractCommand.php @@ -180,6 +180,12 @@ abstract class AbstractCommand } } + if (empty($output)) { + $output .= "\n"; + $output .= "Sorry, there's no help for this command at the moment."; + $output .= "\n"; + } + return $output; } } diff --git a/tests/MageTest/Command/AbstractCommandTest.php b/tests/MageTest/Command/AbstractCommandTest.php index b903f7c..52b8278 100644 --- a/tests/MageTest/Command/AbstractCommandTest.php +++ b/tests/MageTest/Command/AbstractCommandTest.php @@ -229,6 +229,14 @@ class AbstractCommandTest extends BaseTest . " mage example\n" . " * Runs the command with lights:\n" . " mage example light\n" + ), + "no_info_at_all" => array( + 'name' => '', + 'helpMessage' => '', + 'examples' => array(), + 'syntax' => '', + 'output' => "\n" + . "Sorry, there's no help for this command at the moment.\n" ) ); } From fb236c1bb3d825bd767c295c8f6a1c0d1e65838f Mon Sep 17 00:00:00 2001 From: Jakub Turek Date: Sun, 8 Mar 2015 12:36:54 +0100 Subject: [PATCH 07/12] Enable running help command in Console --- Mage/Console.php | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/Mage/Console.php b/Mage/Console.php index d9fcbb2..ef29492 100644 --- a/Mage/Console.php +++ b/Mage/Console.php @@ -13,6 +13,7 @@ namespace Mage; use Mage\Command\Factory; use Mage\Command\RequiresEnvironment; use Mage\Console\Colors; + use Exception; use RecursiveDirectoryIterator; use SplFileInfo; @@ -94,6 +95,7 @@ class Console try { // Load configuration $config->load($arguments); + } catch (Exception $exception) { $configError = $exception->getMessage(); } @@ -117,6 +119,7 @@ class Console if ($showGreetings) { if (!self::$logEnabled) { self::output('Starting Magallanes', 0, 2); + } else { self::output('Starting Magallanes', 0, 1); self::log("Logging enabled"); @@ -127,15 +130,20 @@ class Console // Run Command - Check if there is a Configuration Error if ($configError !== false) { self::output('' . $configError . '', 1, 2); + } else { // Run Command and check for Command Requirements try { $command = Factory::get($commandName, $config); - if ($command instanceof RequiresEnvironment) { - if ($config->getEnvironment() === false) { - throw new Exception('You must specify an environment for this command.'); - } + if ($config->getParameter('help')) { + self::output($command->getInfoMessage(), 2); + + return 0; + } + + if ($command instanceof RequiresEnvironment && $config->getEnvironment() === false) { + throw new Exception('You must specify an environment for this command.'); } // Run the Command @@ -306,4 +314,5 @@ class Console || self::$config->general('verbose_logging') || self::$config->environmentConfig('verbose_logging', false); } + } From 48fbefa61907cd1a722e7336d889356ab2eaaa0d Mon Sep 17 00:00:00 2001 From: Jakub Turek Date: Sun, 8 Mar 2015 12:39:34 +0100 Subject: [PATCH 08/12] Correct syntax for arrays --- Mage/Command/AbstractCommand.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mage/Command/AbstractCommand.php b/Mage/Command/AbstractCommand.php index 18d045a..0d45d5f 100644 --- a/Mage/Command/AbstractCommand.php +++ b/Mage/Command/AbstractCommand.php @@ -116,7 +116,7 @@ abstract class AbstractCommand */ public function addUsageExample($snippet, $description = '') { - array_push($this->usageExamples, [$snippet, $description]); + array_push($this->usageExamples, array($snippet, $description)); return $this; } From c49d36a91aa3c3074e69f78a1024298dbeccafd8 Mon Sep 17 00:00:00 2001 From: Jakub Turek Date: Sun, 8 Mar 2015 12:44:37 +0100 Subject: [PATCH 09/12] Fix coverage annotations --- tests/MageTest/Command/AbstractCommandTest.php | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/MageTest/Command/AbstractCommandTest.php b/tests/MageTest/Command/AbstractCommandTest.php index 52b8278..cd21930 100644 --- a/tests/MageTest/Command/AbstractCommandTest.php +++ b/tests/MageTest/Command/AbstractCommandTest.php @@ -246,6 +246,7 @@ class AbstractCommandTest extends BaseTest * @covers ::setHelpMessage * @covers ::addUsageExample * @covers ::setSyntaxMessage + * @covers ::setName * * @dataProvider infoMessageProvider */ From 5db9905ed49e90b762cb2d75286476e88bf9c5cc Mon Sep 17 00:00:00 2001 From: Jakub Turek Date: Sun, 8 Mar 2015 14:46:39 +0100 Subject: [PATCH 10/12] Add sample config for Magallanes' built-in commands --- Mage/Command/BuiltIn/AddCommand.php | 15 ++++++++++++ Mage/Command/BuiltIn/CompileCommand.php | 7 ++++++ Mage/Command/BuiltIn/DeployCommand.php | 16 +++++++++++++ Mage/Command/BuiltIn/InitCommand.php | 14 +++++++++++ Mage/Command/BuiltIn/InstallCommand.php | 18 ++++++++++++++ Mage/Command/BuiltIn/ListCommand.php | 11 +++++++++ Mage/Command/BuiltIn/LockCommand.php | 15 ++++++++++++ Mage/Command/BuiltIn/ReleasesCommand.php | 30 ++++++++++++++++++++++++ Mage/Command/BuiltIn/RollbackCommand.php | 18 ++++++++++++++ Mage/Command/BuiltIn/UnlockCommand.php | 11 +++++++++ Mage/Command/BuiltIn/UpdateCommand.php | 7 ++++++ Mage/Command/BuiltIn/UpgradeCommand.php | 7 ++++++ Mage/Command/BuiltIn/VersionCommand.php | 6 +++++ 13 files changed, 175 insertions(+) diff --git a/Mage/Command/BuiltIn/AddCommand.php b/Mage/Command/BuiltIn/AddCommand.php index 26d9a37..7932e5c 100644 --- a/Mage/Command/BuiltIn/AddCommand.php +++ b/Mage/Command/BuiltIn/AddCommand.php @@ -23,6 +23,21 @@ use Exception; */ class AddCommand extends AbstractCommand { + public function __construct() + { + $this->setName('Add command') + ->setHelpMessage('Generates new config for Magallanes. For now, only adding a environment is possible') + ->setSyntaxMessage('mage add [environment] [--name=env_name] [--enableReleases]') + ->addUsageExample( + 'mage add environment --name=production', + 'Add a production environment' + ) + ->addUsageExample( + 'mage add environment --name=qa --enableReleases', + 'Add a QA environment and enable releasing' + ); + } + /** * Adds new Configuration Elements * @see \Mage\Command\AbstractCommand::run() diff --git a/Mage/Command/BuiltIn/CompileCommand.php b/Mage/Command/BuiltIn/CompileCommand.php index ab92fd2..ae08ab9 100644 --- a/Mage/Command/BuiltIn/CompileCommand.php +++ b/Mage/Command/BuiltIn/CompileCommand.php @@ -21,6 +21,13 @@ use Mage\Compiler; */ class CompileCommand extends AbstractCommand { + public function __construct() + { + $this->setName('Compile command') + ->setHelpMessage('Compiles Magallanes to mage.phar file') + ->setSyntaxMessage('mage compile'); + } + /** * @var Compiler */ diff --git a/Mage/Command/BuiltIn/DeployCommand.php b/Mage/Command/BuiltIn/DeployCommand.php index 9105792..014dea6 100644 --- a/Mage/Command/BuiltIn/DeployCommand.php +++ b/Mage/Command/BuiltIn/DeployCommand.php @@ -103,6 +103,22 @@ class DeployCommand extends AbstractCommand implements RequiresEnvironment */ protected static $failedTasks = 0; + public function __construct() + { + $this->setName('Deploy command') + ->setHelpMessage('Deploys the project into target environment') + ->setSyntaxMessage('mage deploy to:[environment_name]') + ->addUsageExample( + 'mage deploy to:production', + 'Deploy the project into production environment' + ) + ->addUsageExample( + 'mage deploy to:production --overrideRelease', + 'Deploy the project into production environment ' + . 'but skip SkipOnOverride aware tasks' + ); + } + /** * Returns the Status of the Deployment * diff --git a/Mage/Command/BuiltIn/InitCommand.php b/Mage/Command/BuiltIn/InitCommand.php index 326f0e9..a363583 100644 --- a/Mage/Command/BuiltIn/InitCommand.php +++ b/Mage/Command/BuiltIn/InitCommand.php @@ -20,6 +20,20 @@ use Mage\Console; */ class InitCommand extends AbstractCommand { + public function __construct() + { + $this->setName('Initialize command') + ->setHelpMessage('Initialize Magallanes project, create .mage directory with starter configs') + ->setSyntaxMessage('mage init --name=[project_name] [--email=[author_email]]') + ->addUsageExample( + 'mage init --name="My awesome project"', + 'Initialize "My awesome project" configuration' + ) + ->addUsageExample( + 'mage init --name="My project" --email="john.smith@example.com"', + 'Initialize "My project" configuration with email notification enabled for john.smith@example.com' + ); + } /** * Command for Initalize a new Configuration Proyect diff --git a/Mage/Command/BuiltIn/InstallCommand.php b/Mage/Command/BuiltIn/InstallCommand.php index 530e1d7..ffa1dbe 100644 --- a/Mage/Command/BuiltIn/InstallCommand.php +++ b/Mage/Command/BuiltIn/InstallCommand.php @@ -20,6 +20,24 @@ use Mage\Console; */ class InstallCommand extends AbstractCommand { + public function __construct() + { + $this->setName('Install command') + ->setHelpMessage( + 'Installs Magallanes system-widely.' + . ' By default, Magallanes\' going to be installed in /opt/magallanes' + ) + ->setSyntaxMessage('mage install [--installDir=[install_directory]] [--systemWide]') + ->addUsageExample( + 'mage install --installDir=/src/projects/Magellanes', + 'Install Magallanes at /src/projects/Magallanes directory' + ) + ->addUsageExample( + 'mage install --systemWide', + 'Install Magallanes at default directory and creates a symlink in /usr/bin/mage' + ); + } + /** * Installs Magallanes * @see \Mage\Command\AbstractCommand::run() diff --git a/Mage/Command/BuiltIn/ListCommand.php b/Mage/Command/BuiltIn/ListCommand.php index d7dd082..b0ff426 100644 --- a/Mage/Command/BuiltIn/ListCommand.php +++ b/Mage/Command/BuiltIn/ListCommand.php @@ -23,6 +23,17 @@ use Exception; */ class ListCommand extends AbstractCommand { + public function __construct() + { + $this->setName('List command') + ->setHelpMessage('List available configurations. For now, only environments listing available') + ->setSyntaxMessage('mage list [environments]') + ->addUsageExample( + 'mage list environments', + 'List currently configured environments' + ); + } + /** * Command for Listing Configuration Elements * @see \Mage\Command\AbstractCommand::run() diff --git a/Mage/Command/BuiltIn/LockCommand.php b/Mage/Command/BuiltIn/LockCommand.php index 09df123..9e00862 100644 --- a/Mage/Command/BuiltIn/LockCommand.php +++ b/Mage/Command/BuiltIn/LockCommand.php @@ -21,6 +21,21 @@ use Mage\Console; */ class LockCommand extends AbstractCommand implements RequiresEnvironment { + public function __construct() + { + $this->setName('Lock command') + ->setHelpMessage( + "Locks the deployment to given environment and creates a lock file " + . "with lock reason and lock performer.\n" + . "You are going to be prompted to provide this information" + ) + ->setSyntaxMessage('mage lock to:[environment_name]') + ->addUsageExample( + 'mage lock to:production', + 'Create a lock to production environment deployment' + ); + } + /** * Locks the Deployment to a Environment * @see \Mage\Command\AbstractCommand::run() diff --git a/Mage/Command/BuiltIn/ReleasesCommand.php b/Mage/Command/BuiltIn/ReleasesCommand.php index 3a40439..ddbb712 100644 --- a/Mage/Command/BuiltIn/ReleasesCommand.php +++ b/Mage/Command/BuiltIn/ReleasesCommand.php @@ -22,6 +22,36 @@ use Mage\Console; */ class ReleasesCommand extends AbstractCommand implements RequiresEnvironment { + public function __construct() + { + $this->setName('Releases management command') + ->setHelpMessage('Manages releases') + ->setSyntaxMessage( + 'mage releases [list|rollback [--release=[release_id]]] ' + . 'to:[environment_name] [--deleteCurrent]' + ) + ->addUsageExample( + 'mage releases list to:production', + 'List releases on production environment' + ) + ->addUsageExample( + 'mage releases rollback --release=20120101172148 to:production', + 'Rollback 20120101172148 release on production environment' + ) + ->addUsageExample( + 'mage releases rollback --release=-1 to:production', + 'Rollback list release -1 release on production environment' + ) + ->addUsageExample( + 'mage releases rollback --release=0 to:production', + 'Rollback last release on production environment' + ) + ->addUsageExample( + 'mage releases rollback -1 to:production --deleteCurrent', + 'Rollbacks the last release -1 release and removes current release' + ); + } + /** * List the Releases, Rollback to a Release * @see \Mage\Command\AbstractCommand::run() diff --git a/Mage/Command/BuiltIn/RollbackCommand.php b/Mage/Command/BuiltIn/RollbackCommand.php index dea92b0..88db0f9 100644 --- a/Mage/Command/BuiltIn/RollbackCommand.php +++ b/Mage/Command/BuiltIn/RollbackCommand.php @@ -22,6 +22,24 @@ use Mage\Console; */ class RollbackCommand extends AbstractCommand implements RequiresEnvironment { + public function __construct() + { + $this->setName('Rollback command') + ->setHelpMessage('Rollbacks the release by given release id or index') + ->setSyntaxMessage('mage rollback [releaseId] to:[environment_name]') + ->addUsageExample( + 'mage rollback 20120101172148 to:production', + 'Rollbacks the 20120101172148 release on production environment' + ) + ->addUsageExample( + 'mage rollback -1 to:production', + 'Rollbacks the last release -1 release' + ) + ->addUsageExample( + 'mage rollback -1 to:production --deleteCurrent', + 'Rollbacks the last release -1 release and removes current release' + ); + } /** * Rollback a release * @see \Mage\Command\AbstractCommand::run() diff --git a/Mage/Command/BuiltIn/UnlockCommand.php b/Mage/Command/BuiltIn/UnlockCommand.php index 2c7d324..874ccef 100644 --- a/Mage/Command/BuiltIn/UnlockCommand.php +++ b/Mage/Command/BuiltIn/UnlockCommand.php @@ -21,6 +21,17 @@ use Mage\Console; */ class UnlockCommand extends AbstractCommand implements RequiresEnvironment { + public function __construct() + { + $this->setName('Unlock command') + ->setHelpMessage('Unlocks deployment for given environment') + ->setSyntaxMessage('mage unlock to:[environment_name]') + ->addUsageExample( + 'mage unlock to:production', + 'Removes the lock form production environment deployment' + ); + } + /** * Unlocks an Environment * @see \Mage\Command\AbstractCommand::run() diff --git a/Mage/Command/BuiltIn/UpdateCommand.php b/Mage/Command/BuiltIn/UpdateCommand.php index 30cff52..699c90a 100644 --- a/Mage/Command/BuiltIn/UpdateCommand.php +++ b/Mage/Command/BuiltIn/UpdateCommand.php @@ -21,6 +21,13 @@ use Mage\Console; */ class UpdateCommand extends AbstractCommand { + public function __construct() + { + $this->setName('Update command') + ->setHelpMessage('Updates the SCM base code') + ->setSyntaxMessage('mage update'); + } + /** * Updates the SCM Base Code * @see \Mage\Command\AbstractCommand::run() diff --git a/Mage/Command/BuiltIn/UpgradeCommand.php b/Mage/Command/BuiltIn/UpgradeCommand.php index a9861ac..c6083ee 100644 --- a/Mage/Command/BuiltIn/UpgradeCommand.php +++ b/Mage/Command/BuiltIn/UpgradeCommand.php @@ -20,6 +20,13 @@ use Mage\Console; */ class UpgradeCommand extends AbstractCommand { + public function __construct() + { + $this->setName('Upgrade command') + ->setHelpMessage('Upgrades Magallanes') + ->setSyntaxMessage('mage upgrade'); + } + /** * Source for downloading * @var string diff --git a/Mage/Command/BuiltIn/VersionCommand.php b/Mage/Command/BuiltIn/VersionCommand.php index 0c7938c..665e559 100644 --- a/Mage/Command/BuiltIn/VersionCommand.php +++ b/Mage/Command/BuiltIn/VersionCommand.php @@ -20,6 +20,12 @@ use Mage\Console; */ class VersionCommand extends AbstractCommand { + public function __construct() + { + $this->setName('Version command') + ->setHelpMessage('Displays the current version of Magallanes') + ->setSyntaxMessage('mage version'); + } /** * Display the Magallanes Version * @see \Mage\Command\AbstractCommand::run() From 8a5f0ee23ee26c960f0b5b57856d29de78632b26 Mon Sep 17 00:00:00 2001 From: Jakub Turek Date: Sat, 16 May 2015 20:23:48 +0200 Subject: [PATCH 11/12] Fix conflicts after merge --- Mage/Command/BuiltIn/CompileCommand.php | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/Mage/Command/BuiltIn/CompileCommand.php b/Mage/Command/BuiltIn/CompileCommand.php index ae08ab9..38a8049 100644 --- a/Mage/Command/BuiltIn/CompileCommand.php +++ b/Mage/Command/BuiltIn/CompileCommand.php @@ -21,13 +21,6 @@ use Mage\Compiler; */ class CompileCommand extends AbstractCommand { - public function __construct() - { - $this->setName('Compile command') - ->setHelpMessage('Compiles Magallanes to mage.phar file') - ->setSyntaxMessage('mage compile'); - } - /** * @var Compiler */ @@ -40,6 +33,10 @@ class CompileCommand extends AbstractCommand } $this->compiler = $compiler; + + $this->setName('Compile command') + ->setHelpMessage('Compiles Magallanes to mage.phar file') + ->setSyntaxMessage('mage compile'); } /** From b9cf2d1058b7f511ec406a9d550c9b9a178452b8 Mon Sep 17 00:00:00 2001 From: Jakub Turek Date: Sat, 16 May 2015 22:20:20 +0200 Subject: [PATCH 12/12] Fix 'covers' annotations --- tests/MageTest/Command/BuiltIn/CompileCommandTest.php | 1 + tests/MageTest/Command/BuiltIn/ListCommandTest.php | 2 ++ tests/MageTest/Command/BuiltIn/LockCommandTest.php | 1 + tests/MageTest/Command/BuiltIn/UnlockCommandTest.php | 1 + tests/MageTest/Command/BuiltIn/VersionCommandTest.php | 6 ++++-- 5 files changed, 9 insertions(+), 2 deletions(-) diff --git a/tests/MageTest/Command/BuiltIn/CompileCommandTest.php b/tests/MageTest/Command/BuiltIn/CompileCommandTest.php index 44b4486..77af2a3 100644 --- a/tests/MageTest/Command/BuiltIn/CompileCommandTest.php +++ b/tests/MageTest/Command/BuiltIn/CompileCommandTest.php @@ -16,6 +16,7 @@ use malkusch\phpmock\MockBuilder; * @uses malkusch\phpmock\MockBuilder * @uses Mage\Console * @uses Mage\Console\Colors + * @uses Mage\Command\AbstractCommand */ class CompileCommandTest extends BaseTest { diff --git a/tests/MageTest/Command/BuiltIn/ListCommandTest.php b/tests/MageTest/Command/BuiltIn/ListCommandTest.php index 4d193e1..36c1389 100644 --- a/tests/MageTest/Command/BuiltIn/ListCommandTest.php +++ b/tests/MageTest/Command/BuiltIn/ListCommandTest.php @@ -93,6 +93,7 @@ class ListCommandTest extends BaseTest } /** + * @covers ::__construct * @covers ::run * @covers ::listEnvironments * @dataProvider listEnvironmentsProvider @@ -109,6 +110,7 @@ class ListCommandTest extends BaseTest } /** + * @covers ::__construct * @covers ::run */ public function testRunWithInvalidCommand() diff --git a/tests/MageTest/Command/BuiltIn/LockCommandTest.php b/tests/MageTest/Command/BuiltIn/LockCommandTest.php index e56b63f..84ab390 100644 --- a/tests/MageTest/Command/BuiltIn/LockCommandTest.php +++ b/tests/MageTest/Command/BuiltIn/LockCommandTest.php @@ -173,6 +173,7 @@ class LockCommandTest extends BaseTest } /** + * @covers ::__construct * @covers ::run * @dataProvider lockCommandProvider */ diff --git a/tests/MageTest/Command/BuiltIn/UnlockCommandTest.php b/tests/MageTest/Command/BuiltIn/UnlockCommandTest.php index 1732811..be22134 100644 --- a/tests/MageTest/Command/BuiltIn/UnlockCommandTest.php +++ b/tests/MageTest/Command/BuiltIn/UnlockCommandTest.php @@ -98,6 +98,7 @@ class UnlockCommandTest extends BaseTest } /** + * @covers ::__construct * @covers ::run * @dataProvider runProvider */ diff --git a/tests/MageTest/Command/BuiltIn/VersionCommandTest.php b/tests/MageTest/Command/BuiltIn/VersionCommandTest.php index 6565510..d6a85db 100644 --- a/tests/MageTest/Command/BuiltIn/VersionCommandTest.php +++ b/tests/MageTest/Command/BuiltIn/VersionCommandTest.php @@ -8,16 +8,18 @@ use MageTest\TestHelper\BaseTest; use PHPUnit_Framework_TestCase; /** - * @coversDefaultClass Mage\Command\BuiltIn\VersionCommands + * @coversDefaultClass Mage\Command\BuiltIn\VersionCommand * @group Mage_Command_BuildIn_VersionCommand * @uses Mage\Console * @uses Mage\Console\Colors + * @uses Mage\Command\AbstractCommand */ class VersionCommandTest extends BaseTest { /** * @group 175 - * @covers Mage\Command\BuiltIn\VersionCommand::run() + * @covers ::__construct + * @covers ::run() */ public function testRun() {