├── .composer-auth.json
├── .gitattributes
├── .gitignore
├── .styleci.yml
├── .travis.yml
├── CHANGELOG.md
├── LICENSE
├── README.md
├── appveyor.yml
├── composer.json
├── phpunit.xml.dist
├── src
├── Adapter
│ ├── ApplicationAdapter.php
│ ├── ArgsFormatInputDefinition.php
│ ├── ArgsInput.php
│ ├── CommandAdapter.php
│ ├── FormatterAdapter.php
│ ├── IOOutput.php
│ └── StyleConverter.php
├── Api
│ ├── Application
│ │ └── Application.php
│ ├── Args
│ │ ├── Args.php
│ │ ├── ArgsParser.php
│ │ ├── CannotAddArgumentException.php
│ │ ├── CannotAddOptionException.php
│ │ ├── CannotParseArgsException.php
│ │ ├── Format
│ │ │ ├── AbstractOption.php
│ │ │ ├── ArgsFormat.php
│ │ │ ├── ArgsFormatBuilder.php
│ │ │ ├── Argument.php
│ │ │ ├── CommandName.php
│ │ │ ├── CommandOption.php
│ │ │ ├── InvalidValueException.php
│ │ │ └── Option.php
│ │ ├── NoSuchArgumentException.php
│ │ ├── NoSuchOptionException.php
│ │ └── RawArgs.php
│ ├── Command
│ │ ├── CannotAddCommandException.php
│ │ ├── Command.php
│ │ ├── CommandCollection.php
│ │ └── NoSuchCommandException.php
│ ├── Config
│ │ ├── ApplicationConfig.php
│ │ ├── CommandConfig.php
│ │ ├── Config.php
│ │ ├── OptionCommandConfig.php
│ │ └── SubCommandConfig.php
│ ├── Event
│ │ ├── ConfigEvent.php
│ │ ├── ConsoleEvents.php
│ │ ├── PreHandleEvent.php
│ │ └── PreResolveEvent.php
│ ├── Formatter
│ │ ├── Formatter.php
│ │ ├── Style.php
│ │ └── StyleSet.php
│ ├── IO
│ │ ├── IO.php
│ │ ├── IOException.php
│ │ ├── Input.php
│ │ ├── InputStream.php
│ │ ├── Output.php
│ │ └── OutputStream.php
│ └── Resolver
│ │ ├── CannotResolveCommandException.php
│ │ ├── CommandResolver.php
│ │ └── ResolvedCommand.php
├── Args
│ ├── ArgvArgs.php
│ ├── DefaultArgsParser.php
│ ├── StringArgs.php
│ └── TokenParser.php
├── Config
│ └── DefaultApplicationConfig.php
├── ConsoleApplication.php
├── Formatter
│ ├── AnsiFormatter.php
│ ├── DefaultStyleSet.php
│ ├── NullFormatter.php
│ └── PlainFormatter.php
├── Handler
│ ├── CallbackHandler.php
│ ├── DelegatingHandler.php
│ ├── Help
│ │ ├── HelpAsciiDocHandler.php
│ │ ├── HelpHandler.php
│ │ ├── HelpJsonHandler.php
│ │ ├── HelpManHandler.php
│ │ ├── HelpTextHandler.php
│ │ └── HelpXmlHandler.php
│ └── NullHandler.php
├── IO
│ ├── BufferedIO.php
│ ├── ConsoleIO.php
│ ├── InputStream
│ │ ├── NullInputStream.php
│ │ ├── StandardInputStream.php
│ │ ├── StreamInputStream.php
│ │ └── StringInputStream.php
│ └── OutputStream
│ │ ├── BufferedOutputStream.php
│ │ ├── ErrorOutputStream.php
│ │ ├── NullOutputStream.php
│ │ ├── StandardOutputStream.php
│ │ └── StreamOutputStream.php
├── Process
│ └── ProcessLauncher.php
├── Resolver
│ ├── DefaultResolver.php
│ └── ResolveResult.php
├── UI
│ ├── Alignment
│ │ └── LabelAlignment.php
│ ├── Component.php
│ ├── Component
│ │ ├── BorderUtil.php
│ │ ├── CellWrapper.php
│ │ ├── EmptyLine.php
│ │ ├── ExceptionTrace.php
│ │ ├── Grid.php
│ │ ├── LabeledParagraph.php
│ │ ├── NameVersion.php
│ │ ├── Paragraph.php
│ │ └── Table.php
│ ├── Help
│ │ ├── AbstractHelp.php
│ │ ├── ApplicationHelp.php
│ │ └── CommandHelp.php
│ ├── Layout
│ │ └── BlockLayout.php
│ ├── Rectangle.php
│ └── Style
│ │ ├── Alignment.php
│ │ ├── BorderStyle.php
│ │ ├── GridStyle.php
│ │ └── TableStyle.php
└── Util
│ ├── ProcessTitle.php
│ ├── SimilarCommandName.php
│ └── StringUtil.php
└── tests
├── Adapter
├── ApplicationAdapterTest.php
├── ArgsFormatInputDefinitionTest.php
├── ArgsInputTest.php
├── CommandAdapterTest.php
├── FormatterAdapterTest.php
├── IOOutputTest.php
└── StyleConverterTest.php
├── Api
├── Args
│ ├── ArgsTest.php
│ └── Format
│ │ ├── ArgsFormatBuilderTest.php
│ │ ├── ArgsFormatTest.php
│ │ ├── ArgumentTest.php
│ │ ├── CommandNameTest.php
│ │ ├── CommandOptionTest.php
│ │ └── OptionTest.php
├── Command
│ ├── CommandCollectionTest.php
│ └── CommandTest.php
├── Config
│ ├── ApplicationConfigTest.php
│ ├── CommandConfigTest.php
│ ├── ConfigTest.php
│ ├── Fixtures
│ │ └── ConcreteConfig.php
│ ├── OptionCommandConfigTest.php
│ └── SubCommandConfigTest.php
├── Formatter
│ ├── StyleSetTest.php
│ └── StyleTest.php
└── IO
│ ├── InputTest.php
│ └── OutputTest.php
├── Args
├── ArgvArgsTest.php
├── DefaultArgsParserTest.php
└── StringArgsTest.php
├── Config
└── DefaultApplicationConfigTest.php
├── ConsoleApplicationTest.php
├── Fixtures
└── terminate-after-run.php
├── Formatter
├── AnsiFormatterTest.php
└── PlainFormatterTest.php
├── Handler
├── CallbackHandlerTest.php
├── DelegatingHandlerTest.php
└── Help
│ ├── Fixtures
│ ├── ascii-doc
│ │ ├── custom-app.txt
│ │ ├── man-not-found.txt
│ │ ├── prefix-the-command.txt
│ │ ├── the-app.txt
│ │ └── the-command.txt
│ └── man
│ │ ├── custom-app.1
│ │ ├── prefix-the-command.1
│ │ ├── the-app.1
│ │ └── the-command.1
│ ├── HelpAsciiDocHandlerTest.php
│ ├── HelpHandlerTest.php
│ ├── HelpJsonHandlerTest.php
│ ├── HelpManHandlerTest.php
│ ├── HelpTextHandlerTest.php
│ └── HelpXmlHandlerTest.php
├── IO
├── BufferedIOTest.php
├── InputStream
│ ├── StandardInputStreamTest.php
│ ├── StreamInputStreamTest.php
│ └── StringInputStreamTest.php
└── OutputStream
│ ├── BufferedOutputStreamTest.php
│ ├── ErrorOutputStreamTest.php
│ ├── StandardOutputStreamTest.php
│ └── StreamOutputStreamTest.php
├── Process
└── ProcessLauncherTest.php
├── Resolver
└── DefaultResolverTest.php
├── UI
├── Component
│ ├── EmptyLineTest.php
│ ├── ExceptionTraceTest.php
│ ├── GridTest.php
│ ├── LabeledParagraphTest.php
│ ├── ParagraphTest.php
│ └── TableTest.php
├── Help
│ ├── ApplicationHelpTest.php
│ └── CommandHelpTest.php
└── Layout
│ └── BlockLayoutTest.php
└── Util
├── SimilarCommandNameTest.php
└── StringUtilTest.php
/.composer-auth.json:
--------------------------------------------------------------------------------
1 | {
2 | "github-oauth": {
3 | "github.com": "PLEASE DO NOT USE THIS TOKEN IN YOUR OWN PROJECTS/FORKS",
4 | "github.com": "This token is reserved for testing the webmozart/* repositories",
5 | "github.com": "a9debbffdd953ee9b3b82dbc3b807cde2086bb86"
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Make sure heredoc with "\n" endings used in the tests is interpreted equally
2 | # on Windows and Unix
3 | *.php text eol=lf
4 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | /vendor/
2 | composer.lock
3 |
--------------------------------------------------------------------------------
/.styleci.yml:
--------------------------------------------------------------------------------
1 | preset: symfony
2 |
3 | enabled:
4 | - ordered_use
5 | - strict
6 |
7 | disabled:
8 | - empty_return
9 | - phpdoc_annotation_without_dot # This is still buggy: https://github.com/symfony/symfony/pull/19198
10 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: php
2 |
3 | sudo: false
4 |
5 | branches:
6 | only:
7 | - master
8 |
9 | cache:
10 | directories:
11 | - $HOME/.composer/cache/files
12 |
13 | matrix:
14 | include:
15 | - php: 5.3
16 | - php: 5.4
17 | - php: 5.5
18 | - php: 5.6
19 | - php: hhvm
20 | - php: nightly
21 | - php: 7.0
22 | env: COVERAGE=yes
23 | - php: 7.0
24 | env: COMPOSER_FLAGS='--prefer-lowest --prefer-stable'
25 | allow_failures:
26 | - php: hhvm
27 | - php: nightly
28 | fast_finish: true
29 |
30 | before_install:
31 | - if [[ $TRAVIS_PHP_VERSION != hhvm && $COVERAGE != yes ]]; then phpenv config-rm xdebug.ini; fi;
32 | - if [[ $TRAVIS_REPO_SLUG = webmozart/console ]]; then cp .composer-auth.json ~/.composer/auth.json; fi;
33 | - composer self-update
34 |
35 | install: composer update $COMPOSER_FLAGS --prefer-dist --no-interaction
36 |
37 | script: if [[ $COVERAGE = yes ]]; then vendor/bin/phpunit --verbose --coverage-clover=coverage.clover; else vendor/bin/phpunit --verbose; fi
38 |
39 | after_script: if [[ $COVERAGE = yes ]]; then wget https://scrutinizer-ci.com/ocular.phar && php ocular.phar code-coverage:upload --format=php-clover coverage.clover; fi
40 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | Changelog
2 | =========
3 |
4 | * 1.0.0-beta5 (2016-02-05)
5 |
6 | * added support for Symfony 3
7 | * fixed shell argument escaping on Windows
8 |
9 | * 1.0.0-beta4 (2015-10-02)
10 |
11 | * renamed `Input` and implementations to `InputStream`
12 | * renamed `Output` and implementations to `OutputStream`
13 | * turned `IO` into a class
14 | * added `Input`
15 | * added `Output`
16 | * added `isClosed()` to `InputStream` and `OutputStream`
17 | * removed `RawIO` and `FormattedIO`
18 | * changed constructor of `BufferedIO`
19 | * changed constructor of `ConsoleIO`
20 |
21 | * 1.0.0-beta3 (2015-08-24)
22 |
23 | * fixed minimum versions in composer.json
24 |
25 | * 1.0.0-beta2 (2015-05-28)
26 |
27 | * fixed `Paragraph` to not indent empty lines
28 | * added `RawArgs::getScriptName()` and `Args::getScriptName()`
29 | * enabled nice exception rendering for exceptions thrown before the IO is created
30 | * made it possible to pass a callable to `ConsoleApplication::__construct()`
31 |
32 | * 1.0.0-beta (2015-03-19)
33 |
34 | * first release
35 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2014 Bernhard Schussek
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of
6 | this software and associated documentation files (the "Software"), to deal in
7 | the Software without restriction, including without limitation the rights to
8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 | the Software, and to permit persons to whom the Software is furnished to do so,
10 | subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
--------------------------------------------------------------------------------
/appveyor.yml:
--------------------------------------------------------------------------------
1 | build: false
2 | platform: x86
3 | clone_folder: c:\projects\webmozart\console
4 |
5 | branches:
6 | only:
7 | - master
8 |
9 | cache:
10 | - c:\php -> appveyor.yml
11 |
12 | init:
13 | - SET PATH=c:\php;%PATH%
14 | - SET COMPOSER_NO_INTERACTION=1
15 | - SET PHP=1
16 |
17 | install:
18 | - IF EXIST c:\php (SET PHP=0) ELSE (mkdir c:\php)
19 | - cd c:\php
20 | - IF %PHP%==1 appveyor DownloadFile http://windows.php.net/downloads/releases/archives/php-7.0.0-nts-Win32-VC14-x86.zip
21 | - IF %PHP%==1 7z x php-7.0.0-nts-Win32-VC14-x86.zip -y >nul
22 | - IF %PHP%==1 del /Q *.zip
23 | - IF %PHP%==1 echo @php %%~dp0composer.phar %%* > composer.bat
24 | - IF %PHP%==1 copy /Y php.ini-development php.ini
25 | - IF %PHP%==1 echo max_execution_time=1200 >> php.ini
26 | - IF %PHP%==1 echo date.timezone="UTC" >> php.ini
27 | - IF %PHP%==1 echo extension_dir=ext >> php.ini
28 | - IF %PHP%==1 echo extension=php_curl.dll >> php.ini
29 | - IF %PHP%==1 echo extension=php_openssl.dll >> php.ini
30 | - IF %PHP%==1 echo extension=php_mbstring.dll >> php.ini
31 | - IF %PHP%==1 echo extension=php_fileinfo.dll >> php.ini
32 | - appveyor DownloadFile https://getcomposer.org/composer.phar
33 | - cd c:\projects\webmozart\console
34 | - mkdir %APPDATA%\Composer
35 | - IF %APPVEYOR_REPO_NAME%==webmozart/console copy /Y .composer-auth.json %APPDATA%\Composer\auth.json
36 | - composer update --prefer-dist --no-progress --ansi
37 |
38 | test_script:
39 | - cd c:\projects\webmozart\console
40 | - vendor\bin\phpunit.bat --verbose
41 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "webmozart/console",
3 | "description": "A usable, beautiful and easily testable console toolkit written in PHP.",
4 | "license": "MIT",
5 | "authors": [
6 | {
7 | "name": "Bernhard Schussek",
8 | "email": "bschussek@gmail.com"
9 | }
10 | ],
11 | "require": {
12 | "php": ">=5.3.9",
13 | "webmozart/assert": "^1.0",
14 | "symfony/console": "^2.7|^3.0",
15 | "symfony/process": "^2.5|^3.0",
16 | "symfony/event-dispatcher": "^2.5|^3.0"
17 | },
18 | "require-dev": {
19 | "symfony/filesystem": "^2.3|^3.0",
20 | "phpunit/phpunit": "^4.6",
21 | "sebastian/version": "^1.0.1"
22 | },
23 | "autoload": {
24 | "psr-4": {
25 | "Webmozart\\Console\\": "src/"
26 | }
27 | },
28 | "autoload-dev": {
29 | "psr-4": {
30 | "Webmozart\\Console\\Tests\\": "tests/"
31 | }
32 | },
33 | "extra": {
34 | "branch-alias": {
35 | "dev-master": "1.0-dev"
36 | }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/phpunit.xml.dist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | ./tests/
7 |
8 |
9 |
10 |
11 |
12 |
13 | ./src/
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/src/Adapter/ApplicationAdapter.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Webmozart\Console\Adapter;
13 |
14 | use Exception;
15 | use Symfony\Component\Console\Application;
16 | use Symfony\Component\Console\Input\InputInterface;
17 | use Symfony\Component\Console\Output\OutputInterface;
18 | use Webmozart\Assert\Assert;
19 |
20 | /**
21 | * Adapts an `Application` instance of this package to Symfony's
22 | * {@link Application} API.
23 | *
24 | * @since 1.0
25 | *
26 | * @author Bernhard Schussek
27 | */
28 | class ApplicationAdapter extends Application
29 | {
30 | /**
31 | * @var \Webmozart\Console\Api\Application\Application
32 | */
33 | private $adaptedApplication;
34 |
35 | /**
36 | * @var CommandAdapter
37 | */
38 | private $currentCommand;
39 |
40 | /**
41 | * Creates the application.
42 | *
43 | * @param \Webmozart\Console\Api\Application\Application $application
44 | */
45 | public function __construct(\Webmozart\Console\Api\Application\Application $application)
46 | {
47 | $this->adaptedApplication = $application;
48 |
49 | $config = $application->getConfig();
50 |
51 | parent::__construct($config->getDisplayName(), $config->getVersion());
52 |
53 | if ($dispatcher = $config->getEventDispatcher()) {
54 | $this->setDispatcher($dispatcher);
55 | }
56 |
57 | $this->setAutoExit($config->isTerminatedAfterRun());
58 | $this->setCatchExceptions($config->isExceptionCaught());
59 |
60 | foreach ($application->getCommands() as $command) {
61 | $this->add(new CommandAdapter($command, $this));
62 | }
63 | }
64 |
65 | /**
66 | * @return \Webmozart\Console\Api\Application\Application
67 | */
68 | public function getAdaptedApplication()
69 | {
70 | return $this->adaptedApplication;
71 | }
72 |
73 | /**
74 | * {@inheritdoc}
75 | */
76 | public function doRun(InputInterface $input, OutputInterface $output)
77 | {
78 | /* @var ArgsInput $input */
79 | Assert::isInstanceOf($input, 'Webmozart\Console\Adapter\ArgsInput');
80 |
81 | $rawArgs = $input->getRawArgs();
82 | $resolvedCommand = $this->adaptedApplication->resolveCommand($rawArgs);
83 |
84 | // Add parsed Args to the adapter
85 | $input = new ArgsInput($rawArgs, $resolvedCommand->getArgs());
86 |
87 | // Don't use $this->get() as get() does not work for sub-commands
88 | $this->currentCommand = new CommandAdapter($resolvedCommand->getCommand(), $this);
89 |
90 | try {
91 | $result = parent::doRun($input, $output);
92 | $this->currentCommand = null;
93 | } catch (Exception $e) {
94 | $this->currentCommand = null;
95 |
96 | throw $e;
97 | }
98 |
99 | return $result;
100 | }
101 |
102 | /**
103 | * {@inheritdoc}
104 | */
105 | protected function getCommandName(InputInterface $input)
106 | {
107 | // This method must return something, otherwise the base class tries
108 | // to set the "command" argument which doesn't usually exist
109 | return 'command-name';
110 | }
111 |
112 | /**
113 | * {@inheritdoc}
114 | */
115 | public function find($name)
116 | {
117 | return $this->currentCommand;
118 | }
119 |
120 | /**
121 | * {@inheritdoc}
122 | */
123 | protected function getDefaultInputDefinition()
124 | {
125 | return new ArgsFormatInputDefinition($this->adaptedApplication->getGlobalArgsFormat());
126 | }
127 |
128 | /**
129 | * {@inheritdoc}
130 | */
131 | protected function getDefaultCommands()
132 | {
133 | return array();
134 | }
135 |
136 | /**
137 | * {@inheritdoc}
138 | */
139 | protected function getDefaultHelperSet()
140 | {
141 | return $this->adaptedApplication->getConfig()->getHelperSet();
142 | }
143 | }
144 |
--------------------------------------------------------------------------------
/src/Adapter/FormatterAdapter.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Webmozart\Console\Adapter;
13 |
14 | use Symfony\Component\Console\Formatter\OutputFormatterInterface;
15 | use Symfony\Component\Console\Formatter\OutputFormatterStyleInterface;
16 | use Webmozart\Console\Api\Formatter\Formatter;
17 |
18 | /**
19 | * Adapts a {@link Formatter} instance to Symfony's
20 | * {@link OutputFormatterInterface} API.
21 | *
22 | * @since 1.0
23 | *
24 | * @author Bernhard Schussek
25 | */
26 | class FormatterAdapter implements OutputFormatterInterface
27 | {
28 | /**
29 | * @var Formatter
30 | */
31 | private $adaptedFormatter;
32 |
33 | /**
34 | * @var bool
35 | */
36 | private $decorated = true;
37 |
38 | /**
39 | * Creates the adapter.
40 | *
41 | * @param Formatter $adaptedFormatter The adapted formatter.
42 | */
43 | public function __construct(Formatter $adaptedFormatter)
44 | {
45 | $this->adaptedFormatter = $adaptedFormatter;
46 | }
47 |
48 | /**
49 | * Returns the adapted formatter.
50 | *
51 | * @return Formatter The adapted formatter.
52 | */
53 | public function getAdaptedFormatter()
54 | {
55 | return $this->adaptedFormatter;
56 | }
57 |
58 | /**
59 | * {@inheritdoc}
60 | */
61 | public function setDecorated($decorated)
62 | {
63 | $this->decorated = $decorated;
64 | }
65 |
66 | /**
67 | * {@inheritdoc}
68 | */
69 | public function isDecorated()
70 | {
71 | return $this->decorated;
72 | }
73 |
74 | /**
75 | * {@inheritdoc}
76 | */
77 | public function setStyle($name, OutputFormatterStyleInterface $style)
78 | {
79 | }
80 |
81 | /**
82 | * {@inheritdoc}
83 | */
84 | public function hasStyle($name)
85 | {
86 | }
87 |
88 | /**
89 | * {@inheritdoc}
90 | */
91 | public function getStyle($name)
92 | {
93 | }
94 |
95 | /**
96 | * {@inheritdoc}
97 | */
98 | public function format($message)
99 | {
100 | if ($this->decorated) {
101 | return $this->adaptedFormatter->format($message);
102 | }
103 |
104 | return $this->adaptedFormatter->removeFormat($message);
105 | }
106 | }
107 |
--------------------------------------------------------------------------------
/src/Adapter/StyleConverter.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Webmozart\Console\Adapter;
13 |
14 | use Symfony\Component\Console\Formatter\OutputFormatterStyle;
15 | use Webmozart\Console\Api\Formatter\Style;
16 |
17 | /**
18 | * Converts {@link Style} instances to Symfony's {@link OutputFormatterStyle}.
19 | *
20 | * @since 1.0
21 | *
22 | * @author Bernhard Schussek
23 | */
24 | class StyleConverter
25 | {
26 | /**
27 | * Converts a {@link Style} instance to an {@link OutputFormatterStyle}.
28 | *
29 | * @param Style $style The style to convert.
30 | *
31 | * @return OutputFormatterStyle The converted style.
32 | */
33 | public static function convert(Style $style)
34 | {
35 | $options = array();
36 |
37 | if ($style->isBold()) {
38 | $options[] = 'bold';
39 | }
40 |
41 | if ($style->isBlinking()) {
42 | $options[] = 'blink';
43 | }
44 |
45 | if ($style->isUnderlined()) {
46 | $options[] = 'underscore';
47 | }
48 |
49 | if ($style->isInverse()) {
50 | $options[] = 'reverse';
51 | }
52 |
53 | if ($style->isHidden()) {
54 | $options[] = 'conceal';
55 | }
56 |
57 | return new OutputFormatterStyle($style->getForegroundColor(), $style->getBackgroundColor(), $options);
58 | }
59 |
60 | private function __construct()
61 | {
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/src/Api/Args/ArgsParser.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Webmozart\Console\Api\Args;
13 |
14 | use Webmozart\Console\Api\Args\Format\ArgsFormat;
15 |
16 | /**
17 | * Parses raw console arguments and returns the parsed arguments.
18 | *
19 | * @since 1.0
20 | *
21 | * @author Bernhard Schussek
22 | */
23 | interface ArgsParser
24 | {
25 | /**
26 | * Parses the raw console arguments and returns the parsed arguments.
27 | *
28 | * @param RawArgs $args The raw console arguments.
29 | * @param ArgsFormat $format The argument format.
30 | * @param bool $lenient Whether the parser should ignore parse errors.
31 | * If `true`, the parser will not throw any
32 | * exceptions when parse errors occur.
33 | *
34 | * @return Args The parsed console arguments.
35 | *
36 | * @throws CannotParseArgsException If the arguments cannot be parsed.
37 | */
38 | public function parseArgs(RawArgs $args, ArgsFormat $format, $lenient = false);
39 | }
40 |
--------------------------------------------------------------------------------
/src/Api/Args/CannotAddArgumentException.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Webmozart\Console\Api\Args;
13 |
14 | use Exception;
15 | use RuntimeException;
16 |
17 | /**
18 | * Thrown when an argument cannot be added.
19 | *
20 | * @since 1.0
21 | *
22 | * @author Bernhard Schussek
23 | */
24 | class CannotAddArgumentException extends RuntimeException
25 | {
26 | /**
27 | * Code: The argument exists already.
28 | */
29 | const EXISTS_ALREADY = 1;
30 |
31 | /**
32 | * Code: An argument was added after a multi-valued argument.
33 | */
34 | const MULTI_VALUED_EXISTS = 2;
35 |
36 | /**
37 | * Code: A required argument was added after an optional argument.
38 | */
39 | const REQUIRED_AFTER_OPTIONAL = 3;
40 |
41 | /**
42 | * Creates an exception with code {@link EXISTS_ALREADY}.
43 | *
44 | * @param string $name The argument name.
45 | * @param Exception $cause The exception that caused this exception.
46 | *
47 | * @return static The created exception.
48 | */
49 | public static function existsAlready($name, Exception $cause = null)
50 | {
51 | return new static(sprintf(
52 | 'An argument named "%s" exists already.',
53 | $name
54 | ), self::EXISTS_ALREADY, $cause);
55 | }
56 |
57 | /**
58 | * Creates an exception with code {@link ADD_AFTER_MULTI_VALUED}.
59 | *
60 | * @param Exception $cause The exception that caused this exception.
61 | *
62 | * @return static The created exception.
63 | */
64 | public static function cannotAddAfterMultiValued(Exception $cause = null)
65 | {
66 | return new static(
67 | 'Cannot add an argument after a multi-valued argument.',
68 | self::MULTI_VALUED_EXISTS,
69 | $cause
70 | );
71 | }
72 |
73 | /**
74 | * Creates an exception with code {@link ADD_REQUIRED_AFTER_OPTIONAL}.
75 | *
76 | * @param Exception $cause The exception that caused this exception.
77 | *
78 | * @return static The created exception.
79 | */
80 | public static function cannotAddRequiredAfterOptional(Exception $cause = null)
81 | {
82 | return new static(
83 | 'Cannot add a required argument after an optional one.',
84 | self::REQUIRED_AFTER_OPTIONAL,
85 | $cause
86 | );
87 | }
88 | }
89 |
--------------------------------------------------------------------------------
/src/Api/Args/CannotAddOptionException.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Webmozart\Console\Api\Args;
13 |
14 | use Exception;
15 | use RuntimeException;
16 |
17 | /**
18 | * Thrown when an option cannot be added.
19 | *
20 | * @since 1.0
21 | *
22 | * @author Bernhard Schussek
23 | */
24 | class CannotAddOptionException extends RuntimeException
25 | {
26 | /**
27 | * Creates an exception for a duplicate option.
28 | *
29 | * @param string $name The option name.
30 | * @param Exception $cause The exception that caused this exception.
31 | *
32 | * @return static The created exception.
33 | */
34 | public static function existsAlready($name, Exception $cause = null)
35 | {
36 | return new static(sprintf(
37 | 'An option named "%s%s" exists already.',
38 | strlen($name) > 1 ? '--' : '-',
39 | $name
40 | ), 0, $cause);
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/Api/Args/CannotParseArgsException.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Webmozart\Console\Api\Args;
13 |
14 | use RuntimeException;
15 |
16 | /**
17 | * Thrown when console arguments cannot be parsed.
18 | *
19 | * @since 1.0
20 | *
21 | * @author Bernhard Schussek
22 | */
23 | class CannotParseArgsException extends RuntimeException
24 | {
25 | }
26 |
--------------------------------------------------------------------------------
/src/Api/Args/Format/CommandName.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Webmozart\Console\Api\Args\Format;
13 |
14 | use Webmozart\Assert\Assert;
15 |
16 | /**
17 | * A command name in the console arguments.
18 | *
19 | * The command name determines which command should be executed. The console
20 | * input may contain one or several command names.
21 | *
22 | * In the example below, the console arguments contain the two command names
23 | * "server" and "add":
24 | *
25 | * ```
26 | * $ console server add localhost
27 | * ```
28 | *
29 | * The last part "localhost" is the argument to the "server add" command.
30 | *
31 | * @since 1.0
32 | *
33 | * @author Bernhard Schussek
34 | *
35 | * @see CommandOption, ArgsFormat
36 | */
37 | class CommandName
38 | {
39 | /**
40 | * @var string
41 | */
42 | private $string;
43 |
44 | /**
45 | * @var string[]
46 | */
47 | private $aliases;
48 |
49 | /**
50 | * Creates a new command name.
51 | *
52 | * @param string $string The command name.
53 | * @param string[] $aliases The alias names.
54 | */
55 | public function __construct($string, array $aliases = array())
56 | {
57 | Assert::string($string, 'The command name must be a string. Got: %s');
58 | Assert::notEmpty($string, 'The command name must not be empty.');
59 | Assert::regex($string, '~^[a-zA-Z0-9\-]+$~', 'The command name must contain letters, digits and hyphens only. Got: "%s"');
60 |
61 | Assert::allString($aliases, 'The command aliases must be strings. Got: %s');
62 | Assert::allNotEmpty($aliases, 'The command aliases must not be empty.');
63 | Assert::allRegex($aliases, '~^[a-zA-Z0-9\-]+$~', 'The command aliases must contain letters, digits and hyphens only. Got: "%s"');
64 |
65 | $this->string = $string;
66 | $this->aliases = $aliases;
67 | }
68 |
69 | /**
70 | * Returns the command name as string.
71 | *
72 | * @return string The command name.
73 | */
74 | public function toString()
75 | {
76 | return $this->string;
77 | }
78 |
79 | /**
80 | * Returns the alias names.
81 | *
82 | * @return string[] The aliases of the command name.
83 | */
84 | public function getAliases()
85 | {
86 | return $this->aliases;
87 | }
88 |
89 | /**
90 | * Returns whether a string matches the command name or one of its aliases.
91 | *
92 | * @param string $string The string to test.
93 | *
94 | * @return bool Returns `true` if the given string matches the command name
95 | * or one of its aliases and `false` otherwise.
96 | */
97 | public function match($string)
98 | {
99 | return $this->string === $string || in_array($string, $this->aliases, true);
100 | }
101 |
102 | /**
103 | * Casts the command name to a string.
104 | *
105 | * @return string The command name.
106 | */
107 | public function __toString()
108 | {
109 | return $this->string;
110 | }
111 | }
112 |
--------------------------------------------------------------------------------
/src/Api/Args/Format/CommandOption.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Webmozart\Console\Api\Args\Format;
13 |
14 | use Webmozart\Assert\Assert;
15 |
16 | /**
17 | * A command option in the console arguments.
18 | *
19 | * The command names and command options determine which command is executed.
20 | *
21 | * In the example below, the console arguments contain the command name "server"
22 | * and the command option "delete":
23 | *
24 | * ```
25 | * $ console server --delete localhost
26 | * $ console server -d localhost
27 | * ```
28 | *
29 | * The last part "localhost" is the argument to the "server --delete" command.
30 | *
31 | * @since 1.0
32 | *
33 | * @author Bernhard Schussek
34 | *
35 | * @see CommandName, ArgsFormat
36 | */
37 | class CommandOption extends AbstractOption
38 | {
39 | /**
40 | * @var string[]
41 | */
42 | private $longAliases = array();
43 |
44 | /**
45 | * @var string[]
46 | */
47 | private $shortAliases = array();
48 |
49 | /**
50 | * Creates the command option.
51 | *
52 | * @param string $longName The long option name.
53 | * @param string|null $shortName The short option name.
54 | * @param string[] $aliases A list of alias names.
55 | * @param int $flags A bitwise combination of the option flag
56 | * constants.
57 | * @param string $description A human-readable description of the option.
58 | *
59 | * @throws InvalidValueException If the default value is invalid.
60 | */
61 | public function __construct($longName, $shortName = null, array $aliases = array(), $flags = 0, $description = null)
62 | {
63 | parent::__construct($longName, $shortName, $flags, $description);
64 |
65 | foreach ($aliases as $key => $alias) {
66 | $alias = $this->removeDashPrefix($alias);
67 |
68 | if (1 === strlen($alias)) {
69 | $this->assertShortAliasValid($alias);
70 | $this->shortAliases[] = $alias;
71 | } else {
72 | $this->assertLongAliasValid($alias);
73 | $this->longAliases[] = $alias;
74 | }
75 | }
76 | }
77 |
78 | /**
79 | * Returns all long alias names.
80 | *
81 | * @return string[] The long alias names.
82 | */
83 | public function getLongAliases()
84 | {
85 | return $this->longAliases;
86 | }
87 |
88 | /**
89 | * Returns all short alias names.
90 | *
91 | * @return string[] The short alias names.
92 | */
93 | public function getShortAliases()
94 | {
95 | return $this->shortAliases;
96 | }
97 |
98 | private function removeDashPrefix($string)
99 | {
100 | if ('--' === substr($string, 0, 2)) {
101 | $string = substr($string, 2);
102 | } elseif (isset($string[0]) && '-' === $string[0]) {
103 | $string = substr($string, 1);
104 | }
105 |
106 | return $string;
107 | }
108 |
109 | private function assertLongAliasValid($alias)
110 | {
111 | Assert::string($alias, 'An option alias must be a string or null. Got: %s');
112 | Assert::notEmpty($alias, 'An option alias must not be empty.');
113 | Assert::startsWithLetter($alias, 'A long option alias must start with a letter.');
114 | Assert::regex($alias, '~^[a-zA-Z0-9\-]+$~', 'A long option alias must contain letters, digits and hyphens only.');
115 | }
116 |
117 | private function assertShortAliasValid($alias)
118 | {
119 | Assert::string($alias, 'An option alias must be a string or null. Got: %s');
120 | Assert::notEmpty($alias, 'An option alias must not be empty.');
121 | Assert::regex($alias, '~^[a-zA-Z]$~', 'A short option alias must be exactly one letter. Got: "%s"');
122 | }
123 | }
124 |
--------------------------------------------------------------------------------
/src/Api/Args/Format/InvalidValueException.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Webmozart\Console\Api\Args\Format;
13 |
14 | use Exception;
15 |
16 | /**
17 | * Thrown when the value of an option or an argument is invalid.
18 | *
19 | * @since 1.0
20 | *
21 | * @author Bernhard Schussek
22 | */
23 | class InvalidValueException extends Exception
24 | {
25 | }
26 |
--------------------------------------------------------------------------------
/src/Api/Args/NoSuchArgumentException.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Webmozart\Console\Api\Args;
13 |
14 | use Exception;
15 | use RuntimeException;
16 |
17 | /**
18 | * Thrown when a non-existing argument is accessed.
19 | *
20 | * @since 1.0
21 | *
22 | * @author Bernhard Schussek
23 | */
24 | class NoSuchArgumentException extends RuntimeException
25 | {
26 | /**
27 | * Creates an exception for the given argument name.
28 | *
29 | * @param string $name The argument name.
30 | * @param int $code The exception code.
31 | * @param Exception $cause The exception that caused this exception.
32 | *
33 | * @return static The created exception.
34 | */
35 | public static function forArgumentName($name, $code = 0, Exception $cause = null)
36 | {
37 | return new static(sprintf(
38 | 'The argument "%s" does not exist.',
39 | $name
40 | ), $code, $cause);
41 | }
42 |
43 | /**
44 | * Creates an exception for the given argument position.
45 | *
46 | * @param int $position The argument position.
47 | * @param int $code The exception code.
48 | * @param Exception $cause The exception that caused this exception.
49 | *
50 | * @return static The created exception.
51 | */
52 | public static function forPosition($position, $code = 0, Exception $cause = null)
53 | {
54 | return new static(sprintf(
55 | 'The argument at position %s does not exist.',
56 | $position
57 | ), $code, $cause);
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/src/Api/Args/NoSuchOptionException.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Webmozart\Console\Api\Args;
13 |
14 | use Exception;
15 | use RuntimeException;
16 |
17 | /**
18 | * Thrown when a non-existing option is accessed.
19 | *
20 | * @since 1.0
21 | *
22 | * @author Bernhard Schussek
23 | */
24 | class NoSuchOptionException extends RuntimeException
25 | {
26 | /**
27 | * Creates an exception for the given option name.
28 | *
29 | * @param string $name The option name.
30 | * @param int $code The exception code.
31 | * @param Exception $cause The exception that caused this exception.
32 | *
33 | * @return static The created exception.
34 | */
35 | public static function forOptionName($name, $code = 0, Exception $cause = null)
36 | {
37 | return new static(sprintf(
38 | 'The option "%s%s" does not exist.',
39 | strlen($name) > 1 ? '--' : '-',
40 | $name
41 | ), $code, $cause);
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/src/Api/Args/RawArgs.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Webmozart\Console\Api\Args;
13 |
14 | /**
15 | * The unparsed console arguments.
16 | *
17 | * Implementations of this class represent the arguments that a user passes
18 | * when calling the console. For example:
19 | *
20 | * ```
21 | * $ console server add --port 80 localhost
22 | * ```
23 | *
24 | * In this case, the raw arguments contain the tokens:
25 | *
26 | * * "server"
27 | * * "add"
28 | * * "--port"
29 | * * "80"
30 | * * "localhost"
31 | *
32 | * With an implementation of {@link ArgsParser} and a configured
33 | * {@link ArgsFormat}, the {@link RawArgs} instance can be converted into an
34 | * {@link Args} instance:
35 | *
36 | * ```php
37 | * $format = ArgsFormat::build()
38 | * ->addCommandName(new CommandName('server'))
39 | * ->addCommandName(new CommandName('add'))
40 | * ->addOption(new Option('port', 'p', Option::VALUE_REQUIRED | Option::INTEGER))
41 | * ->addArgument(new Argument('host', Argument::REQUIRED))
42 | * ->getFormat();
43 | *
44 | * $args = $parser->parseArgs($rawArgs, $format);
45 | * ```
46 | *
47 | * The {@link Args} instance can be used to access the options and arguments of
48 | * a command in a convenient way.
49 | *
50 | * @since 1.0
51 | *
52 | * @author Bernhard Schussek
53 | *
54 | * @see Args, ArgsFormat, ArgsParser
55 | */
56 | interface RawArgs
57 | {
58 | /**
59 | * Returns the PHP script as it was called on the console.
60 | *
61 | * @return string|null The script name or null if no script name is
62 | * available.
63 | */
64 | public function getScriptName();
65 |
66 | /**
67 | * Returns the tokens of the console arguments.
68 | *
69 | * @return string[] The argument tokens.
70 | */
71 | public function getTokens();
72 |
73 | /**
74 | * Returns whether the console arguments contain a given token.
75 | *
76 | * @param string $token The token to look for.
77 | *
78 | * @return bool Returns `true` if the arguments contain the token and
79 | * `false` otherwise.
80 | */
81 | public function hasToken($token);
82 |
83 | /**
84 | * Returns the console arguments as string.
85 | *
86 | * @param bool $scriptName Whether to include the script name in the output.
87 | *
88 | * @return string The arguments as string.
89 | */
90 | public function toString($scriptName = true);
91 | }
92 |
--------------------------------------------------------------------------------
/src/Api/Command/CannotAddCommandException.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Webmozart\Console\Api\Command;
13 |
14 | use Exception;
15 | use RuntimeException;
16 |
17 | /**
18 | * Thrown when two commands have the same name.
19 | *
20 | * @since 1.0
21 | *
22 | * @author Bernhard Schussek
23 | */
24 | class CannotAddCommandException extends RuntimeException
25 | {
26 | /**
27 | * Code: A command with the same name exists.
28 | */
29 | const NAME_EXISTS = 1;
30 |
31 | /**
32 | * Code: An option with the same name exists.
33 | */
34 | const OPTION_EXISTS = 2;
35 |
36 | /**
37 | * Code: The command name is empty.
38 | */
39 | const NAME_EMPTY = 3;
40 |
41 | /**
42 | * Creates an exception for the code {@link NAME_EXISTS}.
43 | *
44 | * @param string $name The command name.
45 | * @param Exception $cause The exception that caused this exception.
46 | *
47 | * @return static The created exception.
48 | */
49 | public static function nameExists($name, Exception $cause = null)
50 | {
51 | return new static(sprintf(
52 | 'A command named "%s" exists already.',
53 | $name
54 | ), self::NAME_EXISTS, $cause);
55 | }
56 |
57 | /**
58 | * Creates an exception for the code {@link OPTION_EXISTS}.
59 | *
60 | * @param string $name The command name.
61 | * @param Exception $cause The exception that caused this exception.
62 | *
63 | * @return static The created exception.
64 | */
65 | public static function optionExists($name, Exception $cause = null)
66 | {
67 | return new static(sprintf(
68 | 'An option named "%s%s" exists already.',
69 | strlen($name) > 1 ? '--' : '-',
70 | $name
71 | ), self::OPTION_EXISTS, $cause);
72 | }
73 |
74 | /**
75 | * Creates an exception for the code {@link NAME_EMPTY}.
76 | *
77 | * @param Exception $cause The exception that caused this exception.
78 | *
79 | * @return static The created exception.
80 | */
81 | public static function nameEmpty(Exception $cause = null)
82 | {
83 | return new static('The command name must be set.', self::NAME_EMPTY, $cause);
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/src/Api/Command/NoSuchCommandException.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Webmozart\Console\Api\Command;
13 |
14 | use Exception;
15 | use RuntimeException;
16 |
17 | /**
18 | * Thrown when a command was not found.
19 | *
20 | * @since 1.0
21 | *
22 | * @author Bernhard Schussek
23 | */
24 | class NoSuchCommandException extends RuntimeException
25 | {
26 | /**
27 | * Creates an exception for the given command name.
28 | *
29 | * @param string $name The command name.
30 | * @param int $code The exception code.
31 | * @param Exception $cause The exception that caused this exception.
32 | *
33 | * @return static The created exception.
34 | */
35 | public static function forCommandName($name, $code = 0, Exception $cause = null)
36 | {
37 | return new static(sprintf(
38 | 'The command "%s" does not exist.',
39 | $name
40 | ), $code, $cause);
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/Api/Config/SubCommandConfig.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Webmozart\Console\Api\Config;
13 |
14 | /**
15 | * The configuration of an console sub-command.
16 | *
17 | * A sub-command is defined within the scope of another command. For example,
18 | * in the command `server add `, the command "add" is a sub-command of the
19 | * "server" command.
20 | *
21 | * @since 1.0
22 | *
23 | * @author Bernhard Schussek
24 | *
25 | * @see OptionCommandConfig
26 | */
27 | class SubCommandConfig extends CommandConfig
28 | {
29 | /**
30 | * @var CommandConfig
31 | */
32 | private $parentConfig;
33 |
34 | /**
35 | * Creates a new configuration.
36 | *
37 | * @param string $name The name of the command.
38 | * @param CommandConfig $parentConfig The command configuration that
39 | * contains this configuration.
40 | */
41 | public function __construct($name = null, CommandConfig $parentConfig = null)
42 | {
43 | parent::__construct($name);
44 |
45 | if ($parentConfig) {
46 | $this->setParentConfig($parentConfig);
47 | }
48 | }
49 |
50 | /**
51 | * Returns the parent command configuration.
52 | *
53 | * @return CommandConfig The parent command configuration.
54 | */
55 | public function getParentConfig()
56 | {
57 | return $this->parentConfig;
58 | }
59 |
60 | /**
61 | * Sets the parent command configuration.
62 | *
63 | * @param CommandConfig $parentConfig The parent command configuration.
64 | */
65 | public function setParentConfig(CommandConfig $parentConfig)
66 | {
67 | $this->parentConfig = $parentConfig;
68 |
69 | if ($parentConfig->getApplicationConfig()) {
70 | $this->setApplicationConfig($parentConfig->getApplicationConfig());
71 | }
72 | }
73 |
74 | /**
75 | * Ends the block when dynamically configuring a nested configuration.
76 | *
77 | * This method is usually used together with
78 | * {@link CommandConfig::beginSubCommand()},
79 | * {@link CommandConfig::beginOptionCommand()} or
80 | * {@link CommandConfig::beginDefaultCommand()}:
81 | *
82 | * ```php
83 | * $config
84 | * ->beginSubCommand('add')
85 | * // ...
86 | * ->end()
87 | *
88 | * // ...
89 | * ;
90 | * ```
91 | *
92 | * @return CommandConfig|SubCommandConfig|OptionCommandConfig The parent command configuration.
93 | */
94 | public function end()
95 | {
96 | return $this->parentConfig;
97 | }
98 |
99 | /**
100 | * {@inheritdoc}
101 | */
102 | protected function getDefaultHelperSet()
103 | {
104 | return $this->parentConfig
105 | ? $this->parentConfig->getHelperSet()
106 | : parent::getDefaultHelperSet();
107 | }
108 |
109 | /**
110 | * {@inheritdoc}
111 | */
112 | protected function getDefaultHandler()
113 | {
114 | return $this->parentConfig
115 | ? $this->parentConfig->getHandler()
116 | : parent::getDefaultHandler();
117 | }
118 |
119 | /**
120 | * {@inheritdoc}
121 | */
122 | protected function getDefaultHandlerMethod()
123 | {
124 | return $this->parentConfig
125 | ? $this->parentConfig->getHandlerMethod()
126 | : parent::getDefaultHandlerMethod();
127 | }
128 |
129 | /**
130 | * {@inheritdoc}
131 | */
132 | protected function getDefaultArgsParser()
133 | {
134 | return $this->parentConfig
135 | ? $this->parentConfig->getArgsParser()
136 | : parent::getDefaultArgsParser();
137 | }
138 |
139 | /**
140 | * {@inheritdoc}
141 | */
142 | protected function getDefaultLenientArgsParsing()
143 | {
144 | return $this->parentConfig
145 | ? $this->parentConfig->isLenientArgsParsingEnabled()
146 | : parent::getDefaultLenientArgsParsing();
147 | }
148 | }
149 |
--------------------------------------------------------------------------------
/src/Api/Event/ConfigEvent.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Webmozart\Console\Api\Event;
13 |
14 | use Symfony\Component\EventDispatcher\Event;
15 | use Webmozart\Console\Api\Config\ApplicationConfig;
16 |
17 | /**
18 | * Dispatched after the configuration is built.
19 | *
20 | * Use this event to add custom configuration to the application.
21 | *
22 | * @since 1.0
23 | *
24 | * @author Bernhard Schussek
25 | */
26 | class ConfigEvent extends Event
27 | {
28 | /**
29 | * @var ApplicationConfig
30 | */
31 | private $config;
32 |
33 | /**
34 | * Creates the event.
35 | *
36 | * @param ApplicationConfig $config The application configuration.
37 | */
38 | public function __construct(ApplicationConfig $config)
39 | {
40 | $this->config = $config;
41 | }
42 |
43 | /**
44 | * Returns the application configuration.
45 | *
46 | * @return ApplicationConfig The application configuration.
47 | */
48 | public function getConfig()
49 | {
50 | return $this->config;
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/src/Api/Event/ConsoleEvents.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Webmozart\Console\Api\Event;
13 |
14 | /**
15 | * Contains all the events supported by this package.
16 | *
17 | * @since 1.0
18 | *
19 | * @author Bernhard Schussek
20 | */
21 | final class ConsoleEvents
22 | {
23 | /**
24 | * Dispatched before console arguments are resolved to a command.
25 | *
26 | * @see PreResolveEvent
27 | */
28 | const PRE_RESOLVE = 'pre-resolve';
29 |
30 | /**
31 | * Dispatched before a command is handled.
32 | *
33 | * @see PreHandleEvent
34 | */
35 | const PRE_HANDLE = 'pre-handle';
36 |
37 | /**
38 | * Dispatched after building the configuration.
39 | *
40 | * @see ConfigEvent
41 | */
42 | const CONFIG = 'config';
43 |
44 | /**
45 | * May not be instantiated.
46 | */
47 | private function __construct()
48 | {
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/src/Api/Event/PreHandleEvent.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Webmozart\Console\Api\Event;
13 |
14 | use Symfony\Component\EventDispatcher\Event;
15 | use Webmozart\Console\Api\Args\Args;
16 | use Webmozart\Console\Api\Command\Command;
17 | use Webmozart\Console\Api\IO\IO;
18 |
19 | /**
20 | * Dispatched before a command is handled.
21 | *
22 | * Add a listener for this event to execute custom logic before or instead of
23 | * the default handler.
24 | *
25 | * @since 1.0
26 | *
27 | * @author Bernhard Schussek
28 | */
29 | class PreHandleEvent extends Event
30 | {
31 | /**
32 | * @var Args
33 | */
34 | private $args;
35 |
36 | /**
37 | * @var IO
38 | */
39 | private $io;
40 |
41 | /**
42 | * @var Command
43 | */
44 | private $command;
45 |
46 | /**
47 | * @var bool
48 | */
49 | private $handled = false;
50 |
51 | /**
52 | * @var int
53 | */
54 | private $statusCode = 0;
55 |
56 | /**
57 | * Creates the event.
58 | *
59 | * @param Args $args The parsed console arguments.
60 | * @param IO $io The I/O.
61 | * @param Command $command The executed command.
62 | */
63 | public function __construct(Args $args, IO $io, Command $command)
64 | {
65 | $this->args = $args;
66 | $this->io = $io;
67 | $this->command = $command;
68 | }
69 |
70 | /**
71 | * Returns the parsed console arguments.
72 | *
73 | * @return Args The parsed console arguments.
74 | */
75 | public function getArgs()
76 | {
77 | return $this->args;
78 | }
79 |
80 | /**
81 | * Returns the I/O.
82 | *
83 | * @return IO The I/O.
84 | */
85 | public function getIO()
86 | {
87 | return $this->io;
88 | }
89 |
90 | /**
91 | * Returns the executed command.
92 | *
93 | * @return Command The executed command.
94 | */
95 | public function getCommand()
96 | {
97 | return $this->command;
98 | }
99 |
100 | /**
101 | * Returns whether the command was handled by the event listener.
102 | *
103 | * @return bool Returns `true` if the command was handled and `false`
104 | * otherwise.
105 | *
106 | * @see setHandled()
107 | */
108 | public function isHandled()
109 | {
110 | return $this->handled;
111 | }
112 |
113 | /**
114 | * Sets whether the command was handled by the event listener.
115 | *
116 | * If set to `true`, the handler configured for the command is not
117 | * executed. Instead the status code returned by {@link getStatusCode()}
118 | * is returned.
119 | *
120 | * @param bool $handled Whether the command was handled by the event
121 | * listener.
122 | */
123 | public function setHandled($handled)
124 | {
125 | $this->handled = (bool) $handled;
126 | }
127 |
128 | /**
129 | * Returns the status code to return.
130 | *
131 | * @return int Returns 0 on success and any positive integer on error.
132 | */
133 | public function getStatusCode()
134 | {
135 | return $this->statusCode;
136 | }
137 |
138 | /**
139 | * Sets the status code to return.
140 | *
141 | * This method is only useful in combination with {@link setHandled()}.
142 | * If the event is not marked as handled, the status code is ignored.
143 | *
144 | * @param int $statusCode Set to 0 on success and any positive integer on
145 | * error.
146 | */
147 | public function setStatusCode($statusCode)
148 | {
149 | $this->statusCode = (int) $statusCode;
150 | }
151 | }
152 |
--------------------------------------------------------------------------------
/src/Api/Event/PreResolveEvent.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Webmozart\Console\Api\Event;
13 |
14 | use Symfony\Component\EventDispatcher\Event;
15 | use Webmozart\Console\Api\Application\Application;
16 | use Webmozart\Console\Api\Args\RawArgs;
17 | use Webmozart\Console\Api\Resolver\ResolvedCommand;
18 |
19 | /**
20 | * Dispatched before the console arguments are resolved to a command.
21 | *
22 | * Add a listener for this event to customize the command used for the given
23 | * console arguments.
24 | *
25 | * @since 1.0
26 | *
27 | * @author Bernhard Schussek
28 | */
29 | class PreResolveEvent extends Event
30 | {
31 | /**
32 | * @var RawArgs
33 | */
34 | private $rawArgs;
35 |
36 | /**
37 | * @var Application
38 | */
39 | private $application;
40 |
41 | /**
42 | * @var ResolvedCommand
43 | */
44 | private $resolvedCommand;
45 |
46 | /**
47 | * Creates the event.
48 | *
49 | * @param RawArgs $rawArgs The raw console arguments.
50 | * @param Application $application The application.
51 | */
52 | public function __construct(RawArgs $rawArgs, Application $application)
53 | {
54 | $this->rawArgs = $rawArgs;
55 | $this->application = $application;
56 | }
57 |
58 | /**
59 | * Returns the raw console arguments.
60 | *
61 | * @return RawArgs The raw console arguments.
62 | */
63 | public function getRawArgs()
64 | {
65 | return $this->rawArgs;
66 | }
67 |
68 | /**
69 | * Returns the application.
70 | *
71 | * @return Application The application.
72 | */
73 | public function getApplication()
74 | {
75 | return $this->application;
76 | }
77 |
78 | /**
79 | * Returns the resolved command.
80 | *
81 | * @return ResolvedCommand Returns the resolved command or `null` if none
82 | * was set.
83 | */
84 | public function getResolvedCommand()
85 | {
86 | return $this->resolvedCommand;
87 | }
88 |
89 | /**
90 | * Sets the resolved command.
91 | *
92 | * @param ResolvedCommand $resolvedCommand The resolved command. Set to
93 | * `null` to let the configured
94 | * resolver decide.
95 | */
96 | public function setResolvedCommand(ResolvedCommand $resolvedCommand = null)
97 | {
98 | $this->resolvedCommand = $resolvedCommand;
99 | }
100 | }
101 |
--------------------------------------------------------------------------------
/src/Api/Formatter/Formatter.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Webmozart\Console\Api\Formatter;
13 |
14 | /**
15 | * Formats strings.
16 | *
17 | * @since 1.0
18 | *
19 | * @author Bernhard Schussek
20 | */
21 | interface Formatter
22 | {
23 | /**
24 | * Formats the given string.
25 | *
26 | * @param string $string The string to format.
27 | * @param Style $style The style to use.
28 | *
29 | * @return string The formatted string.
30 | */
31 | public function format($string, Style $style = null);
32 |
33 | /**
34 | * Removes the format tags from the given string.
35 | *
36 | * @param string $string The string to remove the format tags from.
37 | *
38 | * @return string The string without format tags.
39 | */
40 | public function removeFormat($string);
41 | }
42 |
--------------------------------------------------------------------------------
/src/Api/Formatter/StyleSet.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Webmozart\Console\Api\Formatter;
13 |
14 | use LogicException;
15 | use OutOfBoundsException;
16 |
17 | /**
18 | * A set of styles used by the formatter.
19 | *
20 | * @since 1.0
21 | *
22 | * @author Bernhard Schussek
23 | */
24 | class StyleSet
25 | {
26 | /**
27 | * @var Style[]
28 | */
29 | private $styles = array();
30 |
31 | /**
32 | * Creates a new style set.
33 | *
34 | * @param Style[] $styles The styles to add.
35 | */
36 | public function __construct(array $styles = array())
37 | {
38 | $this->replace($styles);
39 | }
40 |
41 | /**
42 | * Adds a style.
43 | *
44 | * @param Style $style The style to add.
45 | *
46 | * @throws LogicException If the tag of the style is not set.
47 | */
48 | public function add(Style $style)
49 | {
50 | if (!$style->getTag()) {
51 | throw new LogicException('The tag of a style added to the style set must be set.');
52 | }
53 |
54 | $this->styles[$style->getTag()] = $style;
55 | }
56 |
57 | /**
58 | * Adds styles to the style set.
59 | *
60 | * Existing styles are preserved.
61 | *
62 | * @param Style[] $styles The styles to add.
63 | */
64 | public function merge(array $styles)
65 | {
66 | foreach ($styles as $style) {
67 | $this->add($style);
68 | }
69 | }
70 |
71 | /**
72 | * Sets the styles of the style set.
73 | *
74 | * Existing styles are removed.
75 | *
76 | * @param Style[] $styles The styles to set.
77 | */
78 | public function replace(array $styles)
79 | {
80 | $this->styles = array();
81 |
82 | $this->merge($styles);
83 | }
84 |
85 | /**
86 | * Removes a style.
87 | *
88 | * This method does nothing if the tag does not exist.
89 | *
90 | * @param string $tag The tag of the style.
91 | */
92 | public function remove($tag)
93 | {
94 | unset($this->styles[$tag]);
95 | }
96 |
97 | /**
98 | * Clears the contents of the style set.
99 | */
100 | public function clear()
101 | {
102 | $this->styles = array();
103 | }
104 |
105 | /**
106 | * Returns whether the style with the given tag exists.
107 | *
108 | * @param string $tag The tag of the style.
109 | *
110 | * @return bool Returns `true` if a style with the given tag exists and
111 | * `false` otherwise.
112 | */
113 | public function contains($tag)
114 | {
115 | return isset($this->styles[$tag]);
116 | }
117 |
118 | /**
119 | * Returns whether the style set is empty.
120 | *
121 | * @return bool Returns `true` if the set contains no styles and `false`
122 | * otherwise.
123 | */
124 | public function isEmpty()
125 | {
126 | return 0 === count($this->styles);
127 | }
128 |
129 | /**
130 | * Returns the style with the given tag.
131 | *
132 | * @param string $tag The tag of the style.
133 | *
134 | * @return Style The style.
135 | *
136 | * @throws OutOfBoundsException If no style is set for the given tag.
137 | */
138 | public function get($tag)
139 | {
140 | if (!isset($this->styles[$tag])) {
141 | throw new OutOfBoundsException(sprintf(
142 | 'The style tag "%s" does not exist.',
143 | $tag
144 | ));
145 | }
146 |
147 | return $this->styles[$tag];
148 | }
149 |
150 | /**
151 | * Returns all styles.
152 | *
153 | * @return Style[] The styles indexed by their tags.
154 | */
155 | public function toArray()
156 | {
157 | return $this->styles;
158 | }
159 | }
160 |
--------------------------------------------------------------------------------
/src/Api/IO/IOException.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Webmozart\Console\Api\IO;
13 |
14 | use RuntimeException;
15 |
16 | /**
17 | * Thrown if an error happens during I/O.
18 | *
19 | * @since 1.0
20 | *
21 | * @author Bernhard Schussek
22 | */
23 | class IOException extends RuntimeException
24 | {
25 | }
26 |
--------------------------------------------------------------------------------
/src/Api/IO/Input.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Webmozart\Console\Api\IO;
13 |
14 | /**
15 | * The console input.
16 | *
17 | * This class wraps an input stream and adds convenience functionality for
18 | * reading that stream.
19 | *
20 | * @since 1.0
21 | *
22 | * @author Bernhard Schussek
23 | */
24 | class Input
25 | {
26 | /**
27 | * @var InputStream
28 | */
29 | private $stream;
30 |
31 | /**
32 | * @var bool
33 | */
34 | private $interactive = true;
35 |
36 | /**
37 | * Creates an input for the given input stream.
38 | *
39 | * @param InputStream $stream The input stream.
40 | */
41 | public function __construct(InputStream $stream)
42 | {
43 | $this->stream = $stream;
44 | }
45 |
46 | /**
47 | * Reads the given amount of characters from the input stream.
48 | *
49 | * @param int $length The number of characters to read.
50 | * @param string $default The default to return if interaction is disabled.
51 | *
52 | * @return string The characters read from the input stream.
53 | *
54 | * @throws IOException If reading fails or if the input stream is closed.
55 | */
56 | public function read($length, $default = null)
57 | {
58 | if (!$this->interactive) {
59 | return $default;
60 | }
61 |
62 | return $this->stream->read($length);
63 | }
64 |
65 | /**
66 | * Reads a line from the input stream.
67 | *
68 | * @param string $default The default to return if interaction is disabled.
69 | * @param int $length The maximum number of characters to read. If
70 | * `null`, all characters up to the first newline are
71 | * returned.
72 | *
73 | * @return string The characters read from the input stream.
74 | *
75 | * @throws IOException If reading fails or if the input stream is closed.
76 | */
77 | public function readLine($default = null, $length = null)
78 | {
79 | if (!$this->interactive) {
80 | return $default;
81 | }
82 |
83 | return $this->stream->readLine($length);
84 | }
85 |
86 | /**
87 | * Closes the input.
88 | */
89 | public function close()
90 | {
91 | $this->stream->close();
92 | }
93 |
94 | /**
95 | * Returns whether the input is closed.
96 | *
97 | * @return bool Returns `true` if the input is closed and `false`
98 | * otherwise.
99 | */
100 | public function isClosed()
101 | {
102 | return $this->stream->isClosed();
103 | }
104 |
105 | /**
106 | * Sets the underlying stream.
107 | *
108 | * @param InputStream $stream The input stream.
109 | */
110 | public function setStream(InputStream $stream)
111 | {
112 | $this->stream = $stream;
113 | }
114 |
115 | /**
116 | * Returns the underlying stream.
117 | *
118 | * @return InputStream The input stream.
119 | */
120 | public function getStream()
121 | {
122 | return $this->stream;
123 | }
124 |
125 | /**
126 | * Enables or disables interaction with the user.
127 | *
128 | * @param bool $interactive Whether the inputmay interact with the user. If
129 | * set to `false`, all calls to {@link read()} and
130 | * {@link readLine()} will immediately return the
131 | * default value.
132 | */
133 | public function setInteractive($interactive)
134 | {
135 | $this->interactive = (bool) $interactive;
136 | }
137 |
138 | /**
139 | * Returns whether the user may be asked for input.
140 | *
141 | * @return bool Returns `true` if the user may be asked for input and
142 | * `false` otherwise.
143 | */
144 | public function isInteractive()
145 | {
146 | return $this->interactive;
147 | }
148 | }
149 |
--------------------------------------------------------------------------------
/src/Api/IO/InputStream.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Webmozart\Console\Api\IO;
13 |
14 | /**
15 | * The console input stream.
16 | *
17 | * @since 1.0
18 | *
19 | * @author Bernhard Schussek
20 | */
21 | interface InputStream
22 | {
23 | /**
24 | * Reads the given amount of characters from the stream.
25 | *
26 | * @param int $length The number of characters to read.
27 | *
28 | * @return string The characters read from the stream.
29 | *
30 | * @throws IOException If reading fails or if the stream is closed.
31 | */
32 | public function read($length);
33 |
34 | /**
35 | * Reads a line from the stream.
36 | *
37 | * @param int $length The maximum number of characters to read. If `null`,
38 | * all characters up to the first newline are returned.
39 | *
40 | * @return string The characters read from the stream.
41 | *
42 | * @throws IOException If reading fails or if the stream is closed.
43 | */
44 | public function readLine($length = null);
45 |
46 | /**
47 | * Closes the stream.
48 | */
49 | public function close();
50 |
51 | /**
52 | * Returns whether the stream is closed.
53 | *
54 | * @return bool Returns `true` if the stream is closed.
55 | */
56 | public function isClosed();
57 | }
58 |
--------------------------------------------------------------------------------
/src/Api/IO/OutputStream.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Webmozart\Console\Api\IO;
13 |
14 | /**
15 | * The console output stream.
16 | *
17 | * @since 1.0
18 | *
19 | * @author Bernhard Schussek
20 | */
21 | interface OutputStream
22 | {
23 | /**
24 | * Writes a string to the stream.
25 | *
26 | * @param string $string The string to write.
27 | *
28 | * @throws IOException If writing fails or if the stream is closed.
29 | */
30 | public function write($string);
31 |
32 | /**
33 | * Flushes the stream and forces all pending text to be written out.
34 | *
35 | * @throws IOException If flushing fails or if the stream is closed.
36 | */
37 | public function flush();
38 |
39 | /**
40 | * Returns whether the stream supports ANSI format codes.
41 | *
42 | * @return bool Returns `true` if the stream supports ANSI format codes and
43 | * `false` otherwise.
44 | */
45 | public function supportsAnsi();
46 |
47 | /**
48 | * Closes the stream.
49 | */
50 | public function close();
51 |
52 | /**
53 | * Returns whether the stream is closed.
54 | *
55 | * @return bool Returns `true` if the stream is closed.
56 | */
57 | public function isClosed();
58 | }
59 |
--------------------------------------------------------------------------------
/src/Api/Resolver/CannotResolveCommandException.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Webmozart\Console\Api\Resolver;
13 |
14 | use Exception;
15 | use RuntimeException;
16 | use Webmozart\Console\Api\Command\CommandCollection;
17 | use Webmozart\Console\Util\SimilarCommandName;
18 |
19 | /**
20 | * Thrown when a command cannot be resolved.
21 | *
22 | * @since 1.0
23 | *
24 | * @author Bernhard Schussek
25 | */
26 | class CannotResolveCommandException extends RuntimeException
27 | {
28 | /**
29 | * Code: The passed command name was not found.
30 | */
31 | const NAME_NOT_FOUND = 1;
32 |
33 | /**
34 | * Code: No command was passed and no default was configured.
35 | */
36 | const NO_DEFAULT_COMMAND = 2;
37 |
38 | /**
39 | * Creates an exception for the code {@link NAME_NOT_FOUND}.
40 | *
41 | * Suggested alternatives are searched in the passed commands.
42 | *
43 | * @param string $commandName The command name that was not found.
44 | * @param CommandCollection $commands A list of available commands that
45 | * is searched for similar names.
46 | * @param Exception $cause The exception that caused this
47 | * exception.
48 | *
49 | * @return static The created exception.
50 | */
51 | public static function nameNotFound($commandName, CommandCollection $commands, Exception $cause = null)
52 | {
53 | $message = sprintf('The command "%s" is not defined.', $commandName);
54 |
55 | $suggestedNames = SimilarCommandName::find($commandName, $commands);
56 |
57 | if (count($suggestedNames) > 0) {
58 | if (1 === count($suggestedNames)) {
59 | $message .= "\n\nDid you mean this?\n ";
60 | } else {
61 | $message .= "\n\nDid you mean one of these?\n ";
62 | }
63 | $message .= implode("\n ", $suggestedNames);
64 | }
65 |
66 | return new static($message, self::NAME_NOT_FOUND, $cause);
67 | }
68 |
69 | /**
70 | * Creates an exception for the code {@link NO_DEFAULT_COMMAND}.
71 | *
72 | * @param Exception $cause The exception that caused this exception.
73 | *
74 | * @return static The created exception.
75 | */
76 | public static function noDefaultCommand(Exception $cause = null)
77 | {
78 | return new static('No default command is defined.', self::NO_DEFAULT_COMMAND, $cause);
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/src/Api/Resolver/CommandResolver.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Webmozart\Console\Api\Resolver;
13 |
14 | use Webmozart\Console\Api\Application\Application;
15 | use Webmozart\Console\Api\Args\RawArgs;
16 |
17 | /**
18 | * Returns the command to execute for the given console arguments.
19 | *
20 | * @since 1.0
21 | *
22 | * @author Bernhard Schussek
23 | */
24 | interface CommandResolver
25 | {
26 | /**
27 | * Returns the command to execute for the given console arguments.
28 | *
29 | * @param RawArgs $args The console arguments.
30 | * @param Application $application The application.
31 | *
32 | * @return ResolvedCommand The command to execute.
33 | *
34 | * @throws CannotResolveCommandException If the command cannot be resolved.
35 | */
36 | public function resolveCommand(RawArgs $args, Application $application);
37 | }
38 |
--------------------------------------------------------------------------------
/src/Api/Resolver/ResolvedCommand.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Webmozart\Console\Api\Resolver;
13 |
14 | use Webmozart\Console\Api\Args\Args;
15 | use Webmozart\Console\Api\Args\RawArgs;
16 | use Webmozart\Console\Api\Command\Command;
17 |
18 | /**
19 | * A resolved command.
20 | *
21 | * @since 1.0
22 | *
23 | * @author Bernhard Schussek
24 | */
25 | class ResolvedCommand
26 | {
27 | /**
28 | * @var Command
29 | */
30 | private $command;
31 |
32 | /**
33 | * @var RawArgs
34 | */
35 | private $args;
36 |
37 | /**
38 | * Creates a new resolved command.
39 | *
40 | * @param Command $command The command.
41 | * @param Args $args The console arguments.
42 | */
43 | public function __construct(Command $command, Args $args)
44 | {
45 | $this->command = $command;
46 | $this->args = $args;
47 | }
48 |
49 | /**
50 | * Returns the command.
51 | *
52 | * @return Command The command.
53 | */
54 | public function getCommand()
55 | {
56 | return $this->command;
57 | }
58 |
59 | /**
60 | * Returns the parsed console arguments.
61 | *
62 | * @return Args The parsed console arguments.
63 | */
64 | public function getArgs()
65 | {
66 | return $this->args;
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/src/Args/ArgvArgs.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Webmozart\Console\Args;
13 |
14 | use Webmozart\Console\Api\Args\RawArgs;
15 |
16 | /**
17 | * Console arguments passed via PHP's "argv" variable.
18 | *
19 | * @since 1.0
20 | *
21 | * @author Bernhard Schussek
22 | */
23 | class ArgvArgs implements RawArgs
24 | {
25 | /**
26 | * @var string
27 | */
28 | private $scriptName;
29 |
30 | /**
31 | * @var string[]
32 | */
33 | private $tokens;
34 |
35 | /**
36 | * Creates the console arguments.
37 | *
38 | * @param array $argv The contents of the "argv" variable or `null` to read
39 | * the global "argv" variable.
40 | */
41 | public function __construct(array $argv = null)
42 | {
43 | if (null === $argv) {
44 | $argv = $_SERVER['argv'];
45 | }
46 |
47 | $this->scriptName = array_shift($argv);
48 | $this->tokens = $argv;
49 | }
50 |
51 | /**
52 | * {@inheritdoc}
53 | */
54 | public function getScriptName()
55 | {
56 | return $this->scriptName;
57 | }
58 |
59 | /**
60 | * {@inheritdoc}
61 | */
62 | public function hasToken($token)
63 | {
64 | return in_array($token, $this->tokens);
65 | }
66 |
67 | /**
68 | * {@inheritdoc}
69 | */
70 | public function getTokens()
71 | {
72 | return $this->tokens;
73 | }
74 |
75 | /**
76 | * {@inheritdoc}
77 | */
78 | public function toString($scriptName = true)
79 | {
80 | $string = implode(' ', $this->tokens);
81 |
82 | if ($scriptName) {
83 | $string = ltrim($this->scriptName.' ').$string;
84 | }
85 |
86 | return $string;
87 | }
88 | }
89 |
--------------------------------------------------------------------------------
/src/Args/StringArgs.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Webmozart\Console\Args;
13 |
14 | use Webmozart\Console\Api\Args\RawArgs;
15 |
16 | /**
17 | * Console arguments passed as a string.
18 | *
19 | * @since 1.0
20 | *
21 | * @author Bernhard Schussek
22 | */
23 | class StringArgs implements RawArgs
24 | {
25 | /**
26 | * @var string[]
27 | */
28 | private $tokens;
29 |
30 | /**
31 | * Creates the console arguments.
32 | *
33 | * @param string $string The console arguments string.
34 | */
35 | public function __construct($string)
36 | {
37 | $parser = new TokenParser();
38 |
39 | $this->tokens = $parser->parseTokens($string);
40 | }
41 |
42 | /**
43 | * {@inheritdoc}
44 | */
45 | public function getScriptName()
46 | {
47 | return null;
48 | }
49 |
50 | /**
51 | * {@inheritdoc}
52 | */
53 | public function hasToken($token)
54 | {
55 | return in_array($token, $this->tokens);
56 | }
57 |
58 | /**
59 | * {@inheritdoc}
60 | */
61 | public function getTokens()
62 | {
63 | return $this->tokens;
64 | }
65 |
66 | /**
67 | * {@inheritdoc}
68 | */
69 | public function toString($scriptName = true)
70 | {
71 | return implode(' ', $this->tokens);
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/src/Formatter/AnsiFormatter.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Webmozart\Console\Formatter;
13 |
14 | use Symfony\Component\Console\Formatter\OutputFormatter;
15 | use Webmozart\Console\Adapter\StyleConverter;
16 | use Webmozart\Console\Api\Formatter\Formatter;
17 | use Webmozart\Console\Api\Formatter\Style;
18 | use Webmozart\Console\Api\Formatter\StyleSet;
19 |
20 | /**
21 | * A formatter that replaces style tags by ANSI format codes.
22 | *
23 | * @since 1.0
24 | *
25 | * @author Bernhard Schussek
26 | */
27 | class AnsiFormatter implements Formatter
28 | {
29 | /**
30 | * @var OutputFormatter
31 | */
32 | private $innerFormatter;
33 |
34 | /**
35 | * Creates the formatter.
36 | *
37 | * @param StyleSet $styleSet The style set to use.
38 | */
39 | public function __construct(StyleSet $styleSet = null)
40 | {
41 | $this->innerFormatter = new OutputFormatter(true);
42 |
43 | if (!$styleSet) {
44 | $styleSet = new DefaultStyleSet();
45 | }
46 |
47 | foreach ($styleSet->toArray() as $tag => $style) {
48 | $this->innerFormatter->setStyle($tag, StyleConverter::convert($style));
49 | }
50 | }
51 |
52 | /**
53 | * {@inheritdoc}
54 | */
55 | public function format($string, Style $style = null)
56 | {
57 | if (null !== $style) {
58 | $this->innerFormatter->getStyleStack()->push(StyleConverter::convert($style));
59 | }
60 |
61 | $formatted = $this->innerFormatter->format($string);
62 |
63 | if (null !== $style) {
64 | $this->innerFormatter->getStyleStack()->pop();
65 | }
66 |
67 | return $formatted;
68 | }
69 |
70 | /**
71 | * {@inheritdoc}
72 | */
73 | public function removeFormat($string)
74 | {
75 | $this->innerFormatter->setDecorated(false);
76 | $formatted = $this->innerFormatter->format($string);
77 | $this->innerFormatter->setDecorated(true);
78 |
79 | return $formatted;
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/src/Formatter/DefaultStyleSet.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Webmozart\Console\Formatter;
13 |
14 | use Webmozart\Console\Api\Formatter\Style;
15 | use Webmozart\Console\Api\Formatter\StyleSet;
16 |
17 | /**
18 | * A color style which prefers cyan for its good readability.
19 | *
20 | * @since 1.0
21 | *
22 | * @author Bernhard Schussek
23 | */
24 | class DefaultStyleSet extends StyleSet
25 | {
26 | public function __construct()
27 | {
28 | $this->replace(array(
29 | // Default styles
30 | Style::tag('b')->bold(),
31 | Style::tag('u')->underlined(),
32 | Style::tag('bu')->bold()->underlined(),
33 | Style::tag('c1')->fgCyan(),
34 | Style::tag('c2')->fgYellow(),
35 | Style::tag('error')->fgWhite()->bgRed(),
36 | Style::tag('warn')->fgBlack()->bgYellow(),
37 |
38 | // Adapted Symfony default styles
39 | Style::tag('info')->fgCyan(),
40 | Style::tag('comment')->fgCyan(),
41 | Style::tag('question')->fgBlack()->bgCyan(),
42 | ));
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/Formatter/NullFormatter.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Webmozart\Console\Formatter;
13 |
14 | use Webmozart\Console\Api\Formatter\Formatter;
15 | use Webmozart\Console\Api\Formatter\Style;
16 |
17 | /**
18 | * A formatter that returns all text unchanged.
19 | *
20 | * @since 1.0
21 | *
22 | * @author Bernhard Schussek
23 | */
24 | class NullFormatter implements Formatter
25 | {
26 | /**
27 | * {@inheritdoc}
28 | */
29 | public function format($string, Style $style = null)
30 | {
31 | return $string;
32 | }
33 |
34 | /**
35 | * {@inheritdoc}
36 | */
37 | public function removeFormat($string)
38 | {
39 | return $string;
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/Formatter/PlainFormatter.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Webmozart\Console\Formatter;
13 |
14 | use Symfony\Component\Console\Formatter\OutputFormatter;
15 | use Webmozart\Console\Adapter\StyleConverter;
16 | use Webmozart\Console\Api\Formatter\Formatter;
17 | use Webmozart\Console\Api\Formatter\Style;
18 | use Webmozart\Console\Api\Formatter\StyleSet;
19 |
20 | /**
21 | * A formatter that removes all format tags.
22 | *
23 | * @since 1.0
24 | *
25 | * @author Bernhard Schussek
26 | */
27 | class PlainFormatter implements Formatter
28 | {
29 | /**
30 | * @var OutputFormatter
31 | */
32 | private $innerFormatter;
33 |
34 | /**
35 | * Creates the formatter.
36 | *
37 | * @param StyleSet $styleSet The style set to use.
38 | */
39 | public function __construct(StyleSet $styleSet = null)
40 | {
41 | $this->innerFormatter = new OutputFormatter(false);
42 |
43 | if (!$styleSet) {
44 | $styleSet = new DefaultStyleSet();
45 | }
46 |
47 | foreach ($styleSet->toArray() as $tag => $style) {
48 | $this->innerFormatter->setStyle($tag, StyleConverter::convert($style));
49 | }
50 | }
51 |
52 | /**
53 | * {@inheritdoc}
54 | */
55 | public function format($string, Style $style = null)
56 | {
57 | return $this->innerFormatter->format($string);
58 | }
59 |
60 | /**
61 | * {@inheritdoc}
62 | */
63 | public function removeFormat($string)
64 | {
65 | return $this->innerFormatter->format($string);
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/src/Handler/CallbackHandler.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Webmozart\Console\Handler;
13 |
14 | use Webmozart\Assert\Assert;
15 | use Webmozart\Console\Api\Args\Args;
16 | use Webmozart\Console\Api\Command\Command;
17 | use Webmozart\Console\Api\IO\IO;
18 |
19 | /**
20 | * Delegates command handling to a callable.
21 | *
22 | * @since 1.0
23 | *
24 | * @author Bernhard Schussek
25 | */
26 | class CallbackHandler
27 | {
28 | /**
29 | * @var callable
30 | */
31 | private $callback;
32 |
33 | /**
34 | * Creates the command handler.
35 | *
36 | * The passed callback receives three arguments:
37 | *
38 | * * {@link Args} `$args`: The console arguments.
39 | * * {@link IO} `$io`: The I/O.
40 | * * {@link Command} `$command`: The executed command.
41 | *
42 | * The callable should return 0 on success and a positive integer on error.
43 | *
44 | * @param callable $callback The callback to execute when handling a
45 | * command.
46 | */
47 | public function __construct($callback)
48 | {
49 | Assert::isCallable($callback);
50 |
51 | $this->callback = $callback;
52 | }
53 |
54 | /**
55 | * {@inheritdoc}
56 | */
57 | public function handle(Args $args, IO $io, Command $command)
58 | {
59 | return call_user_func($this->callback, $args, $io, $command);
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/src/Handler/Help/HelpAsciiDocHandler.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Webmozart\Console\Handler\Help;
13 |
14 | use Symfony\Component\Process\ExecutableFinder;
15 | use Webmozart\Assert\Assert;
16 | use Webmozart\Console\Api\Args\Args;
17 | use Webmozart\Console\Api\IO\IO;
18 | use Webmozart\Console\Process\ProcessLauncher;
19 |
20 | /**
21 | * Displays the application/command help as AsciiDoc.
22 | *
23 | * @since 1.0
24 | *
25 | * @author Bernhard Schussek
26 | */
27 | class HelpAsciiDocHandler
28 | {
29 | /**
30 | * @var string
31 | */
32 | private $path;
33 |
34 | /**
35 | * @var string
36 | */
37 | private $lessBinary;
38 |
39 | /**
40 | * @var ExecutableFinder
41 | */
42 | private $executableFinder;
43 |
44 | /**
45 | * @var ProcessLauncher
46 | */
47 | private $processLauncher;
48 |
49 | /**
50 | * Creates the handler.
51 | *
52 | * @param string $path The path to the AsciiDoc file.
53 | * @param ExecutableFinder $executableFinder The finder used to find the
54 | * "less" binary.
55 | * @param ProcessLauncher $processLauncher The launcher for executing the
56 | * "less" binary.
57 | */
58 | public function __construct($path, ExecutableFinder $executableFinder = null, ProcessLauncher $processLauncher = null)
59 | {
60 | Assert::file($path);
61 |
62 | $this->path = $path;
63 | $this->executableFinder = $executableFinder ?: new ExecutableFinder();
64 | $this->processLauncher = $processLauncher ?: new ProcessLauncher();
65 | }
66 |
67 | /**
68 | * {@inheritdoc}
69 | */
70 | public function handle(Args $args, IO $io)
71 | {
72 | if ($this->processLauncher->isSupported()) {
73 | if (!$this->lessBinary) {
74 | $this->lessBinary = $this->executableFinder->find('less');
75 | }
76 |
77 | if ($this->lessBinary) {
78 | return $this->processLauncher->launchProcess(
79 | escapeshellcmd($this->lessBinary).' %path%',
80 | array('path' => $this->path),
81 | false
82 | );
83 | }
84 | }
85 |
86 | $io->write(file_get_contents($this->path));
87 |
88 | return 0;
89 | }
90 |
91 | /**
92 | * Returns the "less" binary used to display the AsciiDoc page.
93 | *
94 | * @return string The "less" binary or `null` if the binary is auto-detected.
95 | */
96 | public function getLessBinary()
97 | {
98 | return $this->lessBinary;
99 | }
100 |
101 | /**
102 | * Sets the "less" binary used to display the AsciiDoc page.
103 | *
104 | * @param string $lessBinary The "less" binary to use.
105 | */
106 | public function setLessBinary($lessBinary)
107 | {
108 | if (null !== $lessBinary) {
109 | Assert::string($lessBinary, 'The less binary must be a string or null. Got: %s');
110 | Assert::notEmpty($lessBinary, 'The less binary must not be empty.');
111 | }
112 |
113 | $this->lessBinary = $lessBinary;
114 | }
115 | }
116 |
--------------------------------------------------------------------------------
/src/Handler/Help/HelpJsonHandler.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Webmozart\Console\Handler\Help;
13 |
14 | use Symfony\Component\Console\Descriptor\JsonDescriptor;
15 | use Webmozart\Console\Adapter\ApplicationAdapter;
16 | use Webmozart\Console\Adapter\CommandAdapter;
17 | use Webmozart\Console\Adapter\IOOutput;
18 | use Webmozart\Console\Api\Args\Args;
19 | use Webmozart\Console\Api\Command\Command;
20 | use Webmozart\Console\Api\IO\IO;
21 |
22 | /**
23 | * @since 1.0
24 | *
25 | * @author Bernhard Schussek
26 | */
27 | class HelpJsonHandler
28 | {
29 | /**
30 | * {@inheritdoc}
31 | */
32 | public function handle(Args $args, IO $io, Command $command)
33 | {
34 | $descriptor = new JsonDescriptor();
35 | $output = new IOOutput($io);
36 | $application = $command->getApplication();
37 | $applicationAdapter = new ApplicationAdapter($application);
38 |
39 | if ($args->isArgumentSet('command')) {
40 | $theCommand = $application->getCommand($args->getArgument('command'));
41 | $commandAdapter = new CommandAdapter($theCommand, $applicationAdapter);
42 | $descriptor->describe($output, $commandAdapter);
43 | } else {
44 | $descriptor->describe($output, $applicationAdapter);
45 | }
46 |
47 | return 0;
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/src/Handler/Help/HelpManHandler.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Webmozart\Console\Handler\Help;
13 |
14 | use RuntimeException;
15 | use Symfony\Component\Process\ExecutableFinder;
16 | use Webmozart\Assert\Assert;
17 | use Webmozart\Console\Process\ProcessLauncher;
18 |
19 | /**
20 | * @since 1.0
21 | *
22 | * @author Bernhard Schussek
23 | */
24 | class HelpManHandler
25 | {
26 | /**
27 | * @var string
28 | */
29 | private $path;
30 |
31 | /**
32 | * @var string
33 | */
34 | private $manBinary;
35 |
36 | /**
37 | * @var ExecutableFinder
38 | */
39 | private $executableFinder;
40 |
41 | /**
42 | * @var ProcessLauncher
43 | */
44 | private $processLauncher;
45 |
46 | /**
47 | * Creates a new AsciiDoc descriptor.
48 | *
49 | * @param ExecutableFinder $executableFinder The finder used to find the
50 | * "man" binary.
51 | * @param ProcessLauncher $processLauncher The launcher for executing the
52 | * "man" binary.
53 | */
54 | public function __construct($path, ExecutableFinder $executableFinder = null, ProcessLauncher $processLauncher = null)
55 | {
56 | Assert::file($path);
57 |
58 | $this->path = $path;
59 | $this->executableFinder = $executableFinder ?: new ExecutableFinder();
60 | $this->processLauncher = $processLauncher ?: new ProcessLauncher();
61 | }
62 |
63 | /**
64 | * {@inheritdoc}
65 | */
66 | public function handle()
67 | {
68 | if (!$this->processLauncher->isSupported()) {
69 | throw new RuntimeException('The ProcessLauncher must be supported for the man help to run.');
70 | }
71 |
72 | if (!$this->manBinary) {
73 | $this->manBinary = $this->executableFinder->find('man');
74 | }
75 |
76 | if (!$this->manBinary) {
77 | throw new RuntimeException('The "man" binary was not found.');
78 | }
79 |
80 | return $this->processLauncher->launchProcess(
81 | escapeshellcmd($this->manBinary).' -l %path%',
82 | array('path' => $this->path),
83 | false
84 | );
85 | }
86 |
87 | /**
88 | * @return string
89 | */
90 | public function getManBinary()
91 | {
92 | return $this->manBinary;
93 | }
94 |
95 | /**
96 | * @param string $manBinary
97 | */
98 | public function setManBinary($manBinary)
99 | {
100 | $this->manBinary = $manBinary;
101 | }
102 | }
103 |
--------------------------------------------------------------------------------
/src/Handler/Help/HelpTextHandler.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Webmozart\Console\Handler\Help;
13 |
14 | use Webmozart\Console\Api\Args\Args;
15 | use Webmozart\Console\Api\Command\Command;
16 | use Webmozart\Console\Api\IO\IO;
17 | use Webmozart\Console\UI\Help\ApplicationHelp;
18 | use Webmozart\Console\UI\Help\CommandHelp;
19 |
20 | /**
21 | * @since 1.0
22 | *
23 | * @author Bernhard Schussek
24 | */
25 | class HelpTextHandler
26 | {
27 | /**
28 | * {@inheritdoc}
29 | */
30 | public function handle(Args $args, IO $io, Command $command)
31 | {
32 | $application = $command->getApplication();
33 |
34 | if ($args->isArgumentSet('command')) {
35 | $theCommand = $application->getCommand($args->getArgument('command'));
36 | $usage = new CommandHelp($theCommand);
37 | } else {
38 | $usage = new ApplicationHelp($application);
39 | }
40 |
41 | $usage->render($io);
42 |
43 | return 0;
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src/Handler/Help/HelpXmlHandler.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Webmozart\Console\Handler\Help;
13 |
14 | use Symfony\Component\Console\Descriptor\XmlDescriptor;
15 | use Webmozart\Console\Adapter\ApplicationAdapter;
16 | use Webmozart\Console\Adapter\CommandAdapter;
17 | use Webmozart\Console\Adapter\IOOutput;
18 | use Webmozart\Console\Api\Args\Args;
19 | use Webmozart\Console\Api\Command\Command;
20 | use Webmozart\Console\Api\IO\IO;
21 |
22 | /**
23 | * @since 1.0
24 | *
25 | * @author Bernhard Schussek
26 | */
27 | class HelpXmlHandler
28 | {
29 | /**
30 | * {@inheritdoc}
31 | */
32 | public function handle(Args $args, IO $io, Command $command)
33 | {
34 | $descriptor = new XmlDescriptor();
35 | $output = new IOOutput($io);
36 | $application = $command->getApplication();
37 | $applicationAdapter = new ApplicationAdapter($application);
38 |
39 | if ($args->isArgumentSet('command')) {
40 | $theCommand = $application->getCommand($args->getArgument('command'));
41 | $commandAdapter = new CommandAdapter($theCommand, $applicationAdapter);
42 | $descriptor->describe($output, $commandAdapter);
43 | } else {
44 | $descriptor->describe($output, $applicationAdapter);
45 | }
46 |
47 | return 0;
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/src/Handler/NullHandler.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Webmozart\Console\Handler;
13 |
14 | use Webmozart\Console\Api\Args\Args;
15 | use Webmozart\Console\Api\Command\Command;
16 | use Webmozart\Console\Api\IO\IO;
17 |
18 | /**
19 | * A command handler that does nothing.
20 | *
21 | * @since 1.0
22 | *
23 | * @author Bernhard Schussek
24 | */
25 | class NullHandler
26 | {
27 | /**
28 | * {@inheritdoc}
29 | */
30 | public function handle(Args $args, IO $io, Command $command)
31 | {
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/IO/BufferedIO.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Webmozart\Console\IO;
13 |
14 | use Webmozart\Console\Api\Formatter\Formatter;
15 | use Webmozart\Console\Api\IO\Input;
16 | use Webmozart\Console\Api\IO\IO;
17 | use Webmozart\Console\Api\IO\Output;
18 | use Webmozart\Console\Formatter\PlainFormatter;
19 | use Webmozart\Console\IO\InputStream\StringInputStream;
20 | use Webmozart\Console\IO\OutputStream\BufferedOutputStream;
21 |
22 | /**
23 | * An I/O that reads from and writes to a buffer.
24 | *
25 | * @since 1.0
26 | *
27 | * @author Bernhard Schussek
28 | */
29 | class BufferedIO extends IO
30 | {
31 | /**
32 | * Creates the I/O.
33 | *
34 | * @param string $inputData The data to return from the input.
35 | * @param Formatter $formatter The formatter to use.
36 | */
37 | public function __construct($inputData = '', Formatter $formatter = null)
38 | {
39 | $formatter = $formatter ?: new PlainFormatter();
40 | $input = new Input(new StringInputStream($inputData));
41 | $output = new Output(new BufferedOutputStream(), $formatter);
42 | $errorOutput = new Output(new BufferedOutputStream(), $formatter);
43 |
44 | parent::__construct($input, $output, $errorOutput);
45 | }
46 |
47 | /**
48 | * Sets the contents of the input buffer.
49 | *
50 | * @param string $data The input data.
51 | */
52 | public function setInput($data)
53 | {
54 | $this->getInput()->getStream()->set($data);
55 | }
56 |
57 | /**
58 | * Appends data to the input buffer.
59 | *
60 | * @param string $data The input data to append.
61 | */
62 | public function appendInput($data)
63 | {
64 | $this->getInput()->getStream()->append($data);
65 | }
66 |
67 | /**
68 | * Clears the input buffer.
69 | */
70 | public function clearInput()
71 | {
72 | $this->getInput()->getStream()->clear();
73 | }
74 |
75 | /**
76 | * Returns the contents of the output buffer.
77 | *
78 | * @return string The output data.
79 | */
80 | public function fetchOutput()
81 | {
82 | return $this->getOutput()->getStream()->fetch();
83 | }
84 |
85 | /**
86 | * Clears the output buffer.
87 | */
88 | public function clearOutput()
89 | {
90 | $this->getOutput()->getStream()->clear();
91 | }
92 |
93 | /**
94 | * Returns the contents of the error output buffer.
95 | *
96 | * @return string The data of the error output.
97 | */
98 | public function fetchErrors()
99 | {
100 | return $this->getErrorOutput()->getStream()->fetch();
101 | }
102 |
103 | /**
104 | * Clears the error output buffer.
105 | */
106 | public function clearErrors()
107 | {
108 | $this->getErrorOutput()->getStream()->clear();
109 | }
110 | }
111 |
--------------------------------------------------------------------------------
/src/IO/ConsoleIO.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Webmozart\Console\IO;
13 |
14 | use Symfony\Component\Console\Application;
15 | use Webmozart\Console\Api\IO\Input;
16 | use Webmozart\Console\Api\IO\IO;
17 | use Webmozart\Console\Api\IO\Output;
18 | use Webmozart\Console\Formatter\AnsiFormatter;
19 | use Webmozart\Console\Formatter\PlainFormatter;
20 | use Webmozart\Console\IO\InputStream\StandardInputStream;
21 | use Webmozart\Console\IO\OutputStream\ErrorOutputStream;
22 | use Webmozart\Console\IO\OutputStream\StandardOutputStream;
23 | use Webmozart\Console\UI\Rectangle;
24 |
25 | /**
26 | * An I/O that reads from/prints to the console.
27 | *
28 | * @since 1.0
29 | *
30 | * @author Bernhard Schussek
31 | */
32 | class ConsoleIO extends IO
33 | {
34 | /**
35 | * Creates the I/O.
36 | *
37 | * @param Input $input The standard input.
38 | * @param Output $output The standard output.
39 | * @param Output $errorOutput The error output.
40 | */
41 | public function __construct(Input $input = null, Output $output = null, Output $errorOutput = null)
42 | {
43 | if (null === $input) {
44 | $inputStream = new StandardInputStream();
45 | $input = new Input($inputStream);
46 | }
47 |
48 | if (null === $output) {
49 | $outputStream = new StandardOutputStream();
50 | $formatter = $outputStream->supportsAnsi() ? new AnsiFormatter() : new PlainFormatter();
51 | $output = new Output($outputStream, $formatter);
52 | }
53 |
54 | if (null === $errorOutput) {
55 | $errorStream = new ErrorOutputStream();
56 | $formatter = $errorStream->supportsAnsi() ? new AnsiFormatter() : new PlainFormatter();
57 | $errorOutput = new Output($errorStream, $formatter);
58 | }
59 |
60 | parent::__construct($input, $output, $errorOutput);
61 | }
62 |
63 | /**
64 | * {@inheritdoc}
65 | */
66 | protected function getDefaultTerminalDimensions()
67 | {
68 | $application = new Application();
69 |
70 | list($width, $height) = $application->getTerminalDimensions();
71 |
72 | return new Rectangle($width ?: 80, $height ?: 20);
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/src/IO/InputStream/NullInputStream.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Webmozart\Console\IO\InputStream;
13 |
14 | use Webmozart\Console\Api\IO\InputStream;
15 |
16 | /**
17 | * An input stream that returns nothing.
18 | *
19 | * @since 1.0
20 | *
21 | * @author Bernhard Schussek
22 | */
23 | class NullInputStream implements InputStream
24 | {
25 | /**
26 | * {@inheritdoc}
27 | */
28 | public function read($length)
29 | {
30 | }
31 |
32 | /**
33 | * {@inheritdoc}
34 | */
35 | public function readLine($length = null)
36 | {
37 | }
38 |
39 | /**
40 | * {@inheritdoc}
41 | */
42 | public function close()
43 | {
44 | }
45 |
46 | /**
47 | * {@inheritdoc}
48 | */
49 | public function isClosed()
50 | {
51 | return false;
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/src/IO/InputStream/StandardInputStream.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Webmozart\Console\IO\InputStream;
13 |
14 | /**
15 | * An input stream that reads from the standard input.
16 | *
17 | * @since 1.0
18 | *
19 | * @author Bernhard Schussek
20 | */
21 | class StandardInputStream extends StreamInputStream
22 | {
23 | /**
24 | * Creates the input.
25 | */
26 | public function __construct()
27 | {
28 | parent::__construct(fopen('php://stdin', 'r'));
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/IO/InputStream/StreamInputStream.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Webmozart\Console\IO\InputStream;
13 |
14 | use Webmozart\Assert\Assert;
15 | use Webmozart\Console\Api\IO\InputStream;
16 | use Webmozart\Console\Api\IO\IOException;
17 |
18 | /**
19 | * An input stream that reads from a PHP stream.
20 | *
21 | * @since 1.0
22 | *
23 | * @author Bernhard Schussek
24 | */
25 | class StreamInputStream implements InputStream
26 | {
27 | /**
28 | * @var resource
29 | */
30 | private $stream;
31 |
32 | /**
33 | * Creates the input.
34 | *
35 | * @param resource $stream A stream resource.
36 | */
37 | public function __construct($stream)
38 | {
39 | Assert::resource($stream, 'stream');
40 |
41 | $this->stream = $stream;
42 |
43 | // Not all streams are seekable
44 | @rewind($this->stream);
45 | }
46 |
47 | /**
48 | * {@inheritdoc}
49 | */
50 | public function read($length)
51 | {
52 | if (null === $this->stream) {
53 | throw new IOException('Cannot read from a closed input.');
54 | }
55 |
56 | if (feof($this->stream)) {
57 | return null;
58 | }
59 |
60 | $data = fread($this->stream, $length);
61 |
62 | if (false === $data && !feof($this->stream)) {
63 | throw new IOException('Could not read stream.');
64 | }
65 |
66 | return $data ?: null;
67 | }
68 |
69 | /**
70 | * {@inheritdoc}
71 | */
72 | public function readLine($length = null)
73 | {
74 | if (null === $this->stream) {
75 | throw new IOException('Cannot read from a closed input.');
76 | }
77 |
78 | if (feof($this->stream)) {
79 | return null;
80 | }
81 |
82 | if (null !== $length) {
83 | $data = fgets($this->stream, $length);
84 | } else {
85 | $data = fgets($this->stream);
86 | }
87 |
88 | if (false === $data && !feof($this->stream)) {
89 | throw new IOException('Could not read stream.');
90 | }
91 |
92 | return $data ?: null;
93 | }
94 |
95 | /**
96 | * {@inheritdoc}
97 | */
98 | public function close()
99 | {
100 | if ($this->stream) {
101 | @fclose($this->stream);
102 | $this->stream = null;
103 | }
104 | }
105 |
106 | /**
107 | * {@inheritdoc}
108 | */
109 | public function isClosed()
110 | {
111 | return null === $this->stream;
112 | }
113 | }
114 |
--------------------------------------------------------------------------------
/src/IO/InputStream/StringInputStream.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Webmozart\Console\IO\InputStream;
13 |
14 | /**
15 | * An input stream that reads from a string.
16 | *
17 | * @since 1.0
18 | *
19 | * @author Bernhard Schussek
20 | */
21 | class StringInputStream extends StreamInputStream
22 | {
23 | /**
24 | * @var resource
25 | */
26 | private $stream;
27 |
28 | /**
29 | * Creates the input stream.
30 | *
31 | * @param string $string The string to read from.
32 | */
33 | public function __construct($string = '')
34 | {
35 | $this->stream = fopen('php://memory', 'rw');
36 |
37 | parent::__construct($this->stream);
38 |
39 | $this->set($string);
40 | }
41 |
42 | /**
43 | * Clears the contents of the buffer.
44 | */
45 | public function clear()
46 | {
47 | ftruncate($this->stream, 0);
48 | rewind($this->stream);
49 | }
50 |
51 | /**
52 | * Sets the string to read from.
53 | *
54 | * @param string $string The string to read from.
55 | */
56 | public function set($string)
57 | {
58 | $this->clear();
59 |
60 | fwrite($this->stream, $string);
61 | rewind($this->stream);
62 | }
63 |
64 | /**
65 | * Appends a string to the stream.
66 | *
67 | * @param string $string The string to append.
68 | */
69 | public function append($string)
70 | {
71 | $pos = ftell($this->stream);
72 | fseek($this->stream, 0, SEEK_END);
73 | fwrite($this->stream, $string);
74 | fseek($this->stream, $pos);
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/src/IO/OutputStream/BufferedOutputStream.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Webmozart\Console\IO\OutputStream;
13 |
14 | use Webmozart\Console\Api\IO\IOException;
15 | use Webmozart\Console\Api\IO\OutputStream;
16 |
17 | /**
18 | * An output stream that writes to a buffer.
19 | *
20 | * @since 1.0
21 | *
22 | * @author Bernhard Schussek
23 | */
24 | class BufferedOutputStream implements OutputStream
25 | {
26 | /**
27 | * @var string
28 | */
29 | private $buffer = '';
30 |
31 | /**
32 | * @var bool
33 | */
34 | private $closed = false;
35 |
36 | /**
37 | * Returns the contents of the buffer.
38 | *
39 | * @return string The buffered data.
40 | */
41 | public function fetch()
42 | {
43 | return $this->buffer;
44 | }
45 |
46 | /**
47 | * Clears the buffer.
48 | */
49 | public function clear()
50 | {
51 | $this->buffer = '';
52 | }
53 |
54 | /**
55 | * {@inheritdoc}
56 | */
57 | public function write($string)
58 | {
59 | if ($this->closed) {
60 | throw new IOException('Cannot read from a closed input.');
61 | }
62 |
63 | $this->buffer .= $string;
64 | }
65 |
66 | /**
67 | * {@inheritdoc}
68 | */
69 | public function flush()
70 | {
71 | if ($this->closed) {
72 | throw new IOException('Cannot read from a closed input.');
73 | }
74 | }
75 |
76 | /**
77 | * {@inheritdoc}
78 | */
79 | public function supportsAnsi()
80 | {
81 | return false;
82 | }
83 |
84 | /**
85 | * {@inheritdoc}
86 | */
87 | public function close()
88 | {
89 | $this->closed = true;
90 | }
91 |
92 | /**
93 | * {@inheritdoc}
94 | */
95 | public function isClosed()
96 | {
97 | return $this->closed;
98 | }
99 | }
100 |
--------------------------------------------------------------------------------
/src/IO/OutputStream/ErrorOutputStream.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Webmozart\Console\IO\OutputStream;
13 |
14 | /**
15 | * An output stream that writes to the error output.
16 | *
17 | * @since 1.0
18 | *
19 | * @author Bernhard Schussek
20 | */
21 | class ErrorOutputStream extends StreamOutputStream
22 | {
23 | /**
24 | * Creates the stream.
25 | */
26 | public function __construct()
27 | {
28 | parent::__construct(fopen('php://stderr', 'w'));
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/IO/OutputStream/NullOutputStream.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Webmozart\Console\IO\OutputStream;
13 |
14 | use Webmozart\Console\Api\IO\OutputStream;
15 |
16 | /**
17 | * An output stream that ignores all output.
18 | *
19 | * @since 1.0
20 | *
21 | * @author Bernhard Schussek
22 | */
23 | class NullOutputStream implements OutputStream
24 | {
25 | /**
26 | * {@inheritdoc}
27 | */
28 | public function write($string)
29 | {
30 | }
31 |
32 | /**
33 | * {@inheritdoc}
34 | */
35 | public function flush()
36 | {
37 | }
38 |
39 | /**
40 | * {@inheritdoc}
41 | */
42 | public function supportsAnsi()
43 | {
44 | return false;
45 | }
46 |
47 | /**
48 | * {@inheritdoc}
49 | */
50 | public function close()
51 | {
52 | }
53 |
54 | /**
55 | * {@inheritdoc}
56 | */
57 | public function isClosed()
58 | {
59 | return false;
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/src/IO/OutputStream/StandardOutputStream.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Webmozart\Console\IO\OutputStream;
13 |
14 | /**
15 | * An output stream that writes to the standard output.
16 | *
17 | * @since 1.0
18 | *
19 | * @author Bernhard Schussek
20 | */
21 | class StandardOutputStream extends StreamOutputStream
22 | {
23 | /**
24 | * Creates the stream.
25 | */
26 | public function __construct()
27 | {
28 | // From \Symfony\Component\Console\Output\ConsoleOutput
29 | //
30 | // Returns true if current environment supports writing console output
31 | // to STDOUT.
32 | //
33 | // IBM iSeries (OS400) exhibits character-encoding issues when writing
34 | // to STDOUT and doesn't properly convert ASCII to EBCDIC, resulting in
35 | // garbage output.
36 |
37 | $stream = 'OS400' === php_uname('s') ? 'php://output' : 'php://stdout';
38 |
39 | parent::__construct(fopen($stream, 'w'));
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/IO/OutputStream/StreamOutputStream.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Webmozart\Console\IO\OutputStream;
13 |
14 | use Webmozart\Assert\Assert;
15 | use Webmozart\Console\Api\IO\IOException;
16 | use Webmozart\Console\Api\IO\OutputStream;
17 |
18 | /**
19 | * An output stream that writes to a PHP stream.
20 | *
21 | * @since 1.0
22 | *
23 | * @author Bernhard Schussek
24 | */
25 | class StreamOutputStream implements OutputStream
26 | {
27 | /**
28 | * @var resource
29 | */
30 | private $stream;
31 |
32 | /**
33 | * Creates the stream.
34 | *
35 | * @param resource $stream A stream resource.
36 | */
37 | public function __construct($stream)
38 | {
39 | Assert::resource($stream, 'stream');
40 |
41 | $this->stream = $stream;
42 | }
43 |
44 | /**
45 | * {@inheritdoc}
46 | */
47 | public function write($string)
48 | {
49 | if (null === $this->stream) {
50 | throw new IOException('Cannot read from a closed input.');
51 | }
52 |
53 | if (false === fwrite($this->stream, $string)) {
54 | throw new IOException('Could not write stream.');
55 | }
56 | }
57 |
58 | /**
59 | * {@inheritdoc}
60 | */
61 | public function flush()
62 | {
63 | if (null === $this->stream) {
64 | throw new IOException('Cannot read from a closed input.');
65 | }
66 |
67 | if (false === fflush($this->stream)) {
68 | throw new IOException('Could not flush stream.');
69 | }
70 | }
71 |
72 | /**
73 | * {@inheritdoc}
74 | */
75 | public function supportsAnsi()
76 | {
77 | if (DIRECTORY_SEPARATOR === '\\') {
78 | return false !== getenv('ANSICON') || 'ON' === getenv('ConEmuANSI') || 'xterm' === getenv('TERM');
79 | }
80 |
81 | return function_exists('posix_isatty') && @posix_isatty($this->stream);
82 | }
83 |
84 | /**
85 | * {@inheritdoc}
86 | */
87 | public function close()
88 | {
89 | if ($this->stream) {
90 | @fclose($this->stream);
91 | $this->stream = null;
92 | }
93 | }
94 |
95 | /**
96 | * {@inheritdoc}
97 | */
98 | public function isClosed()
99 | {
100 | return null === $this->stream;
101 | }
102 | }
103 |
--------------------------------------------------------------------------------
/src/Process/ProcessLauncher.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Webmozart\Console\Process;
13 |
14 | use RuntimeException;
15 | use Symfony\Component\Process\ProcessUtils;
16 |
17 | /**
18 | * Launches an interactive process in the foreground.
19 | *
20 | * This class is used to execute "man" and "less".
21 | *
22 | * @since 1.0
23 | *
24 | * @author Bernhard Schussek
25 | */
26 | class ProcessLauncher
27 | {
28 | /**
29 | * @var bool
30 | */
31 | private $running = false;
32 |
33 | /**
34 | * @var float
35 | */
36 | private $checkInterval = 0.1;
37 |
38 | /**
39 | * Returns whether the launcher is supported on the current system.
40 | *
41 | * @return bool Whether the launcher is supported on the current system.
42 | */
43 | public function isSupported()
44 | {
45 | return function_exists('proc_open');
46 | }
47 |
48 | /**
49 | * Returns whether the launcher is currently running.
50 | *
51 | * @return bool Whether the launcher is running.
52 | */
53 | public function isRunning()
54 | {
55 | return $this->running;
56 | }
57 |
58 | /**
59 | * Returns the interval used to check whether the process is still alive.
60 | *
61 | * By default, the interval is 1 second.
62 | *
63 | * @param float $checkInterval The check interval.
64 | */
65 | public function setCheckInterval($checkInterval)
66 | {
67 | $this->checkInterval = $checkInterval;
68 | }
69 |
70 | /**
71 | * Launches a process in the foreground.
72 | *
73 | * @param string $command The command to execute.
74 | * @param string[] $arguments Arguments to be quoted and inserted into the
75 | * command. Each key "key" in the array should
76 | * correspond to a placeholder "%key%" in the
77 | * command.
78 | * @param bool $killable Whether the process can be killed by the user.
79 | *
80 | * @return int The exit status of the process.
81 | */
82 | public function launchProcess($command, array $arguments = array(), $killable = true)
83 | {
84 | $this->installSignalHandlers($killable);
85 |
86 | $exitCode = $this->run($command, $arguments);
87 |
88 | $this->restoreSignalHandlers($killable);
89 |
90 | return $exitCode;
91 | }
92 |
93 | private function installSignalHandlers($terminable = true)
94 | {
95 | if (function_exists('pcntl_signal') && !$terminable) {
96 | pcntl_signal(SIGTERM, SIG_IGN);
97 | pcntl_signal(SIGINT, SIG_IGN);
98 | }
99 | }
100 |
101 | private function restoreSignalHandlers($terminable = true)
102 | {
103 | if (function_exists('pcntl_signal') && !$terminable) {
104 | pcntl_signal(SIGTERM, SIG_DFL);
105 | pcntl_signal(SIGINT, SIG_DFL);
106 | }
107 | }
108 |
109 | private function run($command, array $arguments)
110 | {
111 | if (!function_exists('proc_open')) {
112 | throw new RuntimeException('The "proc_open" function is not available.');
113 | }
114 |
115 | $replacements = array();
116 |
117 | foreach ($arguments as $name => $value) {
118 | $replacements['%'.$name.'%'] = ProcessUtils::escapeArgument($value);
119 | }
120 |
121 | // Insert quoted arguments
122 | $command = strtr($command, $replacements);
123 |
124 | $dspec = array(
125 | 0 => STDIN,
126 | 1 => STDOUT,
127 | 2 => STDERR,
128 | );
129 |
130 | $this->running = true;
131 | $proc = proc_open($command, $dspec, $pipes, null, null);
132 |
133 | if (is_resource($proc)) {
134 | while (true) {
135 | $status = proc_get_status($proc);
136 |
137 | if (!$status['running']) {
138 | break;
139 | }
140 |
141 | sleep($this->checkInterval);
142 | }
143 |
144 | proc_close($proc);
145 | }
146 |
147 | $this->running = false;
148 |
149 | return isset($status['exitcode']) ? $status['exitcode'] : 1;
150 | }
151 | }
152 |
--------------------------------------------------------------------------------
/src/Resolver/ResolveResult.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Webmozart\Console\Resolver;
13 |
14 | use Webmozart\Console\Api\Args\Args;
15 | use Webmozart\Console\Api\Args\CannotParseArgsException;
16 | use Webmozart\Console\Api\Args\RawArgs;
17 | use Webmozart\Console\Api\Command\Command;
18 |
19 | /**
20 | * An intermediate result created during resolving.
21 | *
22 | * @since 1.0
23 | *
24 | * @author Bernhard Schussek
25 | */
26 | class ResolveResult
27 | {
28 | /**
29 | * @var Command
30 | */
31 | private $command;
32 |
33 | /**
34 | * @var RawArgs
35 | */
36 | private $rawArgs;
37 |
38 | /**
39 | * @var Args
40 | */
41 | private $parsedArgs;
42 |
43 | /**
44 | * @var CannotParseArgsException
45 | */
46 | private $parseError;
47 |
48 | /**
49 | * @var bool
50 | */
51 | private $parsed = false;
52 |
53 | /**
54 | * Creates a new resolved command.
55 | *
56 | * @param Command $command The command.
57 | * @param RawArgs $rawArgs The raw console arguments.
58 | */
59 | public function __construct(Command $command, RawArgs $rawArgs)
60 | {
61 | $this->command = $command;
62 | $this->rawArgs = $rawArgs;
63 | }
64 |
65 | /**
66 | * Returns the command.
67 | *
68 | * @return Command The command.
69 | */
70 | public function getCommand()
71 | {
72 | return $this->command;
73 | }
74 |
75 | /**
76 | * The raw console arguments.
77 | *
78 | * @return RawArgs The raw console arguments.
79 | */
80 | public function getRawArgs()
81 | {
82 | return $this->rawArgs;
83 | }
84 |
85 | /**
86 | * Returns the parsed console arguments.
87 | *
88 | * @return Args The parsed console arguments or `null` if the console
89 | * arguments cannot be parsed.
90 | *
91 | * @see isParsable(), getParseError()
92 | */
93 | public function getParsedArgs()
94 | {
95 | if (!$this->parsed) {
96 | $this->parse();
97 | }
98 |
99 | return $this->parsedArgs;
100 | }
101 |
102 | /**
103 | * Returns the error that happened during argument parsing.
104 | *
105 | * @return CannotParseArgsException The parse error or `null` if the
106 | * arguments were parsed successfully.
107 | *
108 | * @see isParsable(), getParsedArgs()
109 | */
110 | public function getParseError()
111 | {
112 | if (!$this->parsed) {
113 | $this->parse();
114 | }
115 |
116 | return $this->parseError;
117 | }
118 |
119 | /**
120 | * Returns whether the console arguments can be parsed.
121 | *
122 | * @return bool Returns `true` if the console arguments can be parsed and
123 | * `false` if a parse error occurred.
124 | *
125 | * @see getParsedArgs(), getParseError()
126 | */
127 | public function isParsable()
128 | {
129 | if (!$this->parsed) {
130 | $this->parse();
131 | }
132 |
133 | return null === $this->parseError;
134 | }
135 |
136 | private function parse()
137 | {
138 | try {
139 | $this->parsedArgs = $this->command->parseArgs($this->rawArgs);
140 | } catch (CannotParseArgsException $e) {
141 | $this->parseError = $e;
142 | }
143 |
144 | $this->parsed = true;
145 | }
146 | }
147 |
--------------------------------------------------------------------------------
/src/UI/Alignment/LabelAlignment.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Webmozart\Console\UI\Alignment;
13 |
14 | use Webmozart\Console\Api\Formatter\Formatter;
15 | use Webmozart\Console\UI\Component\LabeledParagraph;
16 |
17 | /**
18 | * Aligns labeled paragraphs.
19 | *
20 | * The alignment takes {@link LabeledParagraph} instances and aligns the texts
21 | * next to the labels so that all texts start at the same offset. Pass the
22 | * paragraphs that you want to align to {@link add()}. When you call
23 | * {@link align()}, the text offset is calculated. You can retrieve the
24 | * calculated offset with {@link getTextOffset()}.
25 | *
26 | * @since 1.0
27 | *
28 | * @author Bernhard Schussek
29 | */
30 | class LabelAlignment
31 | {
32 | /**
33 | * @var LabeledParagraph[]
34 | */
35 | private $paragraphs = array();
36 |
37 | /**
38 | * @var int[]
39 | */
40 | private $indentations = array();
41 |
42 | /**
43 | * @var int
44 | */
45 | private $textOffset = 0;
46 |
47 | /**
48 | * Adds a labeled paragraph to the alignment.
49 | *
50 | * @param LabeledParagraph $paragraph The labeled paragraph.
51 | * @param int $indentation The indentation of the paragraph.
52 | */
53 | public function add(LabeledParagraph $paragraph, $indentation = 0)
54 | {
55 | if ($paragraph->isAligned()) {
56 | $this->paragraphs[] = $paragraph;
57 | $this->indentations[] = $indentation;
58 | }
59 | }
60 |
61 | /**
62 | * Calculates the text offset based on all labels in the alignment.
63 | *
64 | * The passed indentation is added to the indentations of all labeled
65 | * paragraphs.
66 | *
67 | * @param Formatter $formatter The formatter used to remove style tags when
68 | * calculating the label width.
69 | * @param int $indentation The indentation.
70 | */
71 | public function align(Formatter $formatter, $indentation = 0)
72 | {
73 | $this->textOffset = 0;
74 |
75 | foreach ($this->paragraphs as $i => $item) {
76 | $label = $formatter->removeFormat($item->getLabel());
77 | $textOffset = $this->indentations[$i] + strlen($label) + $item->getPadding();
78 |
79 | $this->textOffset = max($this->textOffset, $textOffset);
80 | }
81 |
82 | $this->textOffset += $indentation;
83 | }
84 |
85 | /**
86 | * Manually sets the text offset.
87 | *
88 | * @param int $textOffset The text offset.
89 | */
90 | public function setTextOffset($textOffset)
91 | {
92 | $this->textOffset = $textOffset;
93 | }
94 |
95 | /**
96 | * Returns the calculated text offset.
97 | *
98 | * Before calling {@link align()} or {@link setTextOffset()}, this method
99 | * returns 0.
100 | *
101 | * @return int The text offset.
102 | */
103 | public function getTextOffset()
104 | {
105 | return $this->textOffset;
106 | }
107 | }
108 |
--------------------------------------------------------------------------------
/src/UI/Component.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Webmozart\Console\UI;
13 |
14 | use Webmozart\Console\Api\IO\IO;
15 |
16 | /**
17 | * A UI component that can be rendered on the I/O.
18 | *
19 | * @since 1.0
20 | *
21 | * @author Bernhard Schussek
22 | */
23 | interface Component
24 | {
25 | /**
26 | * Renders the component.
27 | *
28 | * @param IO $io The I/O.
29 | * @param int $indentation The number of spaces to indent.
30 | */
31 | public function render(IO $io, $indentation = 0);
32 | }
33 |
--------------------------------------------------------------------------------
/src/UI/Component/EmptyLine.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Webmozart\Console\UI\Component;
13 |
14 | use Webmozart\Console\Api\IO\IO;
15 | use Webmozart\Console\UI\Component;
16 |
17 | /**
18 | * An empty line.
19 | *
20 | * Contrary to a {@link Line} with no text, an empty line is never indented.
21 | *
22 | * @since 1.0
23 | *
24 | * @author Bernhard Schussek
25 | */
26 | class EmptyLine implements Component
27 | {
28 | /**
29 | * Renders the empty line.
30 | *
31 | * @param IO $io The I/O.
32 | * @param int $indentation The number of spaces to indent.
33 | */
34 | public function render(IO $io, $indentation = 0)
35 | {
36 | // Indentation is ignored for empty lines
37 | $io->write("\n");
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/UI/Component/NameVersion.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Webmozart\Console\UI\Component;
13 |
14 | use Webmozart\Console\Api\Config\ApplicationConfig;
15 | use Webmozart\Console\Api\IO\IO;
16 | use Webmozart\Console\UI\Component;
17 |
18 | /**
19 | * Renders the name and version of an application.
20 | *
21 | * @since 1.0
22 | *
23 | * @author Bernhard Schussek
24 | */
25 | class NameVersion implements Component
26 | {
27 | private $config;
28 |
29 | /**
30 | * Creates the renderer.
31 | *
32 | * @param ApplicationConfig $config The application configuration.
33 | */
34 | public function __construct(ApplicationConfig $config)
35 | {
36 | $this->config = $config;
37 | }
38 |
39 | /**
40 | * Renders the name and version.
41 | *
42 | * @param IO $io The I/O.
43 | * @param int $indentation The number of spaces to indent.
44 | */
45 | public function render(IO $io, $indentation = 0)
46 | {
47 | if ($this->config->getDisplayName() && $this->config->getVersion()) {
48 | $paragraph = new Paragraph("{$this->config->getDisplayName()} version {$this->config->getVersion()}");
49 | } elseif ($this->config->getDisplayName()) {
50 | $paragraph = new Paragraph("{$this->config->getDisplayName()}");
51 | } else {
52 | $paragraph = new Paragraph('Console Tool');
53 | }
54 |
55 | $paragraph->render($io, $indentation);
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/src/UI/Component/Paragraph.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Webmozart\Console\UI\Component;
13 |
14 | use Webmozart\Console\Api\IO\IO;
15 | use Webmozart\Console\UI\Component;
16 |
17 | /**
18 | * A paragraph of text.
19 | *
20 | * The paragraph is wrapped into the dimensions of the output.
21 | *
22 | * @since 1.0
23 | *
24 | * @author Bernhard Schussek
25 | */
26 | class Paragraph implements Component
27 | {
28 | /**
29 | * @var string
30 | */
31 | private $text;
32 |
33 | /**
34 | * Creates a new paragraph.
35 | *
36 | * @param string $text The text of the paragraph.
37 | */
38 | public function __construct($text)
39 | {
40 | $this->text = $text;
41 | }
42 |
43 | /**
44 | * Renders the paragraph.
45 | *
46 | * @param IO $io The I/O.
47 | * @param int $indentation The number of spaces to indent.
48 | */
49 | public function render(IO $io, $indentation = 0)
50 | {
51 | $linePrefix = str_repeat(' ', $indentation);
52 | $textWidth = $io->getTerminalDimensions()->getWidth() - 1 - $indentation;
53 | // TODO replace wordwrap() by implementation that is aware of format codes
54 | $text = preg_replace("~\n(?!\n)~", "\n".$linePrefix, wordwrap($this->text, $textWidth));
55 |
56 | $io->write($linePrefix.rtrim($text)."\n");
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/src/UI/Layout/BlockLayout.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Webmozart\Console\UI\Layout;
13 |
14 | use Webmozart\Console\Api\IO\IO;
15 | use Webmozart\Console\UI\Alignment\LabelAlignment;
16 | use Webmozart\Console\UI\Component;
17 | use Webmozart\Console\UI\Component\LabeledParagraph;
18 |
19 | /**
20 | * Renders renderable objects in indented blocks.
21 | *
22 | * @since 1.0
23 | *
24 | * @author Bernhard Schussek
25 | */
26 | class BlockLayout implements Component
27 | {
28 | /**
29 | * @var int
30 | */
31 | private $currentIndentation = 0;
32 |
33 | /**
34 | * @var Component[]
35 | */
36 | private $elements = array();
37 |
38 | /**
39 | * @var int[]
40 | */
41 | private $indentations = array();
42 |
43 | /**
44 | * @var LabelAlignment
45 | */
46 | private $alignment;
47 |
48 | /**
49 | * Creates a new layout.
50 | */
51 | public function __construct()
52 | {
53 | $this->alignment = new LabelAlignment();
54 | }
55 |
56 | /**
57 | * Adds a renderable element to the layout.
58 | *
59 | * @param Component $element The element to add.
60 | *
61 | * @return static The current instance.
62 | */
63 | public function add(Component $element)
64 | {
65 | $this->elements[] = $element;
66 | $this->indentations[] = $this->currentIndentation;
67 |
68 | if ($element instanceof LabeledParagraph) {
69 | $this->alignment->add($element, $this->currentIndentation);
70 | $element->setAlignment($this->alignment);
71 | }
72 |
73 | return $this;
74 | }
75 |
76 | /**
77 | * Starts a new indented block.
78 | *
79 | * @return static The current instance.
80 | */
81 | public function beginBlock()
82 | {
83 | $this->currentIndentation += 2;
84 |
85 | return $this;
86 | }
87 |
88 | /**
89 | * Ends the current indented block.
90 | *
91 | * @return static The current instance.
92 | */
93 | public function endBlock()
94 | {
95 | $this->currentIndentation -= 2;
96 |
97 | return $this;
98 | }
99 |
100 | /**
101 | * Renders all elements in the layout.
102 | *
103 | * @param IO $io The I/O.
104 | * @param int $indentation The number of spaces to indent.
105 | */
106 | public function render(IO $io, $indentation = 0)
107 | {
108 | $this->alignment->align($io, $indentation);
109 |
110 | foreach ($this->elements as $i => $element) {
111 | $element->render($io, $this->indentations[$i] + $indentation);
112 | }
113 |
114 | $this->elements = array();
115 | }
116 | }
117 |
--------------------------------------------------------------------------------
/src/UI/Rectangle.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Webmozart\Console\UI;
13 |
14 | /**
15 | * A rectangle.
16 | *
17 | * @since 1.0
18 | *
19 | * @author Bernhard Schussek
20 | */
21 | class Rectangle
22 | {
23 | /**
24 | * @var int
25 | */
26 | private $width;
27 |
28 | /**
29 | * @var int
30 | */
31 | private $height;
32 |
33 | /**
34 | * Creates dimensions with the given width and height.
35 | *
36 | * @param int $width The width as number of printable characters.
37 | * @param int $height The height as number of printable lines.
38 | */
39 | public function __construct($width, $height)
40 | {
41 | $this->width = (int) $width;
42 | $this->height = (int) $height;
43 | }
44 |
45 | /**
46 | * Returns the width.
47 | *
48 | * @return int The width as number of printable characters.
49 | */
50 | public function getWidth()
51 | {
52 | return $this->width;
53 | }
54 |
55 | /**
56 | * Returns the height.
57 | *
58 | * @return int The height as number of printable lines.
59 | */
60 | public function getHeight()
61 | {
62 | return $this->height;
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/src/UI/Style/Alignment.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Webmozart\Console\UI\Style;
13 |
14 | /**
15 | * Constants for text alignment.
16 | *
17 | * @since 1.0
18 | *
19 | * @author Bernhard Schussek
20 | */
21 | final class Alignment
22 | {
23 | /**
24 | * Alignment: Align a cell to the left.
25 | */
26 | const LEFT = 0;
27 |
28 | /**
29 | * Alignment: Align a cell to the right.
30 | */
31 | const RIGHT = 1;
32 |
33 | /**
34 | * Alignment: Align a cell to the center.
35 | */
36 | const CENTER = 2;
37 |
38 | /**
39 | * Returns all possible alignments.
40 | *
41 | * @return int[] A list of valid alignment constants.
42 | */
43 | public static function all()
44 | {
45 | return array(
46 | self::LEFT,
47 | self::RIGHT,
48 | self::CENTER,
49 | );
50 | }
51 |
52 | private function __construct()
53 | {
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/src/Util/ProcessTitle.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Webmozart\Console\Util;
13 |
14 | /**
15 | * Sets and resets the PHP process title.
16 | *
17 | * @since 1.0
18 | *
19 | * @author Bernhard Schussek
20 | */
21 | class ProcessTitle
22 | {
23 | /**
24 | * @var bool
25 | */
26 | private static $supported;
27 |
28 | /**
29 | * @var string[]
30 | */
31 | private static $processTitles = array();
32 |
33 | /**
34 | * Returns whether process titles can be set.
35 | *
36 | * @return bool Returns `true` if process titles can be set and `false`
37 | * otherwise.
38 | */
39 | public static function isSupported()
40 | {
41 | if (null === self::$supported) {
42 | self::$supported = function_exists('cli_set_process_title') || function_exists('setproctitle');
43 | }
44 |
45 | return self::$supported;
46 | }
47 |
48 | /**
49 | * Sets the title of the PHP process.
50 | *
51 | * @param string $processTitle The process title.
52 | */
53 | public static function setProcessTitle($processTitle)
54 | {
55 | self::$processTitles[] = $processTitle;
56 |
57 | self::changeProcessTitleTo($processTitle);
58 | }
59 |
60 | /**
61 | * Resets the title of the PHP process to the previous value.
62 | */
63 | public static function resetProcessTitle()
64 | {
65 | $processTitle = self::$processTitles ? array_pop(self::$processTitles) : null;
66 |
67 | self::changeProcessTitleTo($processTitle);
68 | }
69 |
70 | private static function changeProcessTitleTo($processTitle)
71 | {
72 | if (function_exists('cli_set_process_title')) {
73 | cli_set_process_title($processTitle);
74 | } elseif (function_exists('setproctitle')) {
75 | setproctitle($processTitle);
76 | }
77 | }
78 |
79 | private function __construct()
80 | {
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/src/Util/SimilarCommandName.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Webmozart\Console\Util;
13 |
14 | use Webmozart\Console\Api\Command\CommandCollection;
15 |
16 | /**
17 | * Utility to find similar command names.
18 | *
19 | * @since 1.0
20 | *
21 | * @author Bernhard Schussek
22 | */
23 | class SimilarCommandName
24 | {
25 | /**
26 | * Searches a command collection for similar names.
27 | *
28 | * @param string $commandName The command name that was not found.
29 | * @param CommandCollection $commands The available commands.
30 | *
31 | * @return string[] The names of similar commands.
32 | */
33 | public static function find($commandName, CommandCollection $commands)
34 | {
35 | $threshold = 1e3;
36 | $distancesByName = array();
37 |
38 | // Include aliases in the search
39 | $actualNames = $commands->getNames(true);
40 |
41 | foreach ($actualNames as $actualName) {
42 | // Get Levenshtein distance between the input and each command name
43 | $distance = levenshtein($commandName, $actualName);
44 |
45 | $isSimilar = $distance <= (strlen($commandName) / 3);
46 | $isSubString = false !== strpos($actualName, $commandName);
47 |
48 | if ($isSimilar || $isSubString) {
49 | $distancesByName[$actualName] = $distance;
50 | }
51 | }
52 |
53 | // Only keep results with a distance below the threshold
54 | $distancesByName = array_filter($distancesByName, function ($distance) use ($threshold) {
55 | return $distance < 2 * $threshold;
56 | });
57 |
58 | // Display results with shortest distance first
59 | asort($distancesByName);
60 |
61 | $suggestedNames = array_keys($distancesByName);
62 |
63 | return self::filterDuplicates($suggestedNames, $commands);
64 | }
65 |
66 | private static function filterDuplicates(array $names, CommandCollection $commands)
67 | {
68 | $filteredNames = array();
69 |
70 | foreach ($names as $nameToFilter) {
71 | // Check all existing names for duplicates
72 | foreach ($filteredNames as $filteredName) {
73 | // $nameToFilter is a duplicate - skip
74 | if ($commands->get($nameToFilter) === $commands->get($filteredName)) {
75 | continue 2;
76 | }
77 | }
78 |
79 | $filteredNames[] = $nameToFilter;
80 | }
81 |
82 | return $filteredNames;
83 | }
84 |
85 | private function __construct()
86 | {
87 | }
88 | }
89 |
--------------------------------------------------------------------------------
/tests/Adapter/ApplicationAdapterTest.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Webmozart\Console\Tests\Adapter;
13 |
14 | use PHPUnit_Framework_TestCase;
15 | use Symfony\Component\Console\Helper\HelperSet;
16 | use Webmozart\Console\Adapter\ApplicationAdapter;
17 | use Webmozart\Console\Adapter\ArgsFormatInputDefinition;
18 | use Webmozart\Console\Adapter\CommandAdapter;
19 | use Webmozart\Console\Api\Config\ApplicationConfig;
20 | use Webmozart\Console\ConsoleApplication;
21 |
22 | /**
23 | * @since 1.0
24 | *
25 | * @author Bernhard Schussek
26 | */
27 | class ApplicationAdapterTest extends PHPUnit_Framework_TestCase
28 | {
29 | public function testCreate()
30 | {
31 | $config = ApplicationConfig::create()
32 | ->setName('test-bin')
33 | ->setDisplayName('Test Name')
34 | ->setVersion('1.2.3')
35 | ->setHelperSet($helperSet = new HelperSet())
36 | ->beginCommand('command')->end()
37 | ;
38 |
39 | $application = new ConsoleApplication($config);
40 | $adapter = new ApplicationAdapter($application);
41 |
42 | $this->assertSame('Test Name', $adapter->getName());
43 | $this->assertSame('1.2.3', $adapter->getVersion());
44 | $this->assertSame('Test Name version 1.2.3', $adapter->getLongVersion());
45 | $this->assertSame('Test Name version 1.2.3', $adapter->getHelp());
46 | $this->assertSame($helperSet, $adapter->getHelperSet());
47 | $this->assertSame(array(), $adapter->getNamespaces());
48 | $this->assertEquals(new ArgsFormatInputDefinition($application->getGlobalArgsFormat()), $adapter->getDefinition());
49 |
50 | $commandAdapter = new CommandAdapter($application->getCommand('command'), $adapter);
51 | $commandAdapter->setApplication($adapter);
52 | $commandAdapter->setHelperSet($helperSet);
53 |
54 | $this->assertEquals($commandAdapter, $adapter->get('command'));
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/tests/Adapter/CommandAdapterTest.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Webmozart\Console\Tests\Adapter;
13 |
14 | use PHPUnit_Framework_TestCase;
15 | use Symfony\Component\Console\Helper\HelperSet;
16 | use Webmozart\Console\Adapter\ApplicationAdapter;
17 | use Webmozart\Console\Adapter\ArgsFormatInputDefinition;
18 | use Webmozart\Console\Adapter\CommandAdapter;
19 | use Webmozart\Console\Api\Command\Command;
20 | use Webmozart\Console\Api\Config\ApplicationConfig;
21 | use Webmozart\Console\Api\Config\CommandConfig;
22 | use Webmozart\Console\ConsoleApplication;
23 |
24 | /**
25 | * @since 1.0
26 | *
27 | * @author Bernhard Schussek
28 | */
29 | class CommandAdapterTest extends PHPUnit_Framework_TestCase
30 | {
31 | public function testCreate()
32 | {
33 | $config = CommandConfig::create()
34 | ->setName('command')
35 | ->addAlias('alias1')
36 | ->addAlias('alias2')
37 | ->setDescription('Description of the command')
38 | ->setHelp('The help for %command.name%')
39 | ->addArgument('argument')
40 | ->addOption('option', 'o')
41 | ->setHelperSet($helperSet = new HelperSet())
42 | ;
43 |
44 | $applicationConfig = new ApplicationConfig();
45 | $application = new ConsoleApplication($applicationConfig);
46 | $applicationAdapter = new ApplicationAdapter($application);
47 |
48 | $command = new Command($config, $application);
49 | $adapter = new CommandAdapter($command, $applicationAdapter);
50 |
51 | $this->assertSame('command', $adapter->getName());
52 | $this->assertEquals(new ArgsFormatInputDefinition($command->getArgsFormat()), $adapter->getDefinition());
53 | $this->assertEquals(new ArgsFormatInputDefinition($command->getArgsFormat()), $adapter->getNativeDefinition());
54 | $this->assertSame($command, $adapter->getAdaptedCommand());
55 | $this->assertSame(array('alias1', 'alias2'), $adapter->getAliases());
56 | $this->assertSame($applicationAdapter, $adapter->getApplication());
57 | $this->assertSame('Description of the command', $adapter->getDescription());
58 | $this->assertSame('The help for %command.name%', $adapter->getHelp());
59 | $this->assertSame('The help for command', $adapter->getProcessedHelp());
60 | $this->assertSame($helperSet, $adapter->getHelperSet());
61 | $this->assertSame('command [-o|--option] [--] []', $adapter->getSynopsis());
62 | $this->assertTrue($adapter->isEnabled());
63 | }
64 |
65 | public function testCreateDisabled()
66 | {
67 | $config = CommandConfig::create()
68 | ->setName('command')
69 | ->disable()
70 | ;
71 |
72 | $applicationConfig = new ApplicationConfig();
73 | $application = new ConsoleApplication($applicationConfig);
74 | $applicationAdapter = new ApplicationAdapter($application);
75 |
76 | $command = new Command($config, $application);
77 | $adapter = new CommandAdapter($command, $applicationAdapter);
78 |
79 | $this->assertFalse($adapter->isEnabled());
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/tests/Adapter/FormatterAdapterTest.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Webmozart\Console\Tests\Adapter;
13 |
14 | use PHPUnit_Framework_TestCase;
15 | use Webmozart\Console\Adapter\FormatterAdapter;
16 |
17 | /**
18 | * @since 1.0
19 | *
20 | * @author Bernhard Schussek
21 | */
22 | class FormatterAdapterTest extends PHPUnit_Framework_TestCase
23 | {
24 | public function testFormatDecorated()
25 | {
26 | $formatter = $this->getMock('Webmozart\Console\Api\Formatter\Formatter');
27 |
28 | $formatter->expects($this->once())
29 | ->method('format')
30 | ->with('text')
31 | ->willReturn('formatted');
32 |
33 | $adapter = new FormatterAdapter($formatter);
34 | $adapter->setDecorated(true);
35 |
36 | $this->assertSame('formatted', $adapter->format('text'));
37 | }
38 |
39 | public function testFormatNonDecorated()
40 | {
41 | $formatter = $this->getMock('Webmozart\Console\Api\Formatter\Formatter');
42 |
43 | $formatter->expects($this->once())
44 | ->method('removeFormat')
45 | ->with('text')
46 | ->willReturn('unformatted');
47 |
48 | $adapter = new FormatterAdapter($formatter);
49 | $adapter->setDecorated(false);
50 |
51 | $this->assertSame('unformatted', $adapter->format('text'));
52 | }
53 |
54 | public function testIsDecorated()
55 | {
56 | $formatter = $this->getMock('Webmozart\Console\Api\Formatter\Formatter');
57 | $adapter = new FormatterAdapter($formatter);
58 |
59 | $this->assertTrue($adapter->isDecorated());
60 |
61 | $adapter->setDecorated(false);
62 |
63 | $this->assertFalse($adapter->isDecorated());
64 | }
65 |
66 | public function testGetAdaptedFormatter()
67 | {
68 | $formatter = $this->getMock('Webmozart\Console\Api\Formatter\Formatter');
69 | $adapter = new FormatterAdapter($formatter);
70 |
71 | $this->assertSame($formatter, $adapter->getAdaptedFormatter());
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/tests/Api/Args/Format/CommandNameTest.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Webmozart\Console\Tests\Api\Args\Format;
13 |
14 | use PHPUnit_Framework_TestCase;
15 | use Webmozart\Console\Api\Args\Format\CommandName;
16 |
17 | /**
18 | * @since 1.0
19 | *
20 | * @author Bernhard Schussek
21 | */
22 | class CommandNameTest extends PHPUnit_Framework_TestCase
23 | {
24 | /**
25 | * @dataProvider getValidNames
26 | */
27 | public function testCreate($string)
28 | {
29 | $commandName = new CommandName($string);
30 |
31 | $this->assertSame($string, $commandName->toString());
32 | }
33 |
34 | /**
35 | * @dataProvider getValidNames
36 | */
37 | public function testCreateWithAliases($string)
38 | {
39 | $commandName = new CommandName('cmd', array('alias', $string));
40 |
41 | $this->assertSame('cmd', $commandName->toString());
42 | $this->assertSame(array('alias', $string), $commandName->getAliases());
43 | }
44 |
45 | public function testToString()
46 | {
47 | $commandName = new CommandName('cmd');
48 |
49 | $this->assertSame('cmd', (string) $commandName);
50 | }
51 |
52 | /**
53 | * @dataProvider getInvalidNames
54 | * @expectedException \InvalidArgumentException
55 | */
56 | public function testCreateFailsIfInvalidString($string)
57 | {
58 | new CommandName($string);
59 | }
60 |
61 | /**
62 | * @dataProvider getInvalidNames
63 | * @expectedException \InvalidArgumentException
64 | */
65 | public function testCreateFailsIfInvalidAlias($string)
66 | {
67 | new CommandName('cmd', array($string));
68 | }
69 |
70 | public function getValidNames()
71 | {
72 | return array(
73 | array('command'),
74 | array('COMMAND'),
75 | array('command-name'),
76 | array('c'),
77 | array('command1'),
78 | );
79 | }
80 |
81 | public function getInvalidNames()
82 | {
83 | return array(
84 | array('command_name'),
85 | array('command&'),
86 | array(''),
87 | array(null),
88 | array(1234),
89 | array(true),
90 | );
91 | }
92 |
93 | public function testMatch()
94 | {
95 | $commandName = new CommandName('cmd', array('alias1', 'alias2'));
96 |
97 | $this->assertTrue($commandName->match('cmd'));
98 | $this->assertTrue($commandName->match('alias1'));
99 | $this->assertTrue($commandName->match('alias2'));
100 | $this->assertFalse($commandName->match('foo'));
101 | }
102 | }
103 |
--------------------------------------------------------------------------------
/tests/Api/Config/Fixtures/ConcreteConfig.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Webmozart\Console\Tests\Api\Config\Fixtures;
13 |
14 | use Webmozart\Console\Api\Config\Config;
15 |
16 | /**
17 | * @since 1.0
18 | *
19 | * @author Bernhard Schussek
20 | */
21 | class ConcreteConfig extends Config
22 | {
23 | public $configureCalled = false;
24 |
25 | protected function configure()
26 | {
27 | $this->configureCalled = true;
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/tests/Api/Config/SubCommandConfigTest.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Webmozart\Console\Tests\Api\Config;
13 |
14 | use PHPUnit_Framework_TestCase;
15 | use Symfony\Component\Console\Helper\HelperSet;
16 | use Webmozart\Console\Api\Config\ApplicationConfig;
17 | use Webmozart\Console\Api\Config\CommandConfig;
18 | use Webmozart\Console\Api\Config\SubCommandConfig;
19 | use Webmozart\Console\Args\DefaultArgsParser;
20 | use Webmozart\Console\Handler\NullHandler;
21 |
22 | /**
23 | * @since 1.0
24 | *
25 | * @author Bernhard Schussek
26 | */
27 | class SubCommandConfigTest extends PHPUnit_Framework_TestCase
28 | {
29 | /**
30 | * @var SubCommandConfig
31 | */
32 | private $config;
33 |
34 | /**
35 | * @var CommandConfig
36 | */
37 | private $parentConfig;
38 |
39 | /**
40 | * @var ApplicationConfig
41 | */
42 | private $applicationConfig;
43 |
44 | protected function setUp()
45 | {
46 | $this->applicationConfig = new ApplicationConfig();
47 | $this->parentConfig = new CommandConfig('command', $this->applicationConfig);
48 | $this->config = new SubCommandConfig('sub-command', $this->parentConfig, $this->applicationConfig);
49 | }
50 |
51 | public function testCreate()
52 | {
53 | $config = new SubCommandConfig();
54 |
55 | $this->assertNull($config->getParentConfig());
56 | $this->assertNull($config->getApplicationConfig());
57 | $this->assertNull($config->getName());
58 | }
59 |
60 | public function testCreateWithArguments()
61 | {
62 | $applicationConfig = new ApplicationConfig();
63 | $parentConfig = new CommandConfig('command', $applicationConfig);
64 | $config = new SubCommandConfig('sub-command', $parentConfig, $applicationConfig);
65 |
66 | $this->assertSame($parentConfig, $config->getParentConfig());
67 | $this->assertSame($applicationConfig, $config->getApplicationConfig());
68 | $this->assertSame('sub-command', $config->getName());
69 | }
70 |
71 | public function testGetHelperSetReturnsParentHelperSetByDefault()
72 | {
73 | $helperSet = new HelperSet();
74 |
75 | $this->parentConfig->setHelperSet($helperSet);
76 |
77 | $this->assertSame($helperSet, $this->config->getHelperSet());
78 | }
79 |
80 | public function testGetHandlerReturnsParentHandlerByDefault()
81 | {
82 | $handler = new NullHandler();
83 |
84 | $this->parentConfig->setHandler($handler);
85 |
86 | $this->assertSame($handler, $this->config->getHandler());
87 | }
88 |
89 | public function testGetHandlerMethodReturnsParentHandlerByDefault()
90 | {
91 | $this->parentConfig->setHandlerMethod('method');
92 |
93 | $this->assertSame('method', $this->config->getHandlerMethod());
94 | }
95 |
96 | public function testGetArgsParserReturnsParentArgsParserByDefault()
97 | {
98 | $parser = new DefaultArgsParser();
99 |
100 | $this->parentConfig->setArgsParser($parser);
101 |
102 | $this->assertSame($parser, $this->config->getArgsParser());
103 | }
104 |
105 | public function testLenientArgsParsingDefaultsToParentValue()
106 | {
107 | $this->parentConfig->enableLenientArgsParsing();
108 |
109 | $this->assertTrue($this->config->isLenientArgsParsingEnabled());
110 |
111 | $this->parentConfig->disableLenientArgsParsing();
112 |
113 | $this->assertFalse($this->config->isLenientArgsParsingEnabled());
114 | }
115 | }
116 |
--------------------------------------------------------------------------------
/tests/Api/IO/InputTest.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Webmozart\Console\Tests\Api\IO;
13 |
14 | use PHPUnit_Framework_TestCase;
15 | use Webmozart\Console\Api\IO\Input;
16 | use Webmozart\Console\IO\InputStream\StringInputStream;
17 |
18 | /**
19 | * @since 1.0
20 | *
21 | * @author Bernhard Schussek
22 | */
23 | class InputTest extends PHPUnit_Framework_TestCase
24 | {
25 | const LOREM_IPSUM = "Lorem ipsum dolor sit amet,\nconsetetur sadipscing elitr,\nsed diam nonumy eirmod tempor invidunt";
26 |
27 | /**
28 | * @var StringInputStream
29 | */
30 | private $stream;
31 |
32 | /**
33 | * @var Input
34 | */
35 | private $input;
36 |
37 | protected function setUp()
38 | {
39 | $this->stream = new StringInputStream();
40 | $this->input = new Input($this->stream);
41 | }
42 |
43 | public function testRead()
44 | {
45 | $this->stream->set('Lorem ipsum');
46 |
47 | $this->assertSame('L', $this->input->read(1));
48 | $this->assertSame('orem ipsum', $this->input->read(20));
49 | }
50 |
51 | public function testReadReturnsDefaultIfNotInteractive()
52 | {
53 | $this->stream->set('Lorem ipsum');
54 |
55 | $this->input->setInteractive(false);
56 |
57 | $this->assertSame('Default', $this->input->read(20, 'Default'));
58 | }
59 |
60 | public function testReadLine()
61 | {
62 | $this->stream->set(self::LOREM_IPSUM);
63 |
64 | $this->assertSame("Lorem ipsum dolor sit amet,\n", $this->input->readLine());
65 | $this->assertSame('consetetu', $this->input->readLine(null, 10));
66 | }
67 |
68 | public function testReadLineReturnsDefaultIfNotInteractive()
69 | {
70 | $this->stream->set(self::LOREM_IPSUM);
71 |
72 | $this->input->setInteractive(false);
73 |
74 | $this->assertSame('Default', $this->input->readLine('Default'));
75 | }
76 |
77 | public function testIsInteractive()
78 | {
79 | $this->assertTrue($this->input->isInteractive());
80 |
81 | $this->input->setInteractive(false);
82 |
83 | $this->assertFalse($this->input->isInteractive());
84 |
85 | $this->input->setInteractive(true);
86 |
87 | $this->assertTrue($this->input->isInteractive());
88 | }
89 |
90 | public function testClose()
91 | {
92 | $stream = $this->getMock('Webmozart\Console\Api\IO\InputStream');
93 | $this->input = new Input($stream);
94 |
95 | $stream->expects($this->once())
96 | ->method('close');
97 |
98 | $this->input->close();
99 | }
100 |
101 | public function testIsClosed()
102 | {
103 | $stream = $this->getMock('Webmozart\Console\Api\IO\InputStream');
104 | $this->input = new Input($stream);
105 |
106 | $stream->expects($this->once())
107 | ->method('isClosed')
108 | ->willReturn('RESULT');
109 |
110 | $this->assertSame('RESULT', $this->input->isClosed());
111 | }
112 | }
113 |
--------------------------------------------------------------------------------
/tests/Args/ArgvArgsTest.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Webmozart\Console\Tests\Args;
13 |
14 | use PHPUnit_Framework_TestCase;
15 | use Webmozart\Console\Args\ArgvArgs;
16 |
17 | /**
18 | * @since 1.0
19 | *
20 | * @author Bernhard Schussek
21 | */
22 | class ArgvArgsTest extends PHPUnit_Framework_TestCase
23 | {
24 | public function testCreate()
25 | {
26 | $_SERVER['argv'] = array('console', 'server', 'add', '--port', '80', 'localhost');
27 |
28 | $args = new ArgvArgs();
29 |
30 | $this->assertSame('console', $args->getScriptName());
31 | $this->assertSame(array('server', 'add', '--port', '80', 'localhost'), $args->getTokens());
32 | }
33 |
34 | public function testCreateWithCustomTokens()
35 | {
36 | $_SERVER['argv'] = array('console', 'server', 'add', 'localhost');
37 |
38 | $args = new ArgvArgs(array('other', 'server', 'add', '--port', '80', 'localhost'));
39 |
40 | $this->assertSame('other', $args->getScriptName());
41 | $this->assertSame(array('server', 'add', '--port', '80', 'localhost'), $args->getTokens());
42 | }
43 |
44 | public function testCreateNoArgs()
45 | {
46 | $args = new ArgvArgs(array());
47 |
48 | $this->assertNull($args->getScriptName());
49 | $this->assertSame(array(), $args->getTokens());
50 | }
51 |
52 | public function testHasToken()
53 | {
54 | $args = new ArgvArgs(array('console', 'server', 'add', '--port', '80', 'localhost'));
55 |
56 | $this->assertTrue($args->hasToken('server'));
57 | $this->assertTrue($args->hasToken('--port'));
58 | $this->assertTrue($args->hasToken('80'));
59 | $this->assertFalse($args->hasToken('console'));
60 | $this->assertFalse($args->hasToken('foobar'));
61 | }
62 |
63 | public function testToString()
64 | {
65 | $args = new ArgvArgs(array('console', 'server', 'add', '--port', '80', 'localhost'));
66 |
67 | $this->assertSame('console server add --port 80 localhost', $args->toString());
68 | $this->assertSame('console server add --port 80 localhost', $args->toString(true));
69 | $this->assertSame('server add --port 80 localhost', $args->toString(false));
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/tests/Args/StringArgsTest.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Webmozart\Console\Tests\Args;
13 |
14 | use PHPUnit_Framework_TestCase;
15 | use Webmozart\Console\Args\StringArgs;
16 |
17 | /**
18 | * @since 1.0
19 | *
20 | * @author Bernhard Schussek
21 | */
22 | class StringArgsTest extends PHPUnit_Framework_TestCase
23 | {
24 | /**
25 | * @dataProvider getStringsToParse
26 | */
27 | public function testCreate($string, array $tokens)
28 | {
29 | $args = new StringArgs($string);
30 |
31 | $this->assertSame($tokens, $args->getTokens());
32 | }
33 |
34 | public function getStringsToParse()
35 | {
36 | return array(
37 | array('', array()),
38 | array('foo', array('foo')),
39 | array(' foo bar ', array('foo', 'bar')),
40 | array('"quoted"', array('quoted')),
41 | array("'quoted'", array('quoted')),
42 | array("'a\rb\nc\td'", array("a\rb\nc\td")),
43 | array("'a'\r'b'\n'c'\t'd'", array('a', 'b', 'c', 'd')),
44 | array('"quoted \'twice\'"', array('quoted \'twice\'')),
45 | array("'quoted \"twice\"'", array('quoted "twice"')),
46 | array('"quoted \'three \"times\"\'"', array('quoted \'three "times"\'')),
47 | array("'quoted \"three 'times'\"'", array('quoted "three \'times\'"')),
48 | array("\\'escaped\\'", array('\'escaped\'')),
49 | array('\"escaped\"', array('"escaped"')),
50 | array("\\'escaped more\\'", array('\'escaped', 'more\'')),
51 | array('\"escaped more\"', array('"escaped', 'more"')),
52 | array('-a', array('-a')),
53 | array('-azc', array('-azc')),
54 | array('-awithavalue', array('-awithavalue')),
55 | array('-a"foo bar"', array('-afoo bar')),
56 | array('-a"foo bar""foo bar"', array('-afoo barfoo bar')),
57 | array('-a\'foo bar\'', array('-afoo bar')),
58 | array('-a\'foo bar\'\'foo bar\'', array('-afoo barfoo bar')),
59 | array('-a\'foo bar\'"foo bar"', array('-afoo barfoo bar')),
60 | array('--long-option', array('--long-option')),
61 | array('--long-option=foo', array('--long-option=foo')),
62 | array('--long-option="foo bar"', array('--long-option=foo bar')),
63 | array('--long-option="foo bar""another"', array('--long-option=foo baranother')),
64 | array('--long-option=\'foo bar\'', array('--long-option=foo bar')),
65 | array("--long-option='foo bar''another'", array('--long-option=foo baranother')),
66 | array("--long-option='foo bar'\"another\"", array('--long-option=foo baranother')),
67 | array('foo -a -ffoo --long bar', array('foo', '-a', '-ffoo', '--long', 'bar')),
68 | array('\\\' \\"', array('\'', '"')),
69 | );
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/tests/Fixtures/terminate-after-run.php:
--------------------------------------------------------------------------------
1 | setTerminateAfterRun(true)
11 |
12 | ->editCommand('help')
13 | ->setHandler(new CallbackHandler(function () {
14 | return 123;
15 | }))
16 | ->end()
17 | ;
18 |
19 | $application = new ConsoleApplication($config);
20 | $application->run();
21 |
22 | // Should not be executed
23 | exit(234);
24 |
--------------------------------------------------------------------------------
/tests/Formatter/AnsiFormatterTest.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Webmozart\Console\Tests\Formatter;
13 |
14 | use PHPUnit_Framework_TestCase;
15 | use Webmozart\Console\Api\Formatter\Style;
16 | use Webmozart\Console\Api\Formatter\StyleSet;
17 | use Webmozart\Console\Formatter\AnsiFormatter;
18 |
19 | /**
20 | * @since 1.0
21 | *
22 | * @author Bernhard Schussek
23 | */
24 | class AnsiFormatterTest extends PHPUnit_Framework_TestCase
25 | {
26 | public function testFormat()
27 | {
28 | $formatter = new AnsiFormatter(new StyleSet(array(
29 | Style::tag('bold')->bold(),
30 | Style::tag('yellow')->fgYellow(),
31 | )));
32 |
33 | $this->assertSame("\033[1mtext\033[22m", $formatter->format('text'));
34 | }
35 |
36 | public function testFormatWithStyle()
37 | {
38 | $formatter = new AnsiFormatter(new StyleSet(array(
39 | Style::tag('yellow')->fgYellow(),
40 | )));
41 |
42 | $this->assertSame("\033[1mtext\033[22m", $formatter->format('text', Style::noTag()->bold()));
43 | }
44 |
45 | public function testRemoveFormat()
46 | {
47 | $formatter = new AnsiFormatter(new StyleSet(array(
48 | Style::tag('bold')->bold(),
49 | Style::tag('yellow')->fgYellow(),
50 | )));
51 |
52 | $this->assertSame('text', $formatter->removeFormat('text'));
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/tests/Formatter/PlainFormatterTest.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Webmozart\Console\Tests\Formatter;
13 |
14 | use PHPUnit_Framework_TestCase;
15 | use Webmozart\Console\Api\Formatter\Style;
16 | use Webmozart\Console\Api\Formatter\StyleSet;
17 | use Webmozart\Console\Formatter\PlainFormatter;
18 |
19 | /**
20 | * @since 1.0
21 | *
22 | * @author Bernhard Schussek
23 | */
24 | class PlainFormatterTest extends PHPUnit_Framework_TestCase
25 | {
26 | public function testFormat()
27 | {
28 | $formatter = new PlainFormatter(new StyleSet(array(
29 | Style::tag('bold')->bold(),
30 | )));
31 |
32 | $this->assertSame('text', $formatter->removeFormat('text'));
33 | }
34 |
35 | public function testRemoveFormat()
36 | {
37 | $formatter = new PlainFormatter(new StyleSet(array(
38 | Style::tag('bold')->bold(),
39 | )));
40 |
41 | $this->assertSame('text', $formatter->removeFormat('text'));
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/tests/Handler/CallbackHandlerTest.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Webmozart\Console\Tests\Handler;
13 |
14 | use PHPUnit_Framework_Assert;
15 | use PHPUnit_Framework_TestCase;
16 | use Webmozart\Console\Api\Args\Args;
17 | use Webmozart\Console\Api\Args\Format\ArgsFormat;
18 | use Webmozart\Console\Api\Command\Command;
19 | use Webmozart\Console\Api\Config\CommandConfig;
20 | use Webmozart\Console\Api\IO\IO;
21 | use Webmozart\Console\Handler\CallbackHandler;
22 | use Webmozart\Console\IO\BufferedIO;
23 |
24 | /**
25 | * @since 1.0
26 | *
27 | * @author Bernhard Schussek
28 | */
29 | class CallbackHandlerTest extends PHPUnit_Framework_TestCase
30 | {
31 | public function testHandleCommand()
32 | {
33 | $args = new Args(new ArgsFormat());
34 | $io = new BufferedIO("line1\nline2");
35 | $command = new Command(new CommandConfig('command'));
36 |
37 | $handler = new CallbackHandler(
38 | function (Args $passedArgs, IO $io, Command $passedCommand) use ($args, $command) {
39 | PHPUnit_Framework_Assert::assertSame($args, $passedArgs);
40 | PHPUnit_Framework_Assert::assertSame($command, $passedCommand);
41 |
42 | $io->write($io->readLine());
43 | $io->error($io->readLine());
44 |
45 | return 123;
46 | }
47 | );
48 |
49 | $this->assertSame(123, $handler->handle($args, $io, $command));
50 | $this->assertSame("line1\n", $io->fetchOutput());
51 | $this->assertSame('line2', $io->fetchErrors());
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/tests/Handler/Help/Fixtures/ascii-doc/custom-app.txt:
--------------------------------------------------------------------------------
1 | Contents of custom-app.txt
2 |
--------------------------------------------------------------------------------
/tests/Handler/Help/Fixtures/ascii-doc/man-not-found.txt:
--------------------------------------------------------------------------------
1 | Contents of man-not-found.txt
2 |
--------------------------------------------------------------------------------
/tests/Handler/Help/Fixtures/ascii-doc/prefix-the-command.txt:
--------------------------------------------------------------------------------
1 | Contents of prefix-the-command.txt
2 |
--------------------------------------------------------------------------------
/tests/Handler/Help/Fixtures/ascii-doc/the-app.txt:
--------------------------------------------------------------------------------
1 | Contents of the-app.txt
2 |
--------------------------------------------------------------------------------
/tests/Handler/Help/Fixtures/ascii-doc/the-command.txt:
--------------------------------------------------------------------------------
1 | Contents of the-command.txt
2 |
--------------------------------------------------------------------------------
/tests/Handler/Help/Fixtures/man/custom-app.1:
--------------------------------------------------------------------------------
1 | Contents of custom-app.1
2 |
--------------------------------------------------------------------------------
/tests/Handler/Help/Fixtures/man/prefix-the-command.1:
--------------------------------------------------------------------------------
1 | Contents of prefix-the-command.1
2 |
--------------------------------------------------------------------------------
/tests/Handler/Help/Fixtures/man/the-app.1:
--------------------------------------------------------------------------------
1 | Contents of the-app.1
2 |
--------------------------------------------------------------------------------
/tests/Handler/Help/Fixtures/man/the-command.1:
--------------------------------------------------------------------------------
1 | Contents of the-command.1
2 |
--------------------------------------------------------------------------------
/tests/Handler/Help/HelpJsonHandlerTest.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Webmozart\Console\Tests\Handler\Help;
13 |
14 | use PHPUnit_Framework_TestCase;
15 | use Webmozart\Console\Api\Application\Application;
16 | use Webmozart\Console\Api\Args\Args;
17 | use Webmozart\Console\Api\Command\Command;
18 | use Webmozart\Console\Config\DefaultApplicationConfig;
19 | use Webmozart\Console\ConsoleApplication;
20 | use Webmozart\Console\Handler\Help\HelpJsonHandler;
21 | use Webmozart\Console\IO\BufferedIO;
22 |
23 | /**
24 | * @since 1.0
25 | *
26 | * @author Bernhard Schussek
27 | */
28 | class HelpJsonHandlerTest extends PHPUnit_Framework_TestCase
29 | {
30 | /**
31 | * @var Application
32 | */
33 | private $application;
34 |
35 | /**
36 | * @var Command
37 | */
38 | private $command;
39 |
40 | /**
41 | * @var Command
42 | */
43 | private $helpCommand;
44 |
45 | /**
46 | * @var BufferedIO
47 | */
48 | private $io;
49 |
50 | /**
51 | * @var HelpJsonHandler
52 | */
53 | private $handler;
54 |
55 | protected function setUp()
56 | {
57 | $config = DefaultApplicationConfig::create()
58 | ->beginCommand('the-command')->end()
59 | ;
60 |
61 | $this->application = new ConsoleApplication($config);
62 | $this->command = $this->application->getCommand('the-command');
63 | $this->helpCommand = $this->application->getCommand('help');
64 | $this->io = new BufferedIO();
65 | $this->handler = new HelpJsonHandler();
66 | }
67 |
68 | public function testRenderCommandJson()
69 | {
70 | $args = new Args($this->helpCommand->getArgsFormat());
71 | $args->setArgument('command', 'the-command');
72 |
73 | $status = $this->handler->handle($args, $this->io, $this->command);
74 |
75 | $this->assertStringStartsWith('{"name":"the-command",', $this->io->fetchOutput());
76 | $this->assertSame(0, $status);
77 | }
78 |
79 | public function testRenderApplicationJson()
80 | {
81 | $args = new Args($this->helpCommand->getArgsFormat());
82 |
83 | $status = $this->handler->handle($args, $this->io, $this->command);
84 |
85 | $this->assertStringStartsWith('{"commands":[{"name":"help",', $this->io->fetchOutput());
86 | $this->assertSame(0, $status);
87 | }
88 | }
89 |
--------------------------------------------------------------------------------
/tests/Handler/Help/HelpTextHandlerTest.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Webmozart\Console\Tests\Handler\Help;
13 |
14 | use PHPUnit_Framework_TestCase;
15 | use Webmozart\Console\Api\Application\Application;
16 | use Webmozart\Console\Api\Args\Args;
17 | use Webmozart\Console\Api\Command\Command;
18 | use Webmozart\Console\Config\DefaultApplicationConfig;
19 | use Webmozart\Console\ConsoleApplication;
20 | use Webmozart\Console\Handler\Help\HelpTextHandler;
21 | use Webmozart\Console\IO\BufferedIO;
22 |
23 | /**
24 | * @since 1.0
25 | *
26 | * @author Bernhard Schussek
27 | */
28 | class HelpTextHandlerTest extends PHPUnit_Framework_TestCase
29 | {
30 | /**
31 | * @var Application
32 | */
33 | private $application;
34 |
35 | /**
36 | * @var Command
37 | */
38 | private $command;
39 |
40 | /**
41 | * @var Command
42 | */
43 | private $helpCommand;
44 |
45 | /**
46 | * @var BufferedIO
47 | */
48 | private $io;
49 |
50 | /**
51 | * @var HelpTextHandler
52 | */
53 | private $handler;
54 |
55 | protected function setUp()
56 | {
57 | $config = DefaultApplicationConfig::create()
58 | ->setDisplayName('The Application')
59 | ->setVersion('1.2.3')
60 | ->beginCommand('the-command')->end()
61 | ;
62 |
63 | $this->application = new ConsoleApplication($config);
64 | $this->command = $this->application->getCommand('the-command');
65 | $this->helpCommand = $this->application->getCommand('help');
66 | $this->io = new BufferedIO();
67 | $this->handler = new HelpTextHandler();
68 | }
69 |
70 | public function testRenderCommandText()
71 | {
72 | $args = new Args($this->helpCommand->getArgsFormat());
73 | $args->setArgument('command', 'the-command');
74 |
75 | $status = $this->handler->handle($args, $this->io, $this->command);
76 |
77 | $expected = <<<'EOF'
78 | USAGE
79 | console the-command
80 |
81 | GLOBAL OPTIONS
82 | EOF;
83 |
84 | $this->assertStringStartsWith($expected, $this->io->fetchOutput());
85 | $this->assertSame(0, $status);
86 | }
87 |
88 | public function testRenderApplicationText()
89 | {
90 | $args = new Args($this->helpCommand->getArgsFormat());
91 |
92 | $status = $this->handler->handle($args, $this->io, $this->command);
93 |
94 | $expected = <<<'EOF'
95 | The Application version 1.2.3
96 |
97 | USAGE
98 | console
99 | EOF;
100 |
101 | $this->assertStringStartsWith($expected, $this->io->fetchOutput());
102 | $this->assertSame(0, $status);
103 | }
104 | }
105 |
--------------------------------------------------------------------------------
/tests/Handler/Help/HelpXmlHandlerTest.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Webmozart\Console\Tests\Handler\Help;
13 |
14 | use PHPUnit_Framework_TestCase;
15 | use Webmozart\Console\Api\Application\Application;
16 | use Webmozart\Console\Api\Args\Args;
17 | use Webmozart\Console\Api\Command\Command;
18 | use Webmozart\Console\Config\DefaultApplicationConfig;
19 | use Webmozart\Console\ConsoleApplication;
20 | use Webmozart\Console\Handler\Help\HelpXmlHandler;
21 | use Webmozart\Console\IO\BufferedIO;
22 |
23 | /**
24 | * @since 1.0
25 | *
26 | * @author Bernhard Schussek
27 | */
28 | class HelpXmlHandlerTest extends PHPUnit_Framework_TestCase
29 | {
30 | /**
31 | * @var Application
32 | */
33 | private $application;
34 |
35 | /**
36 | * @var Command
37 | */
38 | private $command;
39 |
40 | /**
41 | * @var Command
42 | */
43 | private $helpCommand;
44 |
45 | /**
46 | * @var BufferedIO
47 | */
48 | private $io;
49 |
50 | /**
51 | * @var HelpXmlHandler
52 | */
53 | private $handler;
54 |
55 | protected function setUp()
56 | {
57 | $config = DefaultApplicationConfig::create()
58 | ->setDisplayName('The Application')
59 | ->setVersion('1.2.3')
60 | ->beginCommand('the-command')->end()
61 | ;
62 |
63 | $this->application = new ConsoleApplication($config);
64 | $this->command = $this->application->getCommand('the-command');
65 | $this->helpCommand = $this->application->getCommand('help');
66 | $this->io = new BufferedIO();
67 | $this->handler = new HelpXmlHandler();
68 | }
69 |
70 | public function testRenderCommandXml()
71 | {
72 | $args = new Args($this->helpCommand->getArgsFormat());
73 | $args->setArgument('command', 'the-command');
74 |
75 | $status = $this->handler->handle($args, $this->io, $this->command);
76 |
77 | $expected = <<<'EOF'
78 |
79 |
80 | EOF;
81 |
82 | $this->assertStringStartsWith($expected, $this->io->fetchOutput());
83 | $this->assertSame(0, $status);
84 | }
85 |
86 | public function testRenderApplicationXml()
87 | {
88 | $args = new Args($this->helpCommand->getArgsFormat());
89 |
90 | $status = $this->handler->handle($args, $this->io, $this->command);
91 |
92 | $expected = <<<'EOF'
93 |
94 |
95 | EOF;
96 |
97 | $this->assertStringStartsWith($expected, $this->io->fetchOutput());
98 | $this->assertSame(0, $status);
99 | }
100 | }
101 |
--------------------------------------------------------------------------------
/tests/IO/BufferedIOTest.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Webmozart\Console\Tests\IO;
13 |
14 | use PHPUnit_Framework_TestCase;
15 | use Webmozart\Console\IO\BufferedIO;
16 |
17 | /**
18 | * @since 1.0
19 | *
20 | * @author Bernhard Schussek
21 | */
22 | class BufferedIOTest extends PHPUnit_Framework_TestCase
23 | {
24 | public function testCreate()
25 | {
26 | $io = new BufferedIO('Lorem ipsum');
27 |
28 | $this->assertSame('Lorem ipsum', $io->readLine());
29 | }
30 |
31 | public function testSetInput()
32 | {
33 | $io = new BufferedIO();
34 | $io->setInput('Lorem ipsum');
35 |
36 | $this->assertSame('Lorem ipsum', $io->readLine());
37 | }
38 |
39 | public function testAppendInput()
40 | {
41 | $io = new BufferedIO();
42 | $io->setInput('Lorem ipsum');
43 |
44 | $this->assertSame('Lorem', $io->read(5));
45 |
46 | $io->appendInput(' dolor');
47 |
48 | $this->assertSame(' ipsum dolor', $io->readLine());
49 | }
50 |
51 | public function testClearInput()
52 | {
53 | $io = new BufferedIO();
54 | $io->setInput('Lorem ipsum');
55 |
56 | $this->assertSame('Lorem', $io->read(5));
57 |
58 | $io->clearInput();
59 |
60 | $this->assertNull($io->readLine());
61 | }
62 |
63 | public function testFetchOutput()
64 | {
65 | $io = new BufferedIO();
66 | $io->write('Lorem ipsum');
67 |
68 | $this->assertSame('Lorem ipsum', $io->fetchOutput());
69 | }
70 |
71 | public function testClearOutput()
72 | {
73 | $io = new BufferedIO();
74 | $io->write('Lorem');
75 | $io->clearOutput();
76 | $io->write('ipsum');
77 |
78 | $this->assertSame('ipsum', $io->fetchOutput());
79 | }
80 |
81 | public function testFetchErrors()
82 | {
83 | $io = new BufferedIO();
84 | $io->error('Lorem ipsum');
85 |
86 | $this->assertSame('Lorem ipsum', $io->fetchErrors());
87 | }
88 |
89 | public function testClearErrors()
90 | {
91 | $io = new BufferedIO();
92 | $io->error('Lorem');
93 | $io->clearErrors();
94 | $io->error('ipsum');
95 |
96 | $this->assertSame('ipsum', $io->fetchErrors());
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/tests/IO/InputStream/StandardInputStreamTest.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Webmozart\Console\Tests\IO\InputStream;
13 |
14 | use PHPUnit_Framework_TestCase;
15 | use Webmozart\Console\IO\InputStream\StandardInputStream;
16 |
17 | /**
18 | * @since 1.0
19 | *
20 | * @author Bernhard Schussek
21 | */
22 | class StandardInputStreamTest extends PHPUnit_Framework_TestCase
23 | {
24 | public function testCreate()
25 | {
26 | $input = new StandardInputStream();
27 |
28 | $this->assertInstanceOf('Webmozart\Console\IO\InputStream\StandardInputStream', $input);
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/tests/IO/InputStream/StreamInputStreamTest.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Webmozart\Console\Tests\IO\InputStream;
13 |
14 | use PHPUnit_Framework_TestCase;
15 | use Webmozart\Console\IO\InputStream\StreamInputStream;
16 |
17 | /**
18 | * @since 1.0
19 | *
20 | * @author Bernhard Schussek
21 | */
22 | class StreamInputStreamTest extends PHPUnit_Framework_TestCase
23 | {
24 | const LOREM_IPSUM = "Lorem ipsum dolor sit amet,\nconsetetur sadipscing elitr,\nsed diam nonumy eirmod tempor invidunt";
25 |
26 | private $handle;
27 |
28 | protected function setUp()
29 | {
30 | $this->handle = fopen('php://memory', 'rw');
31 |
32 | fwrite($this->handle, self::LOREM_IPSUM);
33 | rewind($this->handle);
34 | }
35 |
36 | protected function tearDown()
37 | {
38 | @fclose($this->handle);
39 | }
40 |
41 | public function testRead()
42 | {
43 | $stream = new StreamInputStream($this->handle);
44 |
45 | $this->assertSame('L', $stream->read(1));
46 | $this->assertSame('o', $stream->read(1));
47 | $this->assertSame('rem ipsum dolor sit ', $stream->read(20));
48 | $this->assertSame("amet,\nconsetetur sadipscing elitr,\nsed diam nonumy eirmod tempor invidunt", $stream->read(100));
49 | $this->assertNull($stream->read(1));
50 | }
51 |
52 | /**
53 | * @expectedException \Webmozart\Console\Api\IO\IOException
54 | */
55 | public function testReadFailsAfterClose()
56 | {
57 | $stream = new StreamInputStream($this->handle);
58 | $stream->close();
59 |
60 | $stream->read(1);
61 | }
62 |
63 | public function testReadLine()
64 | {
65 | $stream = new StreamInputStream($this->handle);
66 |
67 | $this->assertSame("Lorem ipsum dolor sit amet,\n", $stream->readLine());
68 | $this->assertSame('consetetu', $stream->readLine(10));
69 | $this->assertSame("r sadipscing elitr,\n", $stream->readLine(100));
70 | $this->assertSame('sed diam nonumy eirmod tempor invidunt', $stream->readLine());
71 | $this->assertNull($stream->readLine());
72 | }
73 |
74 | /**
75 | * @expectedException \Webmozart\Console\Api\IO\IOException
76 | */
77 | public function testReadLineFailsAfterClose()
78 | {
79 | $stream = new StreamInputStream($this->handle);
80 | $stream->close();
81 |
82 | $stream->readLine();
83 | }
84 |
85 | public function testIgnoreDuplicateClose()
86 | {
87 | $stream = new StreamInputStream($this->handle);
88 | $stream->close();
89 | $stream->close();
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/tests/IO/InputStream/StringInputStreamTest.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Webmozart\Console\Tests\IO\InputStream;
13 |
14 | use PHPUnit_Framework_TestCase;
15 | use Webmozart\Console\IO\InputStream\StringInputStream;
16 |
17 | /**
18 | * @since 1.0
19 | *
20 | * @author Bernhard Schussek
21 | */
22 | class StringInputStreamTest extends PHPUnit_Framework_TestCase
23 | {
24 | const LOREM_IPSUM = "Lorem ipsum dolor sit amet,\nconsetetur sadipscing elitr,\nsed diam nonumy eirmod tempor invidunt";
25 |
26 | public function testRead()
27 | {
28 | $stream = new StringInputStream(self::LOREM_IPSUM);
29 |
30 | $this->assertSame('L', $stream->read(1));
31 | $this->assertSame('o', $stream->read(1));
32 | $this->assertSame('rem ipsum dolor sit ', $stream->read(20));
33 | $this->assertSame("amet,\nconsetetur sadipscing elitr,\nsed diam nonumy eirmod tempor invidunt", $stream->read(100));
34 | $this->assertNull($stream->read(1));
35 | }
36 |
37 | public function testReadEmpty()
38 | {
39 | $stream = new StringInputStream();
40 |
41 | $this->assertNull($stream->read(1));
42 | }
43 |
44 | public function testReadLine()
45 | {
46 | $stream = new StringInputStream(self::LOREM_IPSUM);
47 |
48 | $this->assertSame("Lorem ipsum dolor sit amet,\n", $stream->readLine());
49 | $this->assertSame('consetetu', $stream->readLine(10));
50 | $this->assertSame("r sadipscing elitr,\n", $stream->readLine(100));
51 | $this->assertSame('sed diam nonumy eirmod tempor invidunt', $stream->readLine());
52 | $this->assertNull($stream->readLine());
53 | }
54 |
55 | public function testReadLineEmpty()
56 | {
57 | $stream = new StringInputStream();
58 |
59 | $this->assertNull($stream->readLine());
60 | }
61 |
62 | public function testClear()
63 | {
64 | $stream = new StringInputStream(self::LOREM_IPSUM);
65 |
66 | $this->assertSame("Lorem ipsum dolor sit amet,\n", $stream->readLine());
67 |
68 | $stream->clear();
69 |
70 | $this->assertNull($stream->readLine());
71 | }
72 |
73 | public function testAppend()
74 | {
75 | $stream = new StringInputStream("Lorem\nIpsum\n");
76 |
77 | $this->assertSame("Lorem\n", $stream->readLine());
78 |
79 | $stream->append("Dolor\n");
80 |
81 | $this->assertSame("Ipsum\n", $stream->readLine());
82 | $this->assertSame("Dolor\n", $stream->readLine());
83 | $this->assertNull($stream->readLine());
84 | }
85 |
86 | public function testSet()
87 | {
88 | $stream = new StringInputStream(self::LOREM_IPSUM);
89 |
90 | $this->assertSame("Lorem ipsum dolor sit amet,\n", $stream->readLine());
91 |
92 | $stream->set('Foobar');
93 |
94 | $this->assertSame('Foobar', $stream->readLine());
95 | $this->assertNull($stream->readLine());
96 | }
97 | }
98 |
--------------------------------------------------------------------------------
/tests/IO/OutputStream/BufferedOutputStreamTest.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Webmozart\Console\Tests\IO\OutputStream;
13 |
14 | use PHPUnit_Framework_TestCase;
15 | use Webmozart\Console\IO\OutputStream\BufferedOutputStream;
16 |
17 | /**
18 | * @since 1.0
19 | *
20 | * @author Bernhard Schussek
21 | */
22 | class BufferedOutputStreamTest extends PHPUnit_Framework_TestCase
23 | {
24 | public function testWrite()
25 | {
26 | $stream = new BufferedOutputStream();
27 | $stream->write('Lorem ipsum');
28 |
29 | $this->assertSame('Lorem ipsum', $stream->fetch());
30 | }
31 |
32 | /**
33 | * @expectedException \Webmozart\Console\Api\IO\IOException
34 | */
35 | public function testWriteFailsAfterClose()
36 | {
37 | $stream = new BufferedOutputStream();
38 | $stream->close();
39 | $stream->write('Lorem ipsum');
40 | }
41 |
42 | public function testFetchAfterClose()
43 | {
44 | $stream = new BufferedOutputStream();
45 | $stream->write('Lorem ipsum');
46 | $stream->close();
47 |
48 | $this->assertSame('Lorem ipsum', $stream->fetch());
49 | }
50 |
51 | /**
52 | * @expectedException \Webmozart\Console\Api\IO\IOException
53 | */
54 | public function testFlushFailsAfterClose()
55 | {
56 | $stream = new BufferedOutputStream();
57 | $stream->close();
58 | $stream->flush();
59 | }
60 |
61 | public function testIgnoreDuplicateClose()
62 | {
63 | $stream = new BufferedOutputStream();
64 | $stream->close();
65 | $stream->close();
66 | }
67 |
68 | public function testClear()
69 | {
70 | $stream = new BufferedOutputStream();
71 | $stream->write('Lorem');
72 | $stream->clear();
73 | $stream->write('ipsum');
74 | $stream->close();
75 |
76 | $this->assertSame('ipsum', $stream->fetch());
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/tests/IO/OutputStream/ErrorOutputStreamTest.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Webmozart\Console\Tests\IO\OutputStream;
13 |
14 | use PHPUnit_Framework_TestCase;
15 | use Webmozart\Console\IO\OutputStream\ErrorOutputStream;
16 |
17 | /**
18 | * @since 1.0
19 | *
20 | * @author Bernhard Schussek
21 | */
22 | class ErrorOutputStreamTest extends PHPUnit_Framework_TestCase
23 | {
24 | public function testCreate()
25 | {
26 | $stream = new ErrorOutputStream();
27 |
28 | $this->assertInstanceOf('Webmozart\Console\IO\OutputStream\ErrorOutputStream', $stream);
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/tests/IO/OutputStream/StandardOutputStreamTest.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Webmozart\Console\Tests\IO\OutputStream;
13 |
14 | use PHPUnit_Framework_TestCase;
15 | use Webmozart\Console\IO\OutputStream\StandardOutputStream;
16 |
17 | /**
18 | * @since 1.0
19 | *
20 | * @author Bernhard Schussek
21 | */
22 | class StandardOutputStreamTest extends PHPUnit_Framework_TestCase
23 | {
24 | public function testCreate()
25 | {
26 | $stream = new StandardOutputStream();
27 |
28 | $this->assertInstanceOf('Webmozart\Console\IO\OutputStream\StandardOutputStream', $stream);
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/tests/IO/OutputStream/StreamOutputStreamTest.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Webmozart\Console\Tests\IO\OutputStream;
13 |
14 | use PHPUnit_Framework_TestCase;
15 | use Webmozart\Console\IO\OutputStream\StreamOutputStream;
16 |
17 | /**
18 | * @since 1.0
19 | *
20 | * @author Bernhard Schussek
21 | */
22 | class StreamOutputStreamTest extends PHPUnit_Framework_TestCase
23 | {
24 | private $handle;
25 |
26 | protected function setUp()
27 | {
28 | $this->handle = fopen('php://memory', 'rw');
29 | }
30 |
31 | protected function tearDown()
32 | {
33 | @fclose($this->handle);
34 | }
35 |
36 | public function testWrite()
37 | {
38 | $stream = new StreamOutputStream($this->handle);
39 | $stream->write('Lorem ipsum');
40 |
41 | rewind($this->handle);
42 |
43 | $this->assertSame('Lorem ipsum', fread($this->handle, 20));
44 | }
45 |
46 | /**
47 | * @expectedException \Webmozart\Console\Api\IO\IOException
48 | */
49 | public function testWriteFailsAfterClose()
50 | {
51 | $stream = new StreamOutputStream($this->handle);
52 | $stream->close();
53 | $stream->write('Lorem ipsum');
54 | }
55 |
56 | /**
57 | * @expectedException \Webmozart\Console\Api\IO\IOException
58 | */
59 | public function testFlushFailsAfterClose()
60 | {
61 | $stream = new StreamOutputStream($this->handle);
62 | $stream->close();
63 | $stream->flush();
64 | }
65 |
66 | public function testIgnoreDuplicateClose()
67 | {
68 | $stream = new StreamOutputStream($this->handle);
69 | $stream->close();
70 | $stream->close();
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/tests/Process/ProcessLauncherTest.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Webmozart\Console\Tests\Process;
13 |
14 | use PHPUnit_Framework_TestCase;
15 | use Symfony\Component\Process\PhpExecutableFinder;
16 | use Webmozart\Console\Process\ProcessLauncher;
17 |
18 | /**
19 | * @since 1.0
20 | *
21 | * @author Bernhard Schussek
22 | */
23 | class ProcessLauncherTest extends PHPUnit_Framework_TestCase
24 | {
25 | /**
26 | * @var ProcessLauncher
27 | */
28 | private $launcher;
29 |
30 | /**
31 | * @var string
32 | */
33 | private $php;
34 |
35 | protected function setUp()
36 | {
37 | $finder = new PhpExecutableFinder();
38 | $this->php = escapeshellcmd($finder->find());
39 | $this->launcher = new ProcessLauncher();
40 |
41 | // Speed up the tests
42 | $this->launcher->setCheckInterval(0.01);
43 | }
44 |
45 | public function testLaunchSuccessfully()
46 | {
47 | if (!$this->php) {
48 | $this->markTestSkipped('The "bash" binary is not available.');
49 |
50 | return;
51 | }
52 |
53 | if (!function_exists('proc_open')) {
54 | $this->markTestSkipped('The "proc_open" function is not available.');
55 |
56 | return;
57 | }
58 |
59 | $status = $this->launcher->launchProcess($this->php.' -r %command%', array(
60 | 'command' => 'exit(0);',
61 | ));
62 |
63 | $this->assertSame(0, $status);
64 | }
65 |
66 | public function testLaunchWithError()
67 | {
68 | if (!$this->php) {
69 | $this->markTestSkipped('The "bash" binary is not available.');
70 |
71 | return;
72 | }
73 |
74 | if (!function_exists('proc_open')) {
75 | $this->markTestSkipped('The "proc_open" function is not available.');
76 |
77 | return;
78 | }
79 |
80 | $status = $this->launcher->launchProcess($this->php.' -r %command%', array(
81 | 'command' => 'exit(123);',
82 | ));
83 |
84 | $this->assertSame(123, $status);
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/tests/UI/Component/EmptyLineTest.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Webmozart\Console\Tests\UI\Component;
13 |
14 | use PHPUnit_Framework_TestCase;
15 | use Webmozart\Console\IO\BufferedIO;
16 | use Webmozart\Console\UI\Component\EmptyLine;
17 |
18 | /**
19 | * @since 1.0
20 | *
21 | * @author Bernhard Schussek
22 | */
23 | class EmptyLineTest extends PHPUnit_Framework_TestCase
24 | {
25 | /**
26 | * @var BufferedIO
27 | */
28 | private $io;
29 |
30 | protected function setUp()
31 | {
32 | $this->io = new BufferedIO();
33 | }
34 |
35 | public function testRender()
36 | {
37 | $line = new EmptyLine();
38 | $line->render($this->io);
39 |
40 | $this->assertSame("\n", $this->io->fetchOutput());
41 | }
42 |
43 | public function testRenderIgnoresIndentation()
44 | {
45 | $line = new EmptyLine();
46 | $line->render($this->io, 10);
47 |
48 | $this->assertSame("\n", $this->io->fetchOutput());
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/tests/UI/Component/LabeledParagraphTest.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Webmozart\Console\Tests\UI\Component;
13 |
14 | use PHPUnit_Framework_TestCase;
15 | use Webmozart\Console\IO\BufferedIO;
16 | use Webmozart\Console\UI\Alignment\LabelAlignment;
17 | use Webmozart\Console\UI\Component\LabeledParagraph;
18 |
19 | /**
20 | * @since 1.0
21 | *
22 | * @author Bernhard Schussek
23 | */
24 | class LabeledParagraphTest extends PHPUnit_Framework_TestCase
25 | {
26 | const LOREM_IPSUM = 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt';
27 |
28 | /**
29 | * @var BufferedIO
30 | */
31 | private $io;
32 |
33 | protected function setUp()
34 | {
35 | $this->io = new BufferedIO();
36 | }
37 |
38 | public function testRender()
39 | {
40 | $para = new LabeledParagraph('Label', 'Text');
41 | $para->render($this->io);
42 |
43 | $this->assertSame("Label Text\n", $this->io->fetchOutput());
44 | }
45 |
46 | public function testRenderWithTrailingNewline()
47 | {
48 | $para = new LabeledParagraph('Label', "Text\n");
49 | $para->render($this->io);
50 |
51 | $this->assertSame("Label Text\n", $this->io->fetchOutput());
52 | }
53 |
54 | public function testRenderWithIndentation()
55 | {
56 | $para = new LabeledParagraph('Label', 'Text');
57 | $para->render($this->io, 4);
58 |
59 | $this->assertSame(" Label Text\n", $this->io->fetchOutput());
60 | }
61 |
62 | public function testRenderWithLabelDistance()
63 | {
64 | $para = new LabeledParagraph('Label', 'Text', 1);
65 | $para->render($this->io);
66 |
67 | $this->assertSame("Label Text\n", $this->io->fetchOutput());
68 | }
69 |
70 | public function testRenderWithoutText()
71 | {
72 | $para = new LabeledParagraph('Label', '');
73 | $para->render($this->io);
74 |
75 | $this->assertSame("Label\n", $this->io->fetchOutput());
76 | }
77 |
78 | public function testRenderWithAlignment()
79 | {
80 | $alignment = new LabelAlignment();
81 | $alignment->setTextOffset(10);
82 |
83 | $para = new LabeledParagraph('Label', 'Text');
84 | $para->setAlignment($alignment);
85 | $para->render($this->io);
86 |
87 | $this->assertSame("Label Text\n", $this->io->fetchOutput());
88 | }
89 |
90 | public function testRenderWithAlignmentIgnoresIfTextOffsetToSmall()
91 | {
92 | $alignment = new LabelAlignment();
93 | $alignment->setTextOffset(5);
94 |
95 | $para = new LabeledParagraph('Label', 'Text');
96 | $para->setAlignment($alignment);
97 | $para->render($this->io);
98 |
99 | $this->assertSame("Label Text\n", $this->io->fetchOutput());
100 | }
101 |
102 | public function testRenderWrapsText()
103 | {
104 | $para = new LabeledParagraph('Label', self::LOREM_IPSUM);
105 | $para->render($this->io);
106 |
107 | $expected = <<<'EOF'
108 | Label Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy
109 | eirmod tempor invidunt
110 |
111 | EOF;
112 |
113 | $this->assertSame($expected, $this->io->fetchOutput());
114 | }
115 |
116 | public function testRenderWithIndentationWrapsText()
117 | {
118 | $para = new LabeledParagraph('Label', self::LOREM_IPSUM);
119 | $para->render($this->io, 4);
120 |
121 | $expected = <<<'EOF'
122 | Label Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam
123 | nonumy eirmod tempor invidunt
124 |
125 | EOF;
126 |
127 | $this->assertSame($expected, $this->io->fetchOutput());
128 | }
129 |
130 | public function testRenderWithLabelDistanceWrapsText()
131 | {
132 | $para = new LabeledParagraph('Label', self::LOREM_IPSUM, 6);
133 | $para->render($this->io);
134 |
135 | $expected = <<<'EOF'
136 | Label Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam
137 | nonumy eirmod tempor invidunt
138 |
139 | EOF;
140 |
141 | $this->assertSame($expected, $this->io->fetchOutput());
142 | }
143 | }
144 |
--------------------------------------------------------------------------------
/tests/UI/Component/ParagraphTest.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Webmozart\Console\Tests\UI\Component;
13 |
14 | use PHPUnit_Framework_TestCase;
15 | use Webmozart\Console\IO\BufferedIO;
16 | use Webmozart\Console\UI\Component\Paragraph;
17 |
18 | /**
19 | * @since 1.0
20 | *
21 | * @author Bernhard Schussek
22 | */
23 | class ParagraphTest extends PHPUnit_Framework_TestCase
24 | {
25 | const LOREM_IPSUM = 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt';
26 |
27 | /**
28 | * @var BufferedIO
29 | */
30 | private $io;
31 |
32 | protected function setUp()
33 | {
34 | $this->io = new BufferedIO();
35 | }
36 |
37 | public function testRender()
38 | {
39 | $para = new Paragraph(self::LOREM_IPSUM);
40 | $para->render($this->io);
41 |
42 | $expected = <<<'EOF'
43 | Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod
44 | tempor invidunt
45 |
46 | EOF;
47 |
48 | $this->assertSame($expected, $this->io->fetchOutput());
49 | }
50 |
51 | public function testRenderWithIndentation()
52 | {
53 | $para = new Paragraph(self::LOREM_IPSUM);
54 | $para->render($this->io, 6);
55 |
56 | $expected = <<<'EOF'
57 | Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy
58 | eirmod tempor invidunt
59 |
60 | EOF;
61 |
62 | $this->assertSame($expected, $this->io->fetchOutput());
63 | }
64 |
65 | public function testSkipIndentationForEmptyLines()
66 | {
67 | $para = new Paragraph(self::LOREM_IPSUM."\n\n".self::LOREM_IPSUM);
68 | $para->render($this->io, 6);
69 |
70 | $expected = <<<'EOF'
71 | Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy
72 | eirmod tempor invidunt
73 |
74 | Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy
75 | eirmod tempor invidunt
76 |
77 | EOF;
78 |
79 | $this->assertSame($expected, $this->io->fetchOutput());
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/tests/UI/Layout/BlockLayoutTest.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Webmozart\Console\Tests\UI\Layout;
13 |
14 | use PHPUnit_Framework_TestCase;
15 | use Webmozart\Console\IO\BufferedIO;
16 | use Webmozart\Console\UI\Component\EmptyLine;
17 | use Webmozart\Console\UI\Component\LabeledParagraph;
18 | use Webmozart\Console\UI\Component\Paragraph;
19 | use Webmozart\Console\UI\Layout\BlockLayout;
20 |
21 | /**
22 | * @since 1.0
23 | *
24 | * @author Bernhard Schussek
25 | */
26 | class BlockLayoutTest extends PHPUnit_Framework_TestCase
27 | {
28 | const LOREM_IPSUM = 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt';
29 |
30 | /**
31 | * @var BufferedIO
32 | */
33 | private $io;
34 |
35 | protected function setUp()
36 | {
37 | $this->io = new BufferedIO();
38 | }
39 |
40 | public function testRender()
41 | {
42 | $layout = new BlockLayout();
43 |
44 | $layout
45 | ->add(new Paragraph('HEADING 1'))
46 | ->add(new Paragraph(self::LOREM_IPSUM))
47 | ->add(new EmptyLine())
48 | ->add(new LabeledParagraph('Not Aligned', self::LOREM_IPSUM, 1, false))
49 | ->add(new EmptyLine())
50 | ->add(new Paragraph('HEADING 2'))
51 | ->beginBlock()
52 | ->add(new LabeledParagraph('Label 1', self::LOREM_IPSUM))
53 | ->add(new LabeledParagraph('Label 2', self::LOREM_IPSUM))
54 | ->endBlock()
55 | ->add(new Paragraph('HEADING 3'))
56 | ->beginBlock()
57 | ->add(new LabeledParagraph('Longer Label', self::LOREM_IPSUM))
58 | ->endBlock()
59 | ;
60 |
61 | $layout->render($this->io);
62 |
63 | $expected = <<<'EOF'
64 | HEADING 1
65 | Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod
66 | tempor invidunt
67 |
68 | Not Aligned Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam
69 | nonumy eirmod tempor invidunt
70 |
71 | HEADING 2
72 | Label 1 Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed
73 | diam nonumy eirmod tempor invidunt
74 | Label 2 Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed
75 | diam nonumy eirmod tempor invidunt
76 | HEADING 3
77 | Longer Label Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed
78 | diam nonumy eirmod tempor invidunt
79 |
80 | EOF;
81 |
82 | $this->assertSame($expected, $this->io->fetchOutput());
83 | }
84 |
85 | public function testRenderWithIndentation()
86 | {
87 | $layout = new BlockLayout();
88 |
89 | $layout
90 | ->add(new Paragraph('HEADING 1'))
91 | ->add(new Paragraph(self::LOREM_IPSUM))
92 | ->add(new EmptyLine())
93 | ->add(new LabeledParagraph('Not Aligned', self::LOREM_IPSUM, 1, false))
94 | ->add(new EmptyLine())
95 | ->add(new Paragraph('HEADING 2'))
96 | ->beginBlock()
97 | ->add(new LabeledParagraph('Label 1', self::LOREM_IPSUM))
98 | ->add(new LabeledParagraph('Label 2', self::LOREM_IPSUM))
99 | ->endBlock()
100 | ->add(new Paragraph('HEADING 3'))
101 | ->beginBlock()
102 | ->add(new LabeledParagraph('Longer Label', self::LOREM_IPSUM))
103 | ->endBlock()
104 | ;
105 |
106 | $layout->render($this->io, 4);
107 |
108 | $expected = <<<'EOF'
109 | HEADING 1
110 | Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy
111 | eirmod tempor invidunt
112 |
113 | Not Aligned Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed
114 | diam nonumy eirmod tempor invidunt
115 |
116 | HEADING 2
117 | Label 1 Lorem ipsum dolor sit amet, consetetur sadipscing elitr,
118 | sed diam nonumy eirmod tempor invidunt
119 | Label 2 Lorem ipsum dolor sit amet, consetetur sadipscing elitr,
120 | sed diam nonumy eirmod tempor invidunt
121 | HEADING 3
122 | Longer Label Lorem ipsum dolor sit amet, consetetur sadipscing elitr,
123 | sed diam nonumy eirmod tempor invidunt
124 |
125 | EOF;
126 |
127 | $this->assertSame($expected, $this->io->fetchOutput());
128 | }
129 | }
130 |
--------------------------------------------------------------------------------
/tests/Util/SimilarCommandNameTest.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Webmozart\Console\Tests\Util;
13 |
14 | use PHPUnit_Framework_TestCase;
15 | use Webmozart\Console\Api\Command\Command;
16 | use Webmozart\Console\Api\Command\CommandCollection;
17 | use Webmozart\Console\Api\Config\CommandConfig;
18 | use Webmozart\Console\Util\SimilarCommandName;
19 |
20 | /**
21 | * @since 1.0
22 | *
23 | * @author Bernhard Schussek
24 | */
25 | class SimilarCommandNameTest extends PHPUnit_Framework_TestCase
26 | {
27 | /**
28 | * @dataProvider getInputOutput
29 | */
30 | public function testFindSimilarNames($input, array $suggestions)
31 | {
32 | $commands = new CommandCollection(array(
33 | new Command(
34 | CommandConfig::create('package')->addAlias('package-alias')
35 | ),
36 | new Command(
37 | CommandConfig::create('pack')->addAlias('pack-alias')
38 | ),
39 | new Command(CommandConfig::create('pack')),
40 | ));
41 |
42 | $this->assertSame($suggestions, SimilarCommandName::find($input, $commands));
43 | }
44 |
45 | public function getInputOutput()
46 | {
47 | return array(
48 | array('pac', array('pack', 'package')),
49 | array('pack', array('pack', 'package')),
50 | array('pack-', array('pack')),
51 | array('pack-a', array('pack')),
52 | array('pack-al', array('pack-alias')),
53 | array('pack-ali', array('pack-alias')),
54 | array('pack-alia', array('pack-alias')),
55 | array('pack-alias', array('pack-alias', 'package-alias')),
56 | array('packa', array('pack', 'package')),
57 | array('packag', array('package', 'pack')),
58 | array('package', array('package')),
59 | array('package-', array('package')),
60 | array('package-a', array('package')),
61 | array('package-al', defined('HHVM_VERSION') || PHP_VERSION_ID >= 70000 ? array('package') : array('package-alias')),
62 | array('package-ali', array('package-alias')),
63 | array('package-alia', array('package-alias', 'pack-alias')),
64 | array('package-alias', array('package-alias', 'pack-alias')),
65 | );
66 | }
67 | }
68 |
--------------------------------------------------------------------------------