├── .editorconfig
├── CHANGELOG.md
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── RoboFile.php
├── codeception.yml
├── composer.json
├── composer.lock
├── data
└── Task
│ └── Development
│ └── GeneratedWrapper.tmpl
├── dependencies.yml
├── phpunit.xml.dist
├── robo
├── robo.yml
└── src
├── Application.php
├── ClassDiscovery
├── AbstractClassDiscovery.php
├── ClassDiscoveryInterface.php
└── RelativeNamespaceDiscovery.php
├── Collection
├── CallableTask.php
├── Collection.php
├── CollectionBuilder.php
├── CollectionInterface.php
├── CollectionProcessHook.php
├── CompletionWrapper.php
├── Element.php
├── NestedCollectionInterface.php
├── TaskForEach.php
├── Tasks.php
└── Temporary.php
├── Common
├── BuilderAwareTrait.php
├── CommandArguments.php
├── CommandReceiver.php
├── ConfigAwareTrait.php
├── DynamicParams.php
├── ExecCommand.php
├── ExecOneCommand.php
├── ExecTrait.php
├── IO.php
├── InflectionTrait.php
├── InputAwareTrait.php
├── OutputAdapter.php
├── OutputAwareTrait.php
├── ProcessExecutor.php
├── ProcessUtils.php
├── ProgressIndicator.php
├── ProgressIndicatorAwareTrait.php
├── ResourceExistenceChecker.php
├── TaskIO.php
├── TimeKeeper.php
├── Timer.php
└── VerbosityThresholdTrait.php
├── Config.php
├── Config
├── Config.php
└── GlobalOptionDefaultValuesInterface.php
├── Contract
├── BuilderAwareInterface.php
├── CommandInterface.php
├── CompletionInterface.php
├── ConfigAwareInterface.php
├── IOAwareInterface.php
├── InflectionInterface.php
├── OutputAdapterInterface.php
├── OutputAwareInterface.php
├── PrintedInterface.php
├── ProgressIndicatorAwareInterface.php
├── ProgressInterface.php
├── RollbackInterface.php
├── SimulatedInterface.php
├── TaskInterface.php
├── VerbosityThresholdInterface.php
└── WrappedTaskInterface.php
├── Exception
├── AbortTasksException.php
├── TaskException.php
└── TaskExitException.php
├── GlobalOptionsEventListener.php
├── LoadAllTasks.php
├── Log
├── ResultPrinter.php
├── RoboLogLevel.php
├── RoboLogStyle.php
└── RoboLogger.php
├── Result.php
├── ResultData.php
├── Robo.php
├── Runner.php
├── Runtime
└── Runner.php
├── State
├── Consumer.php
├── Data.php
├── StateAwareInterface.php
└── StateAwareTrait.php
├── Symfony
├── ConsoleIO.php
├── ConsoleIOInjector.php
└── SymfonyStyleInjector.php
├── Task
├── ApiGen
│ ├── ApiGen.php
│ └── Tasks.php
├── Archive
│ ├── Extract.php
│ ├── Pack.php
│ └── Tasks.php
├── Assets
│ ├── CssPreprocessor.php
│ ├── ImageMinify.php
│ ├── Less.php
│ ├── Minify.php
│ ├── Scss.php
│ └── Tasks.php
├── Base
│ ├── Exec.php
│ ├── ExecStack.php
│ ├── ParallelExec.php
│ ├── Shortcuts.php
│ ├── SymfonyCommand.php
│ ├── Tasks.php
│ └── Watch.php
├── BaseTask.php
├── Bower
│ ├── Base.php
│ ├── Install.php
│ ├── Tasks.php
│ └── Update.php
├── CommandStack.php
├── Composer
│ ├── Base.php
│ ├── CheckPlatformReqs.php
│ ├── Config.php
│ ├── CreateProject.php
│ ├── DumpAutoload.php
│ ├── Init.php
│ ├── Install.php
│ ├── Remove.php
│ ├── RequireDependency.php
│ ├── Tasks.php
│ ├── Update.php
│ └── Validate.php
├── Development
│ ├── Changelog.php
│ ├── GenerateMarkdownDoc.php
│ ├── GenerateTask.php
│ ├── GitHub.php
│ ├── GitHubRelease.php
│ ├── OpenBrowser.php
│ ├── PackPhar.php
│ ├── PhpServer.php
│ ├── SemVer.php
│ └── Tasks.php
├── Docker
│ ├── Base.php
│ ├── Build.php
│ ├── Commit.php
│ ├── Exec.php
│ ├── Pull.php
│ ├── Remove.php
│ ├── Result.php
│ ├── Run.php
│ ├── Start.php
│ ├── Stop.php
│ └── Tasks.php
├── File
│ ├── Concat.php
│ ├── Replace.php
│ ├── Tasks.php
│ ├── TmpFile.php
│ └── Write.php
├── Filesystem
│ ├── BaseDir.php
│ ├── CleanDir.php
│ ├── CopyDir.php
│ ├── DeleteDir.php
│ ├── FilesystemStack.php
│ ├── FlattenDir.php
│ ├── MirrorDir.php
│ ├── Shortcuts.php
│ ├── Tasks.php
│ ├── TmpDir.php
│ └── WorkDir.php
├── Gulp
│ ├── Base.php
│ ├── Run.php
│ └── Tasks.php
├── Logfile
│ ├── BaseLogfile.php
│ ├── RotateLog.php
│ ├── Shortcuts.php
│ ├── Tasks.php
│ └── TruncateLog.php
├── Npm
│ ├── Base.php
│ ├── Install.php
│ ├── Tasks.php
│ └── Update.php
├── Remote
│ ├── Rsync.php
│ ├── Ssh.php
│ └── Tasks.php
├── Simulator.php
├── StackBasedTask.php
├── Testing
│ ├── Atoum.php
│ ├── Behat.php
│ ├── Codecept.php
│ ├── PHPUnit.php
│ ├── Phpspec.php
│ └── Tasks.php
└── Vcs
│ ├── GitStack.php
│ ├── HgStack.php
│ ├── Shortcuts.php
│ ├── SvnStack.php
│ └── Tasks.php
├── TaskAccessor.php
├── TaskInfo.php
└── Tasks.php
/.editorconfig:
--------------------------------------------------------------------------------
1 | # This file is for unifying the coding style for different editors and IDEs
2 | # editorconfig.org
3 |
4 | root = true
5 |
6 | [*]
7 | end_of_line = lf
8 | charset = utf-8
9 | trim_trailing_whitespace = true
10 | insert_final_newline = true
11 |
12 | [**.php]
13 | indent_style = space
14 | indent_size = 4
15 |
16 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing to Robo
2 |
3 | Thank you for your interest in contributing to Robo! Here are some of the guidelines you should follow to make the most of your efforts:
4 |
5 | ## Code Style Guidelines
6 |
7 | Robo adheres to the [PSR-2 Coding Style Guide](https://www.php-fig.org/psr/psr-2/) for PHP code. An `.editorconfig` file is included with the repository to help you get up and running quickly. Most modern editors support this standard, but if yours does not or you would like to configure your editor manually, follow the guidelines in the document linked above.
8 |
9 | You can run the PHP Codesniffer on your work using a convenient command built into this project's own `RoboFile.php`:
10 | ```
11 | robo sniff src/Foo.php --autofix
12 | ```
13 | The above will run the PHP Codesniffer on the `src/Foo.php` file and automatically correct variances from the PSR-2 standard. Please ensure all contributions are compliant _before_ submitting a pull request.
14 |
15 | ## Tests
16 |
17 | Note that in the past, Robo used Codeception / Aspect Mock etc. in its unit tests. These components proved to be difficult to maintain when testing on mutiple PHP versions, so they were removed. The tests formerly in tests/cli were all ported to straight phpunit tests in the tests/integration directory. Some of the unit tests from tests/unit were ported to tests/phpunit; however, a number of tests that still use AspectMock still exist in tests/unit, although these are not currently being used.
18 |
19 | Pull requests that touch parts of the code formerly tested by these disabled tests must also convert the AspectMock test to Prophecy or some other mocking system. Alternately, getting AspectMock working again on the master and 1.x branches is another option, if someone wants to stand up to do that work.
20 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2014-2021 Codegyre Developers Team, Consolidation Team
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 |
22 | DEPENDENCY LICENSES:
23 |
24 | Name Version License
25 | consolidation/annotated-command 4.2.3 MIT
26 | consolidation/config 2.0.0 MIT
27 | consolidation/log 2.0.1 MIT
28 | consolidation/output-formatters 4.1.1 MIT
29 | consolidation/self-update 1.2.0 MIT
30 | dflydev/dot-access-data v1.1.0 MIT
31 | grasmash/expander 1.0.0 MIT
32 | league/container 3.3.3 MIT
33 | psr/container 1.0.0 MIT
34 | psr/log 1.1.3 MIT
35 | symfony/console v4.4.14 MIT
36 | symfony/event-dispatcher v4.4.14 MIT
37 | symfony/event-dispatcher-contracts v1.1.9 MIT
38 | symfony/filesystem v4.4.14 MIT
39 | symfony/finder v4.4.14 MIT
40 | symfony/polyfill-ctype v1.18.1 MIT
41 | symfony/polyfill-mbstring v1.18.1 MIT
42 | symfony/polyfill-php73 v1.18.1 MIT
43 | symfony/polyfill-php80 v1.18.1 MIT
44 | symfony/process v4.4.14 MIT
45 | symfony/service-contracts v1.1.9 MIT
46 |
--------------------------------------------------------------------------------
/codeception.yml:
--------------------------------------------------------------------------------
1 | actor: Guy
2 | paths:
3 | tests: tests
4 | log: tests/_log
5 | data: tests/_data
6 | helpers: tests/_helpers
7 | bootstrap: _bootstrap.php
8 | settings:
9 | colors: true
10 | memory_limit: 1024M
11 | modules:
12 | config:
13 | Db:
14 | dsn: ''
15 | user: ''
16 | password: ''
17 | dump: tests/_data/dump.sql
18 | coverage:
19 | enabled: true
20 | include:
21 | - src/*
22 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "consolidation/robo",
3 | "description": "Modern task runner",
4 | "license": "MIT",
5 | "authors": [
6 | {
7 | "name": "Davert",
8 | "email": "davert.php@resend.cc"
9 | }
10 | ],
11 | "autoload": {
12 | "psr-4": {
13 | "Robo\\": "src"
14 | }
15 | },
16 | "autoload-dev": {
17 | "psr-4": {
18 | "Robo\\": "tests/src",
19 | "RoboExample\\": "examples/src"
20 | }
21 | },
22 | "bin": [
23 | "robo"
24 | ],
25 | "require": {
26 | "php": ">=8.2",
27 | "consolidation/annotated-command": "^4.8.1",
28 | "consolidation/config": "^3",
29 | "consolidation/log": "^3",
30 | "consolidation/output-formatters": "^4.1.2",
31 | "league/container": "^3.3.1 || ^4.0",
32 | "phpowermove/docblock": "^4.0",
33 | "symfony/console": "^6 || ^7",
34 | "symfony/event-dispatcher": "^6 || ^7",
35 | "symfony/filesystem": "^6 || ^7",
36 | "symfony/finder": "^6 || ^7",
37 | "symfony/process": "^6 || ^7",
38 | "symfony/yaml": "^6 || ^7"
39 | },
40 | "require-dev": {
41 | "natxet/cssmin": "3.0.4",
42 | "patchwork/jsqueeze": "^2",
43 | "pear/archive_tar": "^1.4.4",
44 | "squizlabs/php_codesniffer": "^3.6",
45 | "phpunit/phpunit": "^7.5.20 || ^8 || ^9",
46 | "yoast/phpunit-polyfills": "^0.2.0"
47 | },
48 | "scripts": {
49 | "cs": "./robo sniff",
50 | "unit": "phpunit",
51 | "lint": "find src tests/src -name '*.php' -print0 | xargs -0 -n1 -P4 -- php -l",
52 | "test": [
53 | "@lint",
54 | "@unit",
55 | "@cs"
56 | ],
57 | "phpdoc": "build/tools/phpdoc",
58 | "install-tools": [
59 | "if [[ ! -f build/tools/phpdoc ]] ; then mkdir -p build/tools && wget --output-document=build/tools/phpdoc https://phpdoc.org/phpDocumentor.phar && chmod +x build/tools/phpdoc; fi"
60 | ]
61 | },
62 | "config": {
63 | "optimize-autoloader": true,
64 | "sort-packages": true,
65 | "platform": {
66 | "php": "8.2.18"
67 | }
68 | },
69 | "suggest": {
70 | "pear/archive_tar": "Allows tar archives to be created and extracted in taskPack and taskExtract, respectively.",
71 | "totten/lurkerlite": "For monitoring filesystem changes in taskWatch",
72 | "patchwork/jsqueeze": "For minifying JS files in taskMinify",
73 | "natxet/cssmin": "For minifying CSS files in taskMinify",
74 | "consolidation/self-update": "For self-updating a phar-based app built with Robo"
75 | },
76 | "conflict": {
77 | "codegyre/robo": "*"
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/data/Task/Development/GeneratedWrapper.tmpl:
--------------------------------------------------------------------------------
1 | task{wrapperClassName}()
15 | * ...
16 | * ->run();
17 | *
18 | * // one line
19 | * ...
20 | *
21 | * ?>
22 | * ```
23 | *
24 | {methodList}
25 | */
26 | class {wrapperClassName} extends StackBasedTask
27 | {
28 | protected $delegate;
29 |
30 | public function __construct()
31 | {
32 | $this->delegate = new {delegate}();
33 | }
34 |
35 | protected function getDelegate()
36 | {
37 | return $this->delegate;
38 | }{immediateMethods}{methodImplementations}
39 | }
40 |
--------------------------------------------------------------------------------
/dependencies.yml:
--------------------------------------------------------------------------------
1 | version: 2
2 | dependencies:
3 | - type: php
4 | settings:
5 | composer_options: "--no-dev" # used in "collection", overriden when actually making updates
6 | lockfile_updates:
7 | settings:
8 | composer_options: ""
9 | manifest_updates:
10 | settings:
11 | composer_options: ""
12 | filters:
13 | - name: ".*"
14 | versions: "L.Y.Y"
15 |
--------------------------------------------------------------------------------
/phpunit.xml.dist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
23 |
24 |
25 |
26 |
27 |
28 |
29 | tests/integration
30 |
31 |
32 | tests/phpunit
33 |
34 |
35 |
36 |
37 |
38 | ./src
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/robo:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env php
2 | 500000);
17 |
18 | // Non-phar autoloader paths
19 | $candidates = [
20 | __DIR__.'/vendor/autoload.php',
21 | __DIR__.'/../../autoload.php',
22 | __DIR__.'/../autoload.php',
23 | ];
24 |
25 | // Use our phar alias path
26 | if ($isPhar) {
27 | array_unshift($candidates, 'phar://robo.phar/vendor/autoload.php');
28 | }
29 |
30 | $autoloaderPath = false;
31 | foreach ($candidates as $candidate) {
32 | if (file_exists($candidate)) {
33 | $autoloaderPath = $candidate;
34 | break;
35 | }
36 | }
37 | if (!$autoloaderPath) {
38 | die("Could not find autoloader. Run 'composer install'.");
39 | }
40 | $classLoader = require $autoloaderPath;
41 | $configFilePath = getenv('ROBO_CONFIG') ?: getenv('HOME') . '/.robo/robo.yml';
42 | $runner = new \Robo\Runner();
43 | $runner
44 | ->setRelativePluginNamespace('Robo\Plugin')
45 | ->setSelfUpdateRepository('consolidation/robo')
46 | ->setConfigurationFilename($configFilePath)
47 | ->setEnvConfigPrefix('ROBO')
48 | ->setClassLoader($classLoader);
49 | $statusCode = $runner->execute($_SERVER['argv']);
50 | exit($statusCode);
51 |
--------------------------------------------------------------------------------
/robo.yml:
--------------------------------------------------------------------------------
1 | options:
2 | progress-delay: 2
3 | simulate: null
4 | command:
5 | try:
6 | config:
7 | options:
8 | opt: wow
9 |
--------------------------------------------------------------------------------
/src/Application.php:
--------------------------------------------------------------------------------
1 | getDefinition()
22 | ->addOption(
23 | new InputOption('--simulate', null, InputOption::VALUE_NONE, 'Run in simulated mode (show what would have happened).')
24 | );
25 | $this->getDefinition()
26 | ->addOption(
27 | new InputOption('--progress-delay', null, InputOption::VALUE_REQUIRED, 'Number of seconds before progress bar is displayed in long-running task collections. Default: 2s.', Config::DEFAULT_PROGRESS_DELAY)
28 | );
29 |
30 | $this->getDefinition()
31 | ->addOption(
32 | new InputOption('--define', '-D', InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'Define a configuration item value.', [])
33 | );
34 | }
35 |
36 | /**
37 | * @param string $roboFile
38 | * @param string $roboClass
39 | */
40 | public function addInitRoboFileCommand($roboFile, $roboClass)
41 | {
42 | $createRoboFile = new Command('init');
43 | $createRoboFile->setDescription("Intitalizes basic RoboFile in current dir");
44 | $createRoboFile->setCode(function (InputInterface $input, OutputInterface $output) use ($roboClass, $roboFile) {
45 | $output->writeln(" ~~~ Welcome to Robo! ~~~~ ");
46 | $output->writeln(" " . basename($roboFile) . " will be created in the current directory ");
47 | file_put_contents(
48 | $roboFile,
49 | 'writeln(" Edit this file to add your commands! ");
58 | });
59 | $this->add($createRoboFile);
60 | }
61 |
62 | /**
63 | * Add self update command, do nothing if null is provided
64 | *
65 | * @param string $repository
66 | * GitHub Repository for self update.
67 | */
68 | public function addSelfUpdateCommand($repository = null)
69 | {
70 | if (!$repository || !class_exists('\SelfUpdate\SelfUpdateCommand') || empty(\Phar::running())) {
71 | return;
72 | }
73 | $selfUpdateCommand = new \SelfUpdate\SelfUpdateCommand($this->getName(), $this->getVersion(), $repository);
74 | $this->add($selfUpdateCommand);
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/src/ClassDiscovery/AbstractClassDiscovery.php:
--------------------------------------------------------------------------------
1 | searchPattern = $searchPattern;
23 |
24 | return $this;
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/ClassDiscovery/ClassDiscoveryInterface.php:
--------------------------------------------------------------------------------
1 | classLoader = $classLoader;
33 | }
34 |
35 | /**
36 | * @param string $relativeNamespace
37 | *
38 | * @return $this
39 | */
40 | public function setRelativeNamespace($relativeNamespace)
41 | {
42 | $this->relativeNamespace = $relativeNamespace;
43 |
44 | return $this;
45 | }
46 |
47 | /**
48 | * {@inheritDoc}
49 | */
50 | public function getClasses()
51 | {
52 | $classes = [];
53 | $relativePath = $this->convertNamespaceToPath($this->relativeNamespace);
54 |
55 | foreach ($this->classLoader->getPrefixesPsr4() as $baseNamespace => $directories) {
56 | $directories = array_filter(array_map(function ($directory) use ($relativePath) {
57 | return $directory . $relativePath;
58 | }, $directories), 'is_dir');
59 |
60 | if ($directories) {
61 | foreach ($this->search($directories, $this->searchPattern) as $file) {
62 | $relativePathName = $file->getRelativePathname();
63 | $classes[] = $baseNamespace . $this->convertPathToNamespace($relativePath . '/' . $relativePathName);
64 | }
65 | }
66 | }
67 |
68 | return $classes;
69 | }
70 |
71 | /**
72 | * {@inheritdoc}
73 | */
74 | public function getFile($class)
75 | {
76 | return $this->classLoader->findFile($class);
77 | }
78 |
79 | /**
80 | * @param string|array $directories
81 | * @param string $pattern
82 | *
83 | * @return \Symfony\Component\Finder\Finder
84 | */
85 | protected function search($directories, $pattern)
86 | {
87 | $finder = new Finder();
88 | $finder->files()
89 | ->name($pattern)
90 | ->in($directories);
91 |
92 | return $finder;
93 | }
94 |
95 | /**
96 | * @param string $path
97 | *
98 | * @return string
99 | */
100 | protected function convertPathToNamespace($path)
101 | {
102 | return str_replace(['/', '.php'], ['\\', ''], trim($path, '/'));
103 | }
104 |
105 | /**
106 | * @param string $namespace
107 | *
108 | * @return string
109 | */
110 | public function convertNamespaceToPath($namespace)
111 | {
112 | return '/' . str_replace("\\", '/', trim($namespace, '\\'));
113 | }
114 | }
115 |
--------------------------------------------------------------------------------
/src/Collection/CallableTask.php:
--------------------------------------------------------------------------------
1 | fn = $fn;
32 | $this->reference = $reference;
33 | }
34 |
35 | /**
36 | * {@inheritdoc}
37 | */
38 | public function run()
39 | {
40 | $result = call_user_func($this->fn, $this->getState());
41 | // If the function returns no result, then count it
42 | // as a success.
43 | if (!isset($result)) {
44 | $result = Result::success($this->reference);
45 | }
46 | // If the function returns a result, it must either return
47 | // a \Robo\Result or an exit code. In the later case, we
48 | // convert it to a \Robo\Result.
49 | if (!$result instanceof Result) {
50 | $result = new Result($this->reference, $result);
51 | }
52 |
53 | return $result;
54 | }
55 |
56 | /**
57 | * @return \Robo\State\Data
58 | */
59 | public function getState()
60 | {
61 | if ($this->reference instanceof StateAwareInterface) {
62 | return $this->reference->getState();
63 | }
64 | return new Data();
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/src/Collection/CollectionProcessHook.php:
--------------------------------------------------------------------------------
1 | run();
31 | } catch (\Exception $e) {
32 | return Result::fromException($result, $e);
33 | }
34 | }
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/Collection/CompletionWrapper.php:
--------------------------------------------------------------------------------
1 | collection = $collection;
60 | $this->task = ($task instanceof WrappedTaskInterface) ? $task->original() : $task;
61 | $this->rollbackTask = $rollbackTask;
62 | }
63 |
64 | /**
65 | * {@inheritdoc}
66 | */
67 | public function original()
68 | {
69 | return $this->task;
70 | }
71 |
72 | /**
73 | * Before running this task, register its rollback and completion
74 | * handlers on its collection. The reason this class exists is to
75 | * defer registration of rollback and completion tasks until 'run()' time.
76 | *
77 | * @return \Robo\Result
78 | */
79 | public function run()
80 | {
81 | if ($this->rollbackTask) {
82 | $this->collection->registerRollback($this->rollbackTask);
83 | }
84 | if ($this->task instanceof RollbackInterface) {
85 | $this->collection->registerRollback(new CallableTask([$this->task, 'rollback'], $this->task));
86 | }
87 | if ($this->task instanceof CompletionInterface) {
88 | $this->collection->registerCompletion(new CallableTask([$this->task, 'complete'], $this->task));
89 | }
90 |
91 | return $this->task->run();
92 | }
93 |
94 | /**
95 | * Make this wrapper object act like the class it wraps.
96 | *
97 | * @param string $function
98 | * @param array $args
99 | *
100 | * @return mixed
101 | */
102 | public function __call($function, $args)
103 | {
104 | return call_user_func_array(array($this->task, $function), $args);
105 | }
106 | }
107 |
--------------------------------------------------------------------------------
/src/Collection/Element.php:
--------------------------------------------------------------------------------
1 | task = $task;
35 | }
36 |
37 | /**
38 | * @param \Robo\Contract\TaskInterface|callable $before
39 | * @param string $name
40 | */
41 | public function before($before, $name)
42 | {
43 | if ($name) {
44 | $this->before[$name] = $before;
45 | } else {
46 | $this->before[] = $before;
47 | }
48 | }
49 |
50 | /**
51 | * @param \Robo\Contract\TaskInterface|callable $after
52 | * @param string $name
53 | */
54 | public function after($after, $name)
55 | {
56 | if ($name) {
57 | $this->after[$name] = $after;
58 | } else {
59 | $this->after[] = $after;
60 | }
61 | }
62 |
63 | /**
64 | * @return \Robo\Contract\TaskInterface[]|callable[]
65 | */
66 | public function getBefore()
67 | {
68 | return $this->before;
69 | }
70 |
71 | /**
72 | * @return \Robo\Contract\TaskInterface[]|callable[]
73 | */
74 | public function getAfter()
75 | {
76 | return $this->after;
77 | }
78 |
79 | /**
80 | * @return \Robo\Contract\TaskInterface
81 | */
82 | public function getTask()
83 | {
84 | return $this->task;
85 | }
86 |
87 | /**
88 | * @return \Robo\Contract\TaskInterface[]|callable[]
89 | */
90 | public function getTaskList()
91 | {
92 | return array_merge($this->getBefore(), [$this->getTask()], $this->getAfter());
93 | }
94 |
95 | /**
96 | * @return int
97 | */
98 | public function progressIndicatorSteps()
99 | {
100 | $steps = 0;
101 | foreach ($this->getTaskList() as $task) {
102 | if ($task instanceof WrappedTaskInterface) {
103 | $task = $task->original();
104 | }
105 | // If the task is a ProgressIndicatorAwareInterface, then it
106 | // will advance the progress indicator a number of times.
107 | if ($task instanceof ProgressIndicatorAwareInterface) {
108 | $steps += $task->progressIndicatorSteps();
109 | }
110 | // We also advance the progress indicator once regardless
111 | // of whether it is progress-indicator aware or not.
112 | $steps++;
113 | }
114 | return $steps;
115 | }
116 | }
117 |
--------------------------------------------------------------------------------
/src/Collection/NestedCollectionInterface.php:
--------------------------------------------------------------------------------
1 | task(TaskForEach::class, $collection);
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/Collection/Temporary.php:
--------------------------------------------------------------------------------
1 | get('collection');
43 | register_shutdown_function(function () {
44 | static::complete();
45 | });
46 | }
47 |
48 | return static::$collection;
49 | }
50 |
51 | /**
52 | * Call the complete method of all of the registered objects.
53 | */
54 | public static function complete()
55 | {
56 | // Run the collection of tasks. This will also run the
57 | // completion tasks.
58 | $collection = static::getCollection();
59 | $collection->run();
60 | // Make sure that our completion functions do not run twice.
61 | $collection->reset();
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/src/Common/BuilderAwareTrait.php:
--------------------------------------------------------------------------------
1 | builder = $builder;
26 |
27 | return $this;
28 | }
29 |
30 | /**
31 | * @see \Robo\Contract\BuilderAwareInterface::getBuilder()
32 | *
33 | * @return \Robo\Collection\CollectionBuilder
34 | */
35 | public function getBuilder()
36 | {
37 | return $this->builder;
38 | }
39 |
40 | /**
41 | * @return \Robo\Collection\CollectionBuilder
42 | *
43 | * @param \Robo\Symfony\ConsoleIO $io
44 | */
45 | protected function collectionBuilder($io = null)
46 | {
47 | // TODO: trigger_error if $io is null. Eventually this shim will be removed.
48 | if (!$io) {
49 | $io = new ConsoleIO(Robo::input(), Robo::output());
50 | }
51 | return $this->getBuilder()->newBuilder()->inflect($this)->inflect($io);
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/src/Common/CommandArguments.php:
--------------------------------------------------------------------------------
1 | args($arg);
27 | }
28 |
29 | /**
30 | * Pass methods parameters as arguments to executable. Argument values
31 | * are automatically escaped.
32 | *
33 | * @param string|string[] $args
34 | *
35 | * @return $this
36 | */
37 | public function args($args)
38 | {
39 | $func_args = func_get_args();
40 | if (!is_array($args)) {
41 | $args = $func_args;
42 | }
43 | $this->arguments .= ' ' . implode(' ', array_map([static::class, 'escape'], $args));
44 | return $this;
45 | }
46 |
47 | /**
48 | * Pass the provided string in its raw (as provided) form as an argument to executable.
49 | *
50 | * @param string $arg
51 | *
52 | * @return $this
53 | */
54 | public function rawArg($arg)
55 | {
56 | $this->arguments .= " $arg";
57 |
58 | return $this;
59 | }
60 |
61 | /**
62 | * Escape the provided value, unless it contains only alphanumeric
63 | * plus a few other basic characters.
64 | *
65 | * @param string $value
66 | *
67 | * @return string
68 | */
69 | public static function escape($value)
70 | {
71 | if (preg_match('/^[a-zA-Z0-9\/\.@~_-]+$/', $value)) {
72 | return $value;
73 | }
74 | return ProcessUtils::escapeArgument($value);
75 | }
76 |
77 | /**
78 | * Pass option to executable. Options are prefixed with `--` , value can be provided in second parameter.
79 | * Option values are automatically escaped.
80 | *
81 | * @param string $option
82 | * @param string $value
83 | * @param string $separator
84 | *
85 | * @return $this
86 | */
87 | public function option($option, $value = null, $separator = ' ')
88 | {
89 | if ($option !== null and strpos($option, '-') !== 0) {
90 | $option = "--$option";
91 | }
92 | $this->arguments .= null == $option ? '' : " " . $option;
93 | $this->arguments .= null == $value ? '' : $separator . static::escape($value);
94 | return $this;
95 | }
96 |
97 | /**
98 | * Pass multiple options to executable. The associative array contains
99 | * the key:value pairs that become `--key value`, for each item in the array.
100 | * Values are automatically escaped.
101 | *
102 | * @param array $options
103 | * @param string $separator
104 | *
105 | * @return $this
106 | */
107 | public function options(array $options, $separator = ' ')
108 | {
109 | foreach ($options as $option => $value) {
110 | $this->option($option, $value, $separator);
111 | }
112 | return $this;
113 | }
114 |
115 | /**
116 | * Pass an option with multiple values to executable. Value can be a string or array.
117 | * Option values are automatically escaped.
118 | *
119 | * @param string $option
120 | * @param string|array $value
121 | * @param string $separator
122 | *
123 | * @return $this
124 | */
125 | public function optionList($option, $value = array(), $separator = ' ')
126 | {
127 | if (is_array($value)) {
128 | foreach ($value as $item) {
129 | $this->optionList($option, $item, $separator);
130 | }
131 | } else {
132 | $this->option($option, $value, $separator);
133 | }
134 |
135 | return $this;
136 | }
137 | }
138 |
--------------------------------------------------------------------------------
/src/Common/CommandReceiver.php:
--------------------------------------------------------------------------------
1 | getCommand();
27 | } else {
28 | throw new TaskException($this, get_class($command) . " does not implement CommandInterface, so can't be passed into this task");
29 | }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/Common/ConfigAwareTrait.php:
--------------------------------------------------------------------------------
1 | config = $config;
25 |
26 | return $this;
27 | }
28 |
29 | /**
30 | * Get the config management object.
31 | *
32 | * @return \Consolidation\Config\ConfigInterface
33 | */
34 | public function getConfig()
35 | {
36 | return $this->config;
37 | }
38 |
39 | /**
40 | * Any class that uses ConfigAwareTrait SHOULD override this method
41 | * , and define a prefix for its configuration items. This is usually
42 | * done in a base class. When used, this method should return a string
43 | * that ends with a "."; see BaseTask::configPrefix().
44 | *
45 | * @return string
46 | */
47 | protected static function configPrefix()
48 | {
49 | return '';
50 | }
51 |
52 | protected static function configClassIdentifier($classname)
53 | {
54 | $configIdentifier = strtr($classname, '\\', '.');
55 | $configIdentifier = preg_replace('#^(.*\.Task\.|\.)#', '', $configIdentifier);
56 |
57 | return $configIdentifier;
58 | }
59 |
60 | protected static function configPostfix()
61 | {
62 | return '';
63 | }
64 |
65 | /**
66 | * @param string $key
67 | *
68 | * @return string
69 | */
70 | private static function getClassKey($key)
71 | {
72 | $configPrefix = static::configPrefix(); // task.
73 | $configClass = static::configClassIdentifier(static::class); // PARTIAL_NAMESPACE.CLASSNAME
74 | $configPostFix = static::configPostfix(); // .settings
75 |
76 | return sprintf('%s%s%s.%s', $configPrefix, $configClass, $configPostFix, $key);
77 | }
78 |
79 | /**
80 | * @param string $key
81 | * @param mixed $value
82 | * @param \Consolidation\Config\ConfigInterface|null $config
83 | */
84 | public static function configure($key, $value, $config = null)
85 | {
86 | if (!$config) {
87 | $config = Robo::config();
88 | }
89 | $config->setDefault(static::getClassKey($key), $value);
90 | }
91 |
92 | /**
93 | * @param string $key
94 | * @param mixed|null $default
95 | *
96 | * @return mixed|null
97 | */
98 | protected function getConfigValue($key, $default = null)
99 | {
100 | if (!$this->getConfig()) {
101 | return $default;
102 | }
103 | return $this->getConfig()->get(static::getClassKey($key), $default);
104 | }
105 | }
106 |
--------------------------------------------------------------------------------
/src/Common/DynamicParams.php:
--------------------------------------------------------------------------------
1 | $property))) {
29 | $this->$property = !$this->$property;
30 | return $this;
31 | }
32 |
33 | // append item to array
34 | if (is_array($this->$property)) {
35 | if (is_array($args[0])) {
36 | $this->$property = $args[0];
37 | } else {
38 | array_push($this->$property, $args[0]);
39 | }
40 | return $this;
41 | }
42 |
43 | $this->$property = $args[0];
44 | return $this;
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/src/Common/ExecOneCommand.php:
--------------------------------------------------------------------------------
1 | injectDependencies($this);
21 | }
22 | return $this;
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/Common/InputAwareTrait.php:
--------------------------------------------------------------------------------
1 | input = $input;
23 | }
24 |
25 | /**
26 | * @return \Symfony\Component\Console\Input\InputInterface
27 | */
28 | protected function input()
29 | {
30 | if (!isset($this->input)) {
31 | $this->setInput(new ArgvInput());
32 | }
33 | return $this->input;
34 | }
35 |
36 | /**
37 | * Backwards compatibility.
38 | *
39 | * @return \Symfony\Component\Console\Input\InputInterface
40 | *
41 | * @deprecated
42 | */
43 | protected function getInput()
44 | {
45 | return $this->input();
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/src/Common/OutputAdapter.php:
--------------------------------------------------------------------------------
1 | OutputInterface::VERBOSITY_NORMAL,
22 | VerbosityThresholdInterface::VERBOSITY_VERBOSE => OutputInterface::VERBOSITY_VERBOSE,
23 | VerbosityThresholdInterface::VERBOSITY_VERY_VERBOSE => OutputInterface::VERBOSITY_VERY_VERBOSE,
24 | VerbosityThresholdInterface::VERBOSITY_DEBUG => OutputInterface::VERBOSITY_DEBUG,
25 | ];
26 |
27 | /**
28 | * {@inheritdoc}
29 | */
30 | public function verbosityMeetsThreshold($verbosityThreshold)
31 | {
32 | if (!isset($this->verbosityMap[$verbosityThreshold])) {
33 | return true;
34 | }
35 | $verbosityThreshold = $this->verbosityMap[$verbosityThreshold];
36 | $verbosity = $this->output()->getVerbosity();
37 |
38 | return $verbosity >= $verbosityThreshold;
39 | }
40 |
41 | /**
42 | * {@inheritdoc}
43 | */
44 | public function writeMessage($message)
45 | {
46 | $this->output()->write($message);
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/src/Common/OutputAwareTrait.php:
--------------------------------------------------------------------------------
1 | output = $output;
26 |
27 | return $this;
28 | }
29 |
30 | /**
31 | * @return \Symfony\Component\Console\Output\OutputInterface
32 | */
33 | protected function output()
34 | {
35 | if (!isset($this->output)) {
36 | $this->setOutput(new NullOutput());
37 | }
38 | return $this->output;
39 | }
40 |
41 | /**
42 | * @return \Symfony\Component\Console\Output\OutputInterface
43 | */
44 | protected function stderr()
45 | {
46 | $output = $this->output();
47 | if ($output instanceof ConsoleOutputInterface) {
48 | $output = $output->getErrorOutput();
49 | }
50 | return $output;
51 | }
52 |
53 | /**
54 | * Backwards compatibility
55 | *
56 | * @return \Symfony\Component\Console\Output\OutputInterface
57 | *
58 | * @deprecated
59 | */
60 | protected function getOutput()
61 | {
62 | return $this->output();
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/src/Common/ProcessExecutor.php:
--------------------------------------------------------------------------------
1 | process = $process;
23 | }
24 |
25 | /**
26 | * @param \Psr\Container\ContainerInterface $container
27 | * @param \Symfony\Component\Process\Process $process
28 | *
29 | * @return static
30 | */
31 | public static function create($container, $process)
32 | {
33 | $processExecutor = new self($process);
34 |
35 | $processExecutor->setLogger($container->get('logger'));
36 | $processExecutor->setProgressIndicator($container->get('progressIndicator'));
37 | $processExecutor->setConfig($container->get('config'));
38 | $processExecutor->setOutputAdapter($container->get('outputAdapter'));
39 |
40 | return $processExecutor;
41 | }
42 |
43 | /**
44 | * {@inheritdoc}
45 | */
46 | protected function getCommandDescription()
47 | {
48 | return $this->process->getCommandLine();
49 | }
50 |
51 | public function run()
52 | {
53 | return $this->execute($this->process);
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/src/Common/ProcessUtils.php:
--------------------------------------------------------------------------------
1 |
6 | */
7 |
8 | namespace Robo\Common;
9 |
10 | use Symfony\Component\Process\Exception\InvalidArgumentException;
11 |
12 | /**
13 | * ProcessUtils is a bunch of utility methods. We want to allow Robo 1.x
14 | * to work with Symfony 4.x while remaining backwards compatibility. This
15 | * requires us to replace some deprecated functionality removed in Symfony.
16 | */
17 | class ProcessUtils
18 | {
19 | /**
20 | * This class should not be instantiated.
21 | */
22 | private function __construct()
23 | {
24 | }
25 |
26 | /**
27 | * Escapes a string to be used as a shell argument.
28 | *
29 | * This method is a copy of a method that was deprecated by Symfony 3.3 and
30 | * removed in Symfony 4; it will be removed once there is an actual
31 | * replacement for escapeArgument.
32 | *
33 | * @param string $argument
34 | * The argument that will be escaped.
35 | *
36 | * @return string
37 | * The escaped argument.
38 | */
39 | public static function escapeArgument($argument)
40 | {
41 | //Fix for PHP bug #43784 escapeshellarg removes % from given string
42 | //Fix for PHP bug #49446 escapeshellarg doesn't work on Windows
43 | //@see https://bugs.php.net/bug.php?id=43784
44 | //@see https://bugs.php.net/bug.php?id=49446
45 | if ('\\' === DIRECTORY_SEPARATOR) {
46 | if ('' === $argument) {
47 | return escapeshellarg($argument);
48 | }
49 |
50 | $escapedArgument = '';
51 | $quote = false;
52 | foreach (preg_split('/(")/', $argument, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE) as $part) {
53 | if ('"' === $part) {
54 | $escapedArgument .= '\\"';
55 | } elseif (self::isSurroundedBy($part, '%')) {
56 | // Avoid environment variable expansion
57 | $escapedArgument .= '^%"' . substr($part, 1, -1) . '"^%';
58 | } else {
59 | // escape trailing backslash
60 | if ('\\' === substr($part, -1)) {
61 | $part .= '\\';
62 | }
63 | $quote = true;
64 | $escapedArgument .= $part;
65 | }
66 | }
67 | if ($quote) {
68 | $escapedArgument = '"' . $escapedArgument . '"';
69 | }
70 |
71 | return $escapedArgument;
72 | }
73 |
74 | return "'" . str_replace("'", "'\\''", $argument) . "'";
75 | }
76 |
77 | private static function isSurroundedBy($arg, $char)
78 | {
79 | return 2 < strlen($arg) && $char === $arg[0] && $char === $arg[strlen($arg) - 1];
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/src/Common/ProgressIndicatorAwareTrait.php:
--------------------------------------------------------------------------------
1 | progressIndicator = $progressIndicator;
33 |
34 | return $this;
35 | }
36 |
37 | /**
38 | * @return null|bool
39 | */
40 | protected function hideProgressIndicator()
41 | {
42 | if (!$this->progressIndicator) {
43 | return;
44 | }
45 | return $this->progressIndicator->hideProgressIndicator();
46 | }
47 |
48 | protected function showProgressIndicator()
49 | {
50 | if (!$this->progressIndicator) {
51 | return;
52 | }
53 | $this->progressIndicator->showProgressIndicator();
54 | }
55 |
56 | /**
57 | * @param bool $visible
58 | */
59 | protected function restoreProgressIndicator($visible)
60 | {
61 | if (!$this->progressIndicator) {
62 | return;
63 | }
64 | $this->progressIndicator->restoreProgressIndicator($visible);
65 | }
66 |
67 | /**
68 | * @return int
69 | */
70 | protected function getTotalExecutionTime()
71 | {
72 | if (!$this->progressIndicator) {
73 | return 0;
74 | }
75 | return $this->progressIndicator->getExecutionTime();
76 | }
77 |
78 | protected function startProgressIndicator()
79 | {
80 | $this->startTimer();
81 | if ($this instanceof VerbosityThresholdInterface
82 | && !$this->verbosityMeetsThreshold()
83 | ) {
84 | return;
85 | }
86 | if (!$this->progressIndicator) {
87 | return;
88 | }
89 | $totalSteps = $this->progressIndicatorSteps();
90 | $this->progressIndicator->startProgressIndicator($totalSteps, $this);
91 | }
92 |
93 | /**
94 | * @return bool
95 | */
96 | protected function inProgress()
97 | {
98 | if (!$this->progressIndicator) {
99 | return false;
100 | }
101 | return $this->progressIndicator->inProgress();
102 | }
103 |
104 | protected function stopProgressIndicator()
105 | {
106 | $this->stopTimer();
107 | if (!$this->progressIndicator) {
108 | return;
109 | }
110 | $this->progressIndicator->stopProgressIndicator($this);
111 | }
112 |
113 | protected function disableProgressIndicator()
114 | {
115 | $this->stopTimer();
116 | if (!$this->progressIndicator) {
117 | return;
118 | }
119 | $this->progressIndicator->disableProgressIndicator();
120 | }
121 |
122 | protected function detatchProgressIndicator()
123 | {
124 | $this->setProgressIndicator(null);
125 | }
126 |
127 | /**
128 | * @param int $steps
129 | */
130 | protected function advanceProgressIndicator($steps = 1)
131 | {
132 | if (!$this->progressIndicator) {
133 | return;
134 | }
135 | $this->progressIndicator->advanceProgressIndicator($steps);
136 | }
137 | }
138 |
--------------------------------------------------------------------------------
/src/Common/ResourceExistenceChecker.php:
--------------------------------------------------------------------------------
1 | printTaskError(sprintf('Invalid glob "%s"!', $resource), $this);
30 | $success = false;
31 | continue;
32 | }
33 | foreach ($glob as $resource) {
34 | if (!$this->checkResource($resource, $type)) {
35 | $success = false;
36 | }
37 | }
38 | }
39 | return $success;
40 | }
41 |
42 | /**
43 | * Checks a single resource, file or directory.
44 | *
45 | * It will print an error as well on the console.
46 | *
47 | * @param string $resource
48 | * File or folder.
49 | * @param string $type
50 | * Allowed values: "file", "dir", "fileAndDir".
51 | *
52 | * @return bool
53 | */
54 | protected function checkResource($resource, $type)
55 | {
56 | switch ($type) {
57 | case 'file':
58 | if (!$this->isFile($resource)) {
59 | $this->printTaskError(sprintf('File "%s" does not exist!', $resource), $this);
60 | return false;
61 | }
62 | return true;
63 | case 'dir':
64 | if (!$this->isDir($resource)) {
65 | $this->printTaskError(sprintf('Directory "%s" does not exist!', $resource), $this);
66 | return false;
67 | }
68 | return true;
69 | case 'fileAndDir':
70 | if (!$this->isDir($resource) && !$this->isFile($resource)) {
71 | $this->printTaskError(sprintf('File or directory "%s" does not exist!', $resource), $this);
72 | return false;
73 | }
74 | return true;
75 | }
76 | }
77 |
78 | /**
79 | * Convenience method to check the often uses "source => target" file / folder arrays.
80 | *
81 | * @param string|array $resources
82 | */
83 | protected function checkSourceAndTargetResource($resources)
84 | {
85 | if (is_string($resources)) {
86 | $resources = [$resources];
87 | }
88 | $sources = [];
89 | $targets = [];
90 | foreach ($resources as $source => $target) {
91 | $sources[] = $source;
92 | $target[] = $target;
93 | }
94 | $this->checkResources($sources);
95 | $this->checkResources($targets);
96 | }
97 |
98 | /**
99 | * Wrapper method around phps is_dir()
100 | *
101 | * @param string $directory
102 | *
103 | * @return bool
104 | */
105 | protected function isDir($directory)
106 | {
107 | return is_dir($directory);
108 | }
109 |
110 | /**
111 | * Wrapper method around phps file_exists()
112 | *
113 | * @param string $file
114 | *
115 | * @return bool
116 | */
117 | protected function isFile($file)
118 | {
119 | return file_exists($file);
120 | }
121 | }
122 |
--------------------------------------------------------------------------------
/src/Common/TimeKeeper.php:
--------------------------------------------------------------------------------
1 | startedAt) {
24 | return;
25 | }
26 | // Get time in seconds as a float, accurate to the microsecond.
27 | $this->startedAt = microtime(true);
28 | }
29 |
30 | public function stop()
31 | {
32 | $this->finishedAt = microtime(true);
33 | }
34 |
35 | public function reset()
36 | {
37 | $this->startedAt = $this->finishedAt = null;
38 | }
39 |
40 | /**
41 | * @return float|null
42 | */
43 | public function elapsed()
44 | {
45 | $finished = $this->finishedAt ? $this->finishedAt : microtime(true);
46 | if ($finished - $this->startedAt <= 0) {
47 | return null;
48 | }
49 | return $finished - $this->startedAt;
50 | }
51 |
52 | /**
53 | * Format a duration into a human-readable time.
54 | *
55 | * @param float $duration
56 | * Duration in seconds, with fractional component.
57 | *
58 | * @return string
59 | */
60 | public static function formatDuration($duration)
61 | {
62 | if ($duration >= self::DAY * 2) {
63 | return gmdate('z \d\a\y\s H:i:s', (int) $duration);
64 | }
65 | if ($duration >= self::DAY) {
66 | return gmdate('\1 \d\a\y H:i:s', (int) $duration);
67 | }
68 | if ($duration >= self::HOUR) {
69 | return gmdate("H:i:s", (int) $duration);
70 | }
71 | if ($duration >= self::MINUTE) {
72 | return gmdate("i:s", (int) $duration);
73 | }
74 | return round($duration, 3) . 's';
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/src/Common/Timer.php:
--------------------------------------------------------------------------------
1 | timer)) {
15 | $this->timer = new TimeKeeper();
16 | }
17 | $this->timer->start();
18 | }
19 |
20 | protected function stopTimer()
21 | {
22 | if (!isset($this->timer)) {
23 | return;
24 | }
25 | $this->timer->stop();
26 | }
27 |
28 | protected function resetTimer()
29 | {
30 | $this->timer->reset();
31 | }
32 |
33 | /**
34 | * @return float|null
35 | */
36 | protected function getExecutionTime()
37 | {
38 | if (!isset($this->timer)) {
39 | return null;
40 | }
41 | return $this->timer->elapsed();
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/src/Common/VerbosityThresholdTrait.php:
--------------------------------------------------------------------------------
1 | verbosityThreshold = $verbosityThreshold;
44 | return $this;
45 | }
46 |
47 | /**
48 | * @return int
49 | */
50 | public function verbosityThreshold()
51 | {
52 | return $this->verbosityThreshold;
53 | }
54 |
55 | public function setOutputAdapter(OutputAdapterInterface $outputAdapter)
56 | {
57 | $this->outputAdapter = $outputAdapter;
58 | }
59 |
60 | /**
61 | * @return \Robo\Contract\OutputAdapterInterface
62 | */
63 | public function outputAdapter()
64 | {
65 | return $this->outputAdapter;
66 | }
67 |
68 | /**
69 | * @return bool
70 | */
71 | public function hasOutputAdapter()
72 | {
73 | return isset($this->outputAdapter);
74 | }
75 |
76 | /**
77 | * @return bool
78 | */
79 | public function verbosityMeetsThreshold()
80 | {
81 | if ($this->hasOutputAdapter()) {
82 | return $this->outputAdapter()->verbosityMeetsThreshold($this->verbosityThreshold());
83 | }
84 | return true;
85 | }
86 |
87 | /**
88 | * Print a message if the selected verbosity level is over this task's
89 | * verbosity threshold.
90 | *
91 | * @param string $message
92 | */
93 | public function writeMessage($message)
94 | {
95 | if (!$this->verbosityMeetsThreshold()) {
96 | return;
97 | }
98 | $this->outputAdapter()->writeMessage($message);
99 | }
100 | }
101 |
--------------------------------------------------------------------------------
/src/Config.php:
--------------------------------------------------------------------------------
1 | inflect($this)
14 | * ->initializer()
15 | * ->...
16 | *
17 | * Instead of:
18 | *
19 | * (new SomeTask($args))
20 | * ->setLogger($this->logger)
21 | * ->initializer()
22 | * ->...
23 | *
24 | * The reason `inflect` is better than the more explicit alternative is
25 | * that subclasses of BaseTask that implement a new FooAwareInterface
26 | * can override injectDependencies() as explained below, and add more
27 | * dependencies that can be injected as needed.
28 | *
29 | * @param \Robo\Contract\InflectionInterface $parent
30 | */
31 | public function inflect($parent);
32 |
33 | /**
34 | * Take all dependencies availble to this task and inject any that are
35 | * needed into the provided task. The general pattern is that, for every
36 | * FooAwareInterface that this class implements, it should test to see
37 | * if the child also implements the same interface, and if so, should call
38 | * $child->setFoo($this->foo).
39 | *
40 | * The benefits of this are pretty large. Any time an object that implements
41 | * InflectionInterface is created, just call `$child->inflect($this)`, and
42 | * any available optional dependencies will be hooked up via setter injection.
43 | *
44 | * The required dependencies of an object should be provided via constructor
45 | * injection, not inflection.
46 | *
47 | * @param mixed $child An object with one or more *AwareInterfaces implemented.
48 | *
49 | * @see https://mwop.net/blog/2016-04-26-on-locators.html
50 | */
51 | public function injectDependencies($child);
52 | }
53 |
--------------------------------------------------------------------------------
/src/Contract/OutputAdapterInterface.php:
--------------------------------------------------------------------------------
1 | logger->setErrorStream(null);
28 | $this->logger->setOutputStream($output);
29 | }
30 |
31 | /**
32 | * Log the result of a Robo task.
33 | *
34 | * Returns 'true' if the message is printed, or false if it isn't.
35 | *
36 | * @param \Robo\Result $result
37 | *
38 | * @return null|bool
39 | */
40 | public function printResult(Result $result)
41 | {
42 | $task = $result->getTask();
43 | if ($task instanceof VerbosityThresholdInterface && !$task->verbosityMeetsThreshold()) {
44 | return;
45 | }
46 | if (!$result->wasSuccessful()) {
47 | return $this->printError($result);
48 | } else {
49 | return $this->printSuccess($result);
50 | }
51 | }
52 |
53 | /**
54 | * Log that we are about to abort due to an error being encountered
55 | * in 'stop on fail' mode.
56 | *
57 | * @param \Robo\Result $result
58 | */
59 | public function printStopOnFail($result)
60 | {
61 | $this->printMessage(LogLevel::NOTICE, 'Stopping on fail. Exiting....');
62 | $this->printMessage(LogLevel::ERROR, 'Exit Code: {code}', ['code' => $result->getExitCode()]);
63 | }
64 |
65 | /**
66 | * Log the result of a Robo task that returned an error.
67 | *
68 | * @param \Robo\Result $result
69 | *
70 | * @return bool
71 | */
72 | protected function printError(Result $result)
73 | {
74 | $task = $result->getTask();
75 | $context = $result->getContext() + ['timer-label' => 'Time', '_style' => []];
76 | $context['_style']['message'] = '';
77 |
78 | $printOutput = true;
79 | if ($task instanceof PrintedInterface) {
80 | $printOutput = !$task->getPrinted();
81 | }
82 | if ($printOutput) {
83 | $this->printMessage(LogLevel::ERROR, "{message}", $context);
84 | }
85 | $this->printMessage(LogLevel::ERROR, 'Exit code {code}', $context);
86 | return true;
87 | }
88 |
89 | /**
90 | * Log the result of a Robo task that was successful.
91 | *
92 | * @param \Robo\Result $result
93 | *
94 | * @return bool
95 | */
96 | protected function printSuccess(Result $result)
97 | {
98 | $task = $result->getTask();
99 | $context = $result->getContext() + ['timer-label' => 'in'];
100 | $time = $result->getExecutionTime();
101 | if ($time) {
102 | $this->printMessage(RoboLogLevel::SUCCESS, 'Done', $context);
103 | }
104 | return false;
105 | }
106 |
107 | /**
108 | * @param string $level
109 | * @param string $message
110 | * @param array $context
111 | */
112 | protected function printMessage($level, $message, $context = [])
113 | {
114 | $inProgress = $this->hideProgressIndicator();
115 | $this->logger->log($level, $message, $context);
116 | if ($inProgress) {
117 | $this->restoreProgressIndicator($inProgress);
118 | }
119 | }
120 | }
121 |
--------------------------------------------------------------------------------
/src/Log/RoboLogLevel.php:
--------------------------------------------------------------------------------
1 | labelStyles += [
27 | RoboLogLevel::SIMULATED_ACTION => self::TASK_STYLE_SIMULATED,
28 | RoboLogLevel::SUCCESS => self::TASK_STYLE_SUCCESS,
29 | ];
30 | $this->messageStyles += [
31 | RoboLogLevel::SIMULATED_ACTION => '',
32 | RoboLogLevel::SUCCESS => '',
33 | ];
34 | }
35 |
36 | /**
37 | * Log style customization for Robo: replace the log level with
38 | * the task name.
39 | *
40 | * @param string $level
41 | * @param string $message
42 | * @param array $context
43 | *
44 | * @return string
45 | */
46 | protected function formatMessageByLevel($level, $message, $context)
47 | {
48 | $label = $level;
49 | if (array_key_exists('name', $context)) {
50 | $label = $context['name'];
51 | }
52 | return $this->formatMessage($label, $message, $context, $this->labelStyles[$level], $this->messageStyles[$level]);
53 | }
54 |
55 | /**
56 | * Log style customization for Robo: add the time indicator to the
57 | * end of the log message if it exists in the context.
58 | *
59 | * @param string $label
60 | * @param string $message
61 | * @param array $context
62 | * @param string $taskNameStyle
63 | * @param string $messageStyle
64 | *
65 | * @return string
66 | */
67 | protected function formatMessage($label, $message, $context, $taskNameStyle, $messageStyle = '')
68 | {
69 | $message = parent::formatMessage($label, $message, $context, $taskNameStyle, $messageStyle);
70 |
71 | if (array_key_exists('time', $context) && !empty($context['time']) && array_key_exists('timer-label', $context)) {
72 | $duration = TimeKeeper::formatDuration($context['time']);
73 | $message .= ' ' . $context['timer-label'] . ' ' . $this->wrapFormatString($duration, 'fg=yellow');
74 | }
75 |
76 | return $message;
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/src/Log/RoboLogger.php:
--------------------------------------------------------------------------------
1 | OutputInterface::VERBOSITY_NORMAL, // Default is "verbose"
24 | RoboLogLevel::SUCCESS => OutputInterface::VERBOSITY_NORMAL, // Same as "NOTICE"
25 | LogLevel::NOTICE => OutputInterface::VERBOSITY_NORMAL, // Default is "verbose"
26 | LogLevel::INFO => OutputInterface::VERBOSITY_VERBOSE, // Default is "very verbose"
27 | ];
28 | parent::__construct($output, $roboVerbosityOverrides);
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/ResultData.php:
--------------------------------------------------------------------------------
1 | exitCode = $exitCode;
37 | parent::__construct($message, $data);
38 | }
39 |
40 | /**
41 | * @param string $message
42 | * @param array $data
43 | *
44 | * @return static
45 | */
46 | public static function message($message, $data = [])
47 | {
48 | return new self(self::EXITCODE_OK, $message, $data);
49 | }
50 |
51 | /**
52 | * @param string $message
53 | * @param array $data
54 | *
55 | * @return static
56 | */
57 | public static function cancelled($message = '', $data = [])
58 | {
59 | return new ResultData(self::EXITCODE_USER_CANCEL, $message, $data);
60 | }
61 |
62 | /**
63 | * @return int
64 | */
65 | public function getExitCode()
66 | {
67 | return $this->exitCode;
68 | }
69 |
70 | /**
71 | * @return null|string
72 | */
73 | public function getOutputData()
74 | {
75 | if (!empty($this->message) && !isset($this['already-printed']) && isset($this['provide-outputdata'])) {
76 | return $this->message;
77 | }
78 | }
79 |
80 | /**
81 | * Indicate that the message in this data has already been displayed.
82 | */
83 | public function alreadyPrinted()
84 | {
85 | $this['already-printed'] = true;
86 | }
87 |
88 | /**
89 | * Opt-in to providing the result message as the output data
90 | */
91 | public function provideOutputdata()
92 | {
93 | $this['provide-outputdata'] = true;
94 | }
95 |
96 | /**
97 | * @return bool
98 | */
99 | public function wasSuccessful()
100 | {
101 | return $this->exitCode === self::EXITCODE_OK;
102 | }
103 |
104 | /**
105 | * @return bool
106 | */
107 | public function wasCancelled()
108 | {
109 | return $this->exitCode == self::EXITCODE_USER_CANCEL;
110 | }
111 | }
112 |
--------------------------------------------------------------------------------
/src/State/Consumer.php:
--------------------------------------------------------------------------------
1 | state;
23 | }
24 |
25 | public function setState(Data $state)
26 | {
27 | $this->state = $state;
28 | }
29 |
30 | /**
31 | * @param int|string $key
32 | * @param mixed $value
33 | */
34 | public function setStateValue($key, $value)
35 | {
36 | $this->state[$key] = $value;
37 | }
38 |
39 | public function updateState(Data $update)
40 | {
41 | $this->state->update($update);
42 | }
43 |
44 | public function resetState()
45 | {
46 | $this->state = new Data();
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/src/Symfony/ConsoleIO.php:
--------------------------------------------------------------------------------
1 | input = $input;
26 | $this->output = $output;
27 | parent::__construct($input, $output);
28 | }
29 |
30 | public function input()
31 | {
32 | return $this->input;
33 | }
34 |
35 | public function output()
36 | {
37 | return $this->output;
38 | }
39 |
40 | /**
41 | * @param string $text
42 | */
43 | public function say($text)
44 | {
45 | $char = $this->decorationCharacter('>', '➜');
46 | $this->writeln("$char $text");
47 | }
48 |
49 | /**
50 | * @param string $text
51 | * @param int $length
52 | * @param string $color
53 | */
54 | public function yell($text, $length = 40, $color = 'green')
55 | {
56 | $char = $this->decorationCharacter(' ', '➜');
57 | $format = "$char %s";
58 | $this->formattedOutput($text, $length, $format);
59 | }
60 |
61 | /**
62 | * @param string $text
63 | * @param int $length
64 | * @param string $format
65 | */
66 | protected function formattedOutput($text, $length, $format)
67 | {
68 | $lines = explode("\n", trim($text, "\n"));
69 | $maxLineLength = array_reduce(array_map('strlen', $lines), 'max');
70 | $length = max($length, $maxLineLength);
71 | $len = $length + 2;
72 | $space = str_repeat(' ', $len);
73 | $this->writeln(sprintf($format, $space));
74 | foreach ($lines as $line) {
75 | $line = str_pad($line, $length, ' ', STR_PAD_BOTH);
76 | $this->writeln(sprintf($format, " $line "));
77 | }
78 | $this->writeln(sprintf($format, $space));
79 | }
80 |
81 | /**
82 | * @param string $nonDecorated
83 | * @param string $decorated
84 | *
85 | * @return string
86 | */
87 | protected function decorationCharacter($nonDecorated, $decorated)
88 | {
89 | if (!$this->output()->isDecorated() || (strncasecmp(PHP_OS, 'WIN', 3) == 0)) {
90 | return $nonDecorated;
91 | }
92 | return $decorated;
93 | }
94 |
95 | /**
96 | * {@inheritdoc}
97 | */
98 | public function lightText($message)
99 | {
100 | $this->block($message, '', 'fg=gray', '', true);
101 | }
102 |
103 | /**
104 | * {@inheritdoc}
105 | */
106 | public function injectDependencies($child)
107 | {
108 | if ($child instanceof InputAwareInterface) {
109 | $child->setInput($this->input());
110 | }
111 | if ($child instanceof OutputAwareInterface) {
112 | $child->setOutput($this->output());
113 | }
114 | }
115 | }
116 |
--------------------------------------------------------------------------------
/src/Symfony/ConsoleIOInjector.php:
--------------------------------------------------------------------------------
1 | input(), $commandData->output());
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/Symfony/SymfonyStyleInjector.php:
--------------------------------------------------------------------------------
1 | input(), $commandData->output());
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/Task/ApiGen/Tasks.php:
--------------------------------------------------------------------------------
1 | task(ApiGen::class, $pathToApiGen);
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/Task/Archive/Tasks.php:
--------------------------------------------------------------------------------
1 | task(Pack::class, $filename);
15 | }
16 |
17 | /**
18 | * @param string $filename
19 | *
20 | * @return \Robo\Task\Archive\Extract|\Robo\Collection\CollectionBuilder
21 | */
22 | protected function taskExtract($filename)
23 | {
24 | return $this->task(Extract::class, $filename);
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/Task/Assets/Less.php:
--------------------------------------------------------------------------------
1 | taskLess([
13 | * 'less/default.less' => 'css/default.css'
14 | * ])
15 | * ->run();
16 | * ?>
17 | * ```
18 | *
19 | * Use one of both less compilers in your project:
20 | *
21 | * ```
22 | * "leafo/lessphp": "~0.5",
23 | * "oyejorge/less.php": "~1.5"
24 | * ```
25 | *
26 | * Specify directory (string or array) for less imports lookup:
27 | *
28 | * ```php
29 | * taskLess([
31 | * 'less/default.less' => 'css/default.css'
32 | * ])
33 | * ->importDir('less')
34 | * ->compiler('lessphp')
35 | * ->run();
36 | * ?>
37 | * ```
38 | *
39 | * You can implement additional compilers by extending this task and adding a
40 | * method named after them and overloading the lessCompilers() method to
41 | * inject the name there.
42 | */
43 | class Less extends CssPreprocessor
44 | {
45 | const FORMAT_NAME = 'less';
46 |
47 | /**
48 | * @var string[]
49 | */
50 | protected $compilers = [
51 | 'less', // https://github.com/oyejorge/less.php
52 | 'lessphp', //https://github.com/leafo/lessphp
53 | ];
54 |
55 | /**
56 | * lessphp compiler
57 | * @link https://github.com/leafo/lessphp
58 | *
59 | * @param string $file
60 | *
61 | * @return string
62 | */
63 | protected function lessphp($file)
64 | {
65 | if (!class_exists('\lessc')) {
66 | return Result::errorMissingPackage($this, 'lessc', 'leafo/lessphp');
67 | }
68 |
69 | $lessCode = file_get_contents($file);
70 |
71 | $less = new \lessc();
72 | if (isset($this->compilerOptions['importDirs'])) {
73 | $less->setImportDir($this->compilerOptions['importDirs']);
74 | }
75 |
76 | return $less->compile($lessCode);
77 | }
78 |
79 | /**
80 | * less compiler
81 | * @link https://github.com/oyejorge/less.php
82 | *
83 | * @param string $file
84 | *
85 | * @return string
86 | */
87 | protected function less($file)
88 | {
89 | if (!class_exists('\Less_Parser')) {
90 | return Result::errorMissingPackage($this, 'Less_Parser', 'oyejorge/less.php');
91 | }
92 |
93 | $lessCode = file_get_contents($file);
94 |
95 | $parser = new \Less_Parser();
96 | $parser->SetOptions($this->compilerOptions);
97 | if (isset($this->compilerOptions['importDirs'])) {
98 | $importDirs = [];
99 | foreach ($this->compilerOptions['importDirs'] as $dir) {
100 | $importDirs[$dir] = $dir;
101 | }
102 | $parser->SetImportDirs($importDirs);
103 | }
104 |
105 | $parser->parse($lessCode);
106 |
107 | return $parser->getCss();
108 | }
109 | }
110 |
--------------------------------------------------------------------------------
/src/Task/Assets/Scss.php:
--------------------------------------------------------------------------------
1 | taskScss([
13 | * 'scss/default.scss' => 'css/default.css'
14 | * ])
15 | * ->importDir('assets/styles')
16 | * ->run();
17 | * ?>
18 | * ```
19 | *
20 | * Use the following scss compiler in your project:
21 | *
22 | * ```
23 | * "scssphp/scssphp ": "~1.0.0",
24 | * ```
25 | *
26 | * You can implement additional compilers by extending this task and adding a
27 | * method named after them and overloading the scssCompilers() method to
28 | * inject the name there.
29 | */
30 | class Scss extends CssPreprocessor
31 | {
32 | const FORMAT_NAME = 'scss';
33 |
34 | /**
35 | * @var string[]
36 | */
37 | protected $compilers = [
38 | 'scssphp', // https://github.com/scssphp/scssphp
39 | ];
40 |
41 | /**
42 | * scssphp compiler
43 | * @link https://github.com/scssphp/scssphp
44 | *
45 | * @param string $file
46 | *
47 | * @return string
48 | */
49 | protected function scssphp($file)
50 | {
51 | if (!class_exists('\ScssPhp\ScssPhp\Compiler')) {
52 | return Result::errorMissingPackage($this, 'scssphp', 'scssphp/scssphp');
53 | }
54 |
55 | $scssCode = file_get_contents($file);
56 | $scss = new \ScssPhp\ScssPhp\Compiler();
57 |
58 | // set options for the scssphp compiler
59 | if (isset($this->compilerOptions['importDirs'])) {
60 | $scss->setImportPaths($this->compilerOptions['importDirs']);
61 | }
62 |
63 | if (isset($this->compilerOptions['formatter'])) {
64 | $scss->setFormatter($this->compilerOptions['formatter']);
65 | }
66 |
67 | return $scss->compile($scssCode);
68 | }
69 |
70 | /**
71 | * Sets the formatter for scssphp
72 | *
73 | * The method setFormatter($formatterName) sets the current formatter to $formatterName,
74 | * the name of a class as a string that implements the formatting interface. See the source
75 | * for ScssPhp\ScssPhp\Formatter\Expanded for an example.
76 | *
77 | * Five formatters are included with scssphp/scssphp:
78 | * - ScssPhp\ScssPhp\Formatter\Expanded
79 | * - ScssPhp\ScssPhp\Formatter\Nested (default)
80 | * - ScssPhp\ScssPhp\Formatter\Compressed
81 | * - ScssPhp\ScssPhp\Formatter\Compact
82 | * - ScssPhp\ScssPhp\Formatter\Crunched
83 | *
84 | * @link https://scssphp.github.io/scssphp/docs/#output-formatting
85 | *
86 | * @param string $formatterName
87 | *
88 | * @return $this
89 | */
90 | public function setFormatter($formatterName)
91 | {
92 | return parent::setFormatter($formatterName);
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/src/Task/Assets/Tasks.php:
--------------------------------------------------------------------------------
1 | task(Minify::class, $input);
15 | }
16 |
17 | /**
18 | * @param string|string[] $input
19 | *
20 | * @return \Robo\Task\Assets\ImageMinify|\Robo\Collection\CollectionBuilder
21 | */
22 | protected function taskImageMinify($input)
23 | {
24 | return $this->task(ImageMinify::class, $input);
25 | }
26 |
27 | /**
28 | * @param array $input
29 | *
30 | * @return \Robo\Task\Assets\Less|\Robo\Collection\CollectionBuilder
31 | */
32 | protected function taskLess($input)
33 | {
34 | return $this->task(Less::class, $input);
35 | }
36 |
37 | /**
38 | * @param array $input
39 | *
40 | * @return \Robo\Task\Assets\Scss|\Robo\Collection\CollectionBuilder
41 | */
42 | protected function taskScss($input)
43 | {
44 | return $this->task(Scss::class, $input);
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/src/Task/Base/Exec.php:
--------------------------------------------------------------------------------
1 | taskExec('compass')->arg('watch')->run();
21 | * // or use shortcut
22 | * $this->_exec('compass watch');
23 | *
24 | * $this->taskExec('compass watch')->background()->run();
25 | *
26 | * if ($this->taskExec('phpunit .')->run()->wasSuccessful()) {
27 | * $this->say('tests passed');
28 | * }
29 | *
30 | * ?>
31 | * ```
32 | */
33 | class Exec extends BaseTask implements CommandInterface, PrintedInterface, SimulatedInterface
34 | {
35 | use CommandReceiver;
36 | use ExecOneCommand;
37 |
38 | /**
39 | * @var static[]
40 | */
41 | protected static $instances = [];
42 |
43 | /**
44 | * @var string|\Robo\Contract\CommandInterface
45 | */
46 | protected $command;
47 |
48 | private static $isSetupStopRunningJob = false;
49 |
50 | /**
51 | * @param string|\Robo\Contract\CommandInterface $command
52 | */
53 | public function __construct($command)
54 | {
55 | $this->command = $this->receiveCommand($command);
56 |
57 | $this->setupStopRunningJobs();
58 | }
59 |
60 | private function setupStopRunningJobs()
61 | {
62 | if (self::$isSetupStopRunningJob === true) {
63 | return;
64 | }
65 |
66 | $stopRunningJobs = Closure::fromCallable(self::class.'::stopRunningJobs');
67 |
68 | if (function_exists('pcntl_signal')) {
69 | pcntl_signal(SIGTERM, $stopRunningJobs);
70 | }
71 |
72 | register_shutdown_function($stopRunningJobs);
73 |
74 | self::$isSetupStopRunningJob = true;
75 | }
76 |
77 | public function __destruct()
78 | {
79 | $this->stop();
80 | }
81 |
82 | /**
83 | * Executes command in background mode (asynchronously)
84 | *
85 | * @param bool $arg
86 | *
87 | * @return $this
88 | */
89 | public function background($arg = true)
90 | {
91 | self::$instances[] = $this;
92 | $this->background = $arg;
93 | return $this;
94 | }
95 |
96 | /**
97 | * {@inheritdoc}
98 | */
99 | protected function getCommandDescription()
100 | {
101 | return $this->getCommand();
102 | }
103 | /**
104 | * {@inheritdoc}
105 | */
106 | public function getCommand()
107 | {
108 | return trim($this->command . $this->arguments);
109 | }
110 |
111 | /**
112 | * {@inheritdoc}
113 | */
114 | public function simulate($context)
115 | {
116 | $this->printAction($context);
117 | }
118 |
119 | public static function stopRunningJobs()
120 | {
121 | foreach (self::$instances as $instance) {
122 | if ($instance) {
123 | unset($instance);
124 | }
125 | }
126 | }
127 |
128 | /**
129 | * {@inheritdoc}
130 | */
131 | public function run()
132 | {
133 | $this->hideProgressIndicator();
134 | // TODO: Symfony 4 requires that we supply the working directory.
135 | $result_data = $this->execute(Process::fromShellCommandline($this->getCommand(), getcwd()));
136 | $result = new Result(
137 | $this,
138 | $result_data->getExitCode(),
139 | $result_data->getMessage(),
140 | $result_data->getData()
141 | );
142 | $this->showProgressIndicator();
143 | return $result;
144 | }
145 | }
146 |
--------------------------------------------------------------------------------
/src/Task/Base/ExecStack.php:
--------------------------------------------------------------------------------
1 | taskExecStack()
14 | * ->stopOnFail()
15 | * ->exec('mkdir site')
16 | * ->exec('cd site')
17 | * ->run();
18 | *
19 | * ?>
20 | * ```
21 | */
22 | class ExecStack extends CommandStack
23 | {
24 | }
25 |
--------------------------------------------------------------------------------
/src/Task/Base/Shortcuts.php:
--------------------------------------------------------------------------------
1 | taskExec($command)->run();
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/Task/Base/SymfonyCommand.php:
--------------------------------------------------------------------------------
1 | taskSymfonyCommand(new \Codeception\Command\Run('run'))
18 | * ->arg('suite','acceptance')
19 | * ->opt('debug')
20 | * ->run();
21 | *
22 | * // Artisan Command
23 | * $this->taskSymfonyCommand(new ModelGeneratorCommand())
24 | * ->arg('name', 'User')
25 | * ->run();
26 | * ?>
27 | * ```
28 | */
29 | class SymfonyCommand extends BaseTask
30 | {
31 | /**
32 | * @var \Symfony\Component\Console\Command\Command
33 | */
34 | protected $command;
35 |
36 | /**
37 | * @var string[]
38 | */
39 | protected $input;
40 |
41 | public function __construct(Command $command)
42 | {
43 | $this->command = $command;
44 | $this->input = [];
45 | }
46 |
47 | /**
48 | * @param string $arg
49 | * @param string $value
50 | *
51 | * @return $this
52 | */
53 | public function arg($arg, $value)
54 | {
55 | $this->input[$arg] = $value;
56 | return $this;
57 | }
58 |
59 | public function opt($option, $value = null)
60 | {
61 | $this->input["--$option"] = $value;
62 | return $this;
63 | }
64 |
65 | /**
66 | * {@inheritdoc}
67 | */
68 | public function run()
69 | {
70 | $this->printTaskInfo('Running command {command}', ['command' => $this->command->getName()]);
71 | return new Result(
72 | $this,
73 | $this->command->run(new ArrayInput($this->input), $this->output())
74 | );
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/src/Task/Base/Tasks.php:
--------------------------------------------------------------------------------
1 | task(Exec::class, $command);
15 | }
16 |
17 | /**
18 | * @return \Robo\Task\Base\ExecStack|\Robo\Collection\CollectionBuilder
19 | */
20 | protected function taskExecStack()
21 | {
22 | return $this->task(ExecStack::class);
23 | }
24 |
25 | /**
26 | * @return \Robo\Task\Base\ParallelExec|\Robo\Collection\CollectionBuilder
27 | */
28 | protected function taskParallelExec()
29 | {
30 | return $this->task(ParallelExec::class);
31 | }
32 |
33 | /**
34 | * @param \Symfony\Component\Console\Command\Command $command
35 | *
36 | * @return \Robo\Task\Base\SymfonyCommand|\Robo\Collection\CollectionBuilder
37 | */
38 | protected function taskSymfonyCommand($command)
39 | {
40 | return $this->task(SymfonyCommand::class, $command);
41 | }
42 |
43 | /**
44 | * @return \Robo\Task\Base\Watch|\Robo\Collection\CollectionBuilder
45 | */
46 | protected function taskWatch()
47 | {
48 | return $this->task(Watch::class, $this);
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/src/Task/Base/Watch.php:
--------------------------------------------------------------------------------
1 | taskWatch()
18 | * ->monitor(
19 | * 'composer.json',
20 | * function() {
21 | * $this->taskComposerUpdate()->run();
22 | * }
23 | * )->monitor(
24 | * 'src',
25 | * function() {
26 | * $this->taskExec('phpunit')->run();
27 | * },
28 | * \Lurker\Event\FilesystemEvent::ALL
29 | * )->monitor(
30 | * 'migrations',
31 | * function() {
32 | * //do something
33 | * },
34 | * [
35 | * \Lurker\Event\FilesystemEvent::CREATE,
36 | * \Lurker\Event\FilesystemEvent::DELETE
37 | * ]
38 | * )->run();
39 | * ?>
40 | * ```
41 | *
42 | * Pass through the changed file to the callable function
43 | *
44 | * ```
45 | * $this
46 | * ->taskWatch()
47 | * ->monitor(
48 | * 'filename',
49 | * function ($event) {
50 | * $resource = $event->getResource();
51 | * ... do something with (string)$resource ...
52 | * },
53 | * FilesystemEvent::ALL
54 | * )
55 | * ->run();
56 | * ```
57 | *
58 | * The $event parameter is a [standard Symfony file resource object](https://api.symfony.com/3.1/Symfony/Component/Config/Resource/FileResource.html)
59 | */
60 | class Watch extends BaseTask
61 | {
62 | /**
63 | * @var \Closure
64 | */
65 | protected $closure;
66 |
67 | /**
68 | * @var array
69 | */
70 | protected $monitor = [];
71 |
72 | /**
73 | * @var object
74 | */
75 | protected $bindTo;
76 |
77 | /**
78 | * @param $bindTo
79 | */
80 | public function __construct($bindTo)
81 | {
82 | $this->bindTo = $bindTo;
83 | }
84 |
85 | /**
86 | * @param string|string[] $paths
87 | * @param \Closure $callable
88 | * @param int|int[] $events
89 | *
90 | * @return $this
91 | */
92 | public function monitor($paths, \Closure $callable, $events = 2)
93 | {
94 | $this->monitor[] = [(array)$paths, $callable, (array)$events];
95 | return $this;
96 | }
97 |
98 | /**
99 | * {@inheritdoc}
100 | */
101 | public function run()
102 | {
103 | if (!class_exists('Lurker\\ResourceWatcher')) {
104 | return Result::errorMissingPackage($this, 'ResourceWatcher', 'totten/lurkerlite');
105 | }
106 |
107 | $watcher = new ResourceWatcher();
108 |
109 | foreach ($this->monitor as $k => $monitor) {
110 | /** @var \Closure $closure */
111 | $closure = $monitor[1];
112 | $closure->bindTo($this->bindTo);
113 | foreach ($monitor[0] as $i => $dir) {
114 | foreach ($monitor[2] as $j => $event) {
115 | $watcher->track("fs.$k.$i.$j", $dir, $event);
116 | $watcher->addListener("fs.$k.$i.$j", $closure);
117 | }
118 | $this->printTaskInfo('Watching {dir} for changes...', ['dir' => $dir]);
119 | }
120 | }
121 |
122 | $watcher->start();
123 | return Result::success($this);
124 | }
125 | }
126 |
--------------------------------------------------------------------------------
/src/Task/BaseTask.php:
--------------------------------------------------------------------------------
1 | logger) {
52 | $child->setLogger($this->logger);
53 | }
54 | if ($child instanceof OutputAwareInterface) {
55 | $child->setOutput($this->output());
56 | }
57 | if ($child instanceof ProgressIndicatorAwareInterface && $this->progressIndicator) {
58 | $child->setProgressIndicator($this->progressIndicator);
59 | }
60 | if ($child instanceof ConfigAwareInterface && $this->getConfig()) {
61 | $child->setConfig($this->getConfig());
62 | }
63 | if ($child instanceof VerbosityThresholdInterface && $this->outputAdapter()) {
64 | $child->setOutputAdapter($this->outputAdapter());
65 | }
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/src/Task/Bower/Base.php:
--------------------------------------------------------------------------------
1 | option('allow-root');
36 | return $this;
37 | }
38 |
39 | /**
40 | * adds `force-latest` option to bower
41 | *
42 | * @return $this
43 | */
44 | public function forceLatest()
45 | {
46 | $this->option('force-latest');
47 | return $this;
48 | }
49 |
50 | /**
51 | * adds `production` option to bower
52 | *
53 | * @return $this
54 | */
55 | public function noDev()
56 | {
57 | $this->option('production');
58 | return $this;
59 | }
60 |
61 | /**
62 | * adds `offline` option to bower
63 | *
64 | * @return $this
65 | */
66 | public function offline()
67 | {
68 | $this->option('offline');
69 | return $this;
70 | }
71 |
72 | /**
73 | * Base constructor.
74 | *
75 | * @param null|string $pathToBower
76 | *
77 | * @throws \Robo\Exception\TaskException
78 | */
79 | public function __construct($pathToBower = null)
80 | {
81 | $this->command = $pathToBower;
82 | if (!$this->command) {
83 | $this->command = $this->findExecutable('bower');
84 | }
85 | if (!$this->command) {
86 | throw new TaskException(__CLASS__, "Bower executable not found.");
87 | }
88 | }
89 |
90 | /**
91 | * @return string
92 | */
93 | public function getCommand()
94 | {
95 | return "{$this->command} {$this->action}{$this->arguments}";
96 | }
97 | }
98 |
--------------------------------------------------------------------------------
/src/Task/Bower/Install.php:
--------------------------------------------------------------------------------
1 | taskBowerInstall()->run();
14 | *
15 | * // prefer dist with custom path
16 | * $this->taskBowerInstall('path/to/my/bower')
17 | * ->noDev()
18 | * ->run();
19 | * ?>
20 | * ```
21 | */
22 | class Install extends Base implements CommandInterface
23 | {
24 | /**
25 | * {@inheritdoc}
26 | */
27 | protected $action = 'install';
28 |
29 | /**
30 | * {@inheritdoc}
31 | */
32 | public function run()
33 | {
34 | $this->printTaskInfo('Install Bower packages: {arguments}', ['arguments' => $this->arguments]);
35 | return $this->executeCommand($this->getCommand());
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/Task/Bower/Tasks.php:
--------------------------------------------------------------------------------
1 | task(Install::class, $pathToBower);
15 | }
16 |
17 | /**
18 | * @param null|string $pathToBower
19 | *
20 | * @return \Robo\Task\Bower\Update|\Robo\Collection\CollectionBuilder
21 | */
22 | protected function taskBowerUpdate($pathToBower = null)
23 | {
24 | return $this->task(Update::class, $pathToBower);
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/Task/Bower/Update.php:
--------------------------------------------------------------------------------
1 | taskBowerUpdate->run();
12 | *
13 | * // prefer dist with custom path
14 | * $this->taskBowerUpdate('path/to/my/bower')
15 | * ->noDev()
16 | * ->run();
17 | * ?>
18 | * ```
19 | */
20 | class Update extends Base
21 | {
22 | /**
23 | * {@inheritdoc}
24 | */
25 | protected $action = 'update';
26 |
27 | /**
28 | * {@inheritdoc}
29 | */
30 | public function run()
31 | {
32 | $this->printTaskInfo('Update Bower packages: {arguments}', ['arguments' => $this->arguments]);
33 | return $this->executeCommand($this->getCommand());
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/Task/Composer/CheckPlatformReqs.php:
--------------------------------------------------------------------------------
1 | taskComposerValidate()->run();
12 | * ?>
13 | * ```
14 | */
15 | class CheckPlatformReqs extends Base
16 | {
17 | /**
18 | * {@inheritdoc}
19 | */
20 | protected $action = 'check-platform-reqs';
21 |
22 | /**
23 | * {@inheritdoc}
24 | */
25 | public function run()
26 | {
27 | $command = $this->getCommand();
28 | $this->printTaskInfo('Checking platform requirements: {command}', ['command' => $command]);
29 | return $this->executeCommand($command);
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/Task/Composer/Config.php:
--------------------------------------------------------------------------------
1 | taskComposerConfig()->set('bin-dir', 'bin/')->run();
12 | * ?>
13 | * ```
14 | */
15 | class Config extends Base
16 | {
17 | /**
18 | * {@inheritdoc}
19 | */
20 | protected $action = 'config';
21 |
22 | /**
23 | * Set a configuration value.
24 | *
25 | * @param string $key
26 | * @param string $value
27 | *
28 | * @return $this
29 | */
30 | public function set($key, $value)
31 | {
32 | $this->arg($key);
33 | $this->arg($value);
34 | return $this;
35 | }
36 |
37 | /**
38 | * Operate on the global repository
39 | *
40 | * @param bool $useGlobal
41 | *
42 | * @return $this
43 | */
44 | public function useGlobal($useGlobal = true)
45 | {
46 | if ($useGlobal) {
47 | $this->option('global');
48 | }
49 | return $this;
50 | }
51 |
52 | /**
53 | * @param string $id
54 | * @param string $uri
55 | * @param string $repoType
56 | *
57 | * @return $this
58 | */
59 | public function repository($id, $uri, $repoType = 'vcs')
60 | {
61 | $this->arg("repositories.$id");
62 | $this->arg($repoType);
63 | $this->arg($uri);
64 | return $this;
65 | }
66 |
67 | /**
68 | * @param string $id
69 | *
70 | * @return $this
71 | */
72 | public function removeRepository($id)
73 | {
74 | $this->option('unset', "repositories.$id");
75 | return $this;
76 | }
77 |
78 | /**
79 | * @param string $id
80 | *
81 | * @return $this
82 | */
83 | public function disableRepository($id)
84 | {
85 | $this->arg("repositories.$id");
86 | $this->arg('false');
87 | return $this;
88 | }
89 |
90 | /**
91 | * @param string $id
92 | *
93 | * @return $this
94 | */
95 | public function enableRepository($id)
96 | {
97 | $this->arg("repositories.$id");
98 | $this->arg('true');
99 | return $this;
100 | }
101 |
102 | /**
103 | * {@inheritdoc}
104 | */
105 | public function run()
106 | {
107 | $command = $this->getCommand();
108 | $this->printTaskInfo('Configuring composer.json: {command}', ['command' => $command]);
109 | return $this->executeCommand($command);
110 | }
111 | }
112 |
--------------------------------------------------------------------------------
/src/Task/Composer/CreateProject.php:
--------------------------------------------------------------------------------
1 | taskComposerCreateProject()->source('foo/bar')->target('myBar')->run();
12 | * ?>
13 | * ```
14 | */
15 | class CreateProject extends Base
16 | {
17 | /**
18 | * {@inheritdoc}
19 | */
20 | protected $action = 'create-project';
21 |
22 | /**
23 | * @var
24 | */
25 | protected $source;
26 |
27 | /**
28 | * @var string
29 | */
30 | protected $target = '';
31 |
32 | /**
33 | * @var string
34 | */
35 | protected $version = '';
36 |
37 | /**
38 | * @param string $source
39 | *
40 | * @return $this
41 | */
42 | public function source($source)
43 | {
44 | $this->source = $source;
45 | return $this;
46 | }
47 |
48 | /**
49 | * @param string $target
50 | *
51 | * @return $this
52 | */
53 | public function target($target)
54 | {
55 | $this->target = $target;
56 | return $this;
57 | }
58 |
59 | /**
60 | * @param string $version
61 | *
62 | * @return $this
63 | */
64 | public function version($version)
65 | {
66 | $this->version = $version;
67 | return $this;
68 | }
69 |
70 | /**
71 | * @param bool $keep
72 | *
73 | * @return $this
74 | */
75 | public function keepVcs($keep = true)
76 | {
77 | if ($keep) {
78 | $this->option('--keep-vcs');
79 | }
80 | return $this;
81 | }
82 |
83 | /**
84 | * @param bool $noInstall
85 | *
86 | * @return $this
87 | */
88 | public function noInstall($noInstall = true)
89 | {
90 | if ($noInstall) {
91 | $this->option('--no-install');
92 | }
93 | return $this;
94 | }
95 |
96 | /**
97 | * @param string $repository
98 | *
99 | * @return $this
100 | */
101 | public function repository($repository)
102 | {
103 | if (!empty($repository)) {
104 | $this->option('repository', $repository);
105 | }
106 | return $this;
107 | }
108 |
109 | /**
110 | * @param string $stability
111 | *
112 | * @return $this
113 | */
114 | public function stability($stability)
115 | {
116 | if (!empty($stability)) {
117 | $this->option('stability', $stability);
118 | }
119 | return $this;
120 | }
121 |
122 | /**
123 | * {@inheritdoc}
124 | */
125 | public function buildCommand()
126 | {
127 | $this->arg($this->source);
128 | if (!empty($this->target)) {
129 | $this->arg($this->target);
130 | }
131 | if (!empty($this->version)) {
132 | $this->arg($this->version);
133 | }
134 |
135 | return parent::buildCommand();
136 | }
137 |
138 | /**
139 | * {@inheritdoc}
140 | */
141 | public function run()
142 | {
143 | $command = $this->getCommand();
144 | $this->printTaskInfo('Creating project: {command}', ['command' => $command]);
145 | return $this->executeCommand($command);
146 | }
147 | }
148 |
--------------------------------------------------------------------------------
/src/Task/Composer/DumpAutoload.php:
--------------------------------------------------------------------------------
1 | taskComposerDumpAutoload()->run();
12 | *
13 | * // dump auto loader with custom path
14 | * $this->taskComposerDumpAutoload('path/to/my/composer.phar')
15 | * ->preferDist()
16 | * ->run();
17 | *
18 | * // optimize autoloader dump with custom path
19 | * $this->taskComposerDumpAutoload('path/to/my/composer.phar')
20 | * ->optimize()
21 | * ->run();
22 | *
23 | * // optimize autoloader dump with custom path and no dev
24 | * $this->taskComposerDumpAutoload('path/to/my/composer.phar')
25 | * ->optimize()
26 | * ->noDev()
27 | * ->run();
28 | * ?>
29 | * ```
30 | */
31 | class DumpAutoload extends Base
32 | {
33 | /**
34 | * {@inheritdoc}
35 | */
36 | protected $action = 'dump-autoload';
37 |
38 | /**
39 | * @var string
40 | */
41 | protected $optimize;
42 |
43 | /**
44 | * @param bool $optimize
45 | *
46 | * @return $this
47 | */
48 | public function optimize($optimize = true)
49 | {
50 | if ($optimize) {
51 | $this->option("--optimize");
52 | }
53 | return $this;
54 | }
55 |
56 | /**
57 | * {@inheritdoc}
58 | */
59 | public function run()
60 | {
61 | $command = $this->getCommand();
62 | $this->printTaskInfo('Dumping Autoloader: {command}', ['command' => $command]);
63 | return $this->executeCommand($command);
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/src/Task/Composer/Init.php:
--------------------------------------------------------------------------------
1 | taskComposerInit()->run();
12 | * ?>
13 | * ```
14 | */
15 | class Init extends Base
16 | {
17 | /**
18 | * {@inheritdoc}
19 | */
20 | protected $action = 'init';
21 |
22 | /**
23 | * @param string $projectName
24 | *
25 | * @return $this
26 | */
27 | public function projectName($projectName)
28 | {
29 | $this->option('name', $projectName);
30 | return $this;
31 | }
32 |
33 | /**
34 | * @param string $description
35 | *
36 | * @return $this
37 | */
38 | public function description($description)
39 | {
40 | $this->option('description', $description);
41 | return $this;
42 | }
43 |
44 | /**
45 | * @param string $author
46 | *
47 | * @return $this
48 | */
49 | public function author($author)
50 | {
51 | $this->option('author', $author);
52 | return $this;
53 | }
54 |
55 | /**
56 | * @param string $type
57 | *
58 | * @return $this
59 | */
60 | public function projectType($type)
61 | {
62 | $this->option('type', $type);
63 | return $this;
64 | }
65 |
66 | /**
67 | * @param string $homepage
68 | *
69 | * @return $this
70 | */
71 | public function homepage($homepage)
72 | {
73 | $this->option('homepage', $homepage);
74 | return $this;
75 | }
76 |
77 | /**
78 | * 'require' is a keyword, so it cannot be a method name.
79 | *
80 | * @param string $project
81 | * @param null|string $version
82 | *
83 | * @return $this
84 | */
85 | public function dependency($project, $version = null)
86 | {
87 | if (isset($version)) {
88 | $project .= ":$version";
89 | }
90 | $this->option('require', $project);
91 | return $this;
92 | }
93 |
94 | /**
95 | * @param string $stability
96 | *
97 | * @return $this
98 | */
99 | public function stability($stability)
100 | {
101 | $this->option('stability', $stability);
102 | return $this;
103 | }
104 |
105 | /**
106 | * @param string $license
107 | *
108 | * @return $this
109 | */
110 | public function license($license)
111 | {
112 | $this->option('license', $license);
113 | return $this;
114 | }
115 |
116 | /**
117 | * @param string $repository
118 | *
119 | * @return $this
120 | */
121 | public function repository($repository)
122 | {
123 | $this->option('repository', $repository);
124 | return $this;
125 | }
126 |
127 | /**
128 | * {@inheritdoc}
129 | */
130 | public function run()
131 | {
132 | $command = $this->getCommand();
133 | $this->printTaskInfo('Creating composer.json: {command}', ['command' => $command]);
134 | return $this->executeCommand($command);
135 | }
136 | }
137 |
--------------------------------------------------------------------------------
/src/Task/Composer/Install.php:
--------------------------------------------------------------------------------
1 | taskComposerInstall()->run();
12 | *
13 | * // prefer dist with custom path
14 | * $this->taskComposerInstall('path/to/my/composer.phar')
15 | * ->preferDist()
16 | * ->run();
17 | *
18 | * // optimize autoloader with custom path
19 | * $this->taskComposerInstall('path/to/my/composer.phar')
20 | * ->optimizeAutoloader()
21 | * ->run();
22 | * ?>
23 | * ```
24 | */
25 | class Install extends Base
26 | {
27 | /**
28 | * {@inheritdoc}
29 | */
30 | protected $action = 'install';
31 |
32 | /**
33 | * adds `no-suggest` option to composer
34 | *
35 | * @param bool $noSuggest
36 | *
37 | * @return $this
38 | */
39 | public function noSuggest($noSuggest = true)
40 | {
41 | $this->option('--no-suggest');
42 | return $this;
43 | }
44 |
45 | /**
46 | * {@inheritdoc}
47 | */
48 | public function run()
49 | {
50 | $command = $this->getCommand();
51 | $this->printTaskInfo('Installing Packages: {command}', ['command' => $command]);
52 | return $this->executeCommand($command);
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/src/Task/Composer/Remove.php:
--------------------------------------------------------------------------------
1 | taskComposerRemove()->run();
12 | * ?>
13 | * ```
14 | */
15 | class Remove extends Base
16 | {
17 | /**
18 | * {@inheritdoc}
19 | */
20 | protected $action = 'remove';
21 |
22 | /**
23 | * 'remove' is a keyword, so it cannot be a method name.
24 | *
25 | * @param array|string $project
26 | *
27 | * @return $this
28 | */
29 | public function dependency(array|string $project): self
30 | {
31 | $project = (array)$project;
32 | $this->args($project);
33 | return $this;
34 | }
35 |
36 | /**
37 | * @param bool $dev
38 | *
39 | * @return $this
40 | */
41 | public function dev($dev = true)
42 | {
43 | if ($dev) {
44 | $this->option('--dev');
45 | }
46 | return $this;
47 | }
48 |
49 | /**
50 | * @param bool $noProgress
51 | *
52 | * @return $this
53 | */
54 | public function noProgress($noProgress = true)
55 | {
56 | if ($noProgress) {
57 | $this->option('--no-progress');
58 | }
59 | return $this;
60 | }
61 |
62 | /**
63 | * @param bool $noUpdate
64 | *
65 | * @return $this
66 | */
67 | public function noUpdate($noUpdate = true)
68 | {
69 | if ($noUpdate) {
70 | $this->option('--no-update');
71 | }
72 | return $this;
73 | }
74 |
75 | /**
76 | * @param bool $updateNoDev
77 | *
78 | * @return $this
79 | */
80 | public function updateNoDev($updateNoDev = true)
81 | {
82 | if ($updateNoDev) {
83 | $this->option('--update-no-dev');
84 | }
85 | return $this;
86 | }
87 |
88 | /**
89 | * @param bool $updateWithDependencies
90 | *
91 | * @return $this
92 | */
93 | public function noUpdateWithDependencies($updateWithDependencies = true)
94 | {
95 | if ($updateWithDependencies) {
96 | $this->option('--no-update-with-dependencies');
97 | }
98 | return $this;
99 | }
100 |
101 | /**
102 | * {@inheritdoc}
103 | */
104 | public function run()
105 | {
106 | $command = $this->getCommand();
107 | $this->printTaskInfo('Removing packages: {command}', ['command' => $command]);
108 | return $this->executeCommand($command);
109 | }
110 | }
111 |
--------------------------------------------------------------------------------
/src/Task/Composer/RequireDependency.php:
--------------------------------------------------------------------------------
1 | taskComposerRequire()->dependency('foo/bar', '^.2.4.8')->run();
12 | * ?>
13 | * ```
14 | */
15 | class RequireDependency extends Base
16 | {
17 | /**
18 | * {@inheritdoc}
19 | */
20 | protected $action = 'require';
21 |
22 | /**
23 | * 'require' is a keyword, so it cannot be a method name.
24 | *
25 | * @param string $project
26 | * @param null|string $version
27 | *
28 | * @return $this
29 | */
30 | public function dependency($project, $version = null)
31 | {
32 | $project = (array)$project;
33 |
34 | if (isset($version)) {
35 | $project = array_map(
36 | function ($item) use ($version) {
37 | return "$item:$version";
38 | },
39 | $project
40 | );
41 | }
42 | $this->args($project);
43 | return $this;
44 | }
45 |
46 | /**
47 | * adds `no-suggest` option to composer
48 | *
49 | * @param bool $noSuggest
50 | *
51 | * @return $this
52 | */
53 | public function noSuggest($noSuggest = true)
54 | {
55 | $this->option('--no-suggest');
56 | return $this;
57 | }
58 |
59 | /**
60 | * adds `no-update` option to composer
61 | *
62 | * @return $this
63 | */
64 | public function noUpdate(): self
65 | {
66 | $this->option('--no-update');
67 | return $this;
68 | }
69 |
70 | /**
71 | * {@inheritdoc}
72 | */
73 | public function run()
74 | {
75 | $command = $this->getCommand();
76 | $this->printTaskInfo('Requiring packages: {command}', ['command' => $command]);
77 | return $this->executeCommand($command);
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/src/Task/Composer/Tasks.php:
--------------------------------------------------------------------------------
1 | task(Install::class, $pathToComposer);
15 | }
16 |
17 | /**
18 | * @param null|string $pathToComposer
19 | *
20 | * @return \Robo\Task\Composer\Update|\Robo\Collection\CollectionBuilder
21 | */
22 | protected function taskComposerUpdate($pathToComposer = null)
23 | {
24 | return $this->task(Update::class, $pathToComposer);
25 | }
26 |
27 | /**
28 | * @param null|string $pathToComposer
29 | *
30 | * @return \Robo\Task\Composer\DumpAutoload|\Robo\Collection\CollectionBuilder
31 | */
32 | protected function taskComposerDumpAutoload($pathToComposer = null)
33 | {
34 | return $this->task(DumpAutoload::class, $pathToComposer);
35 | }
36 |
37 | /**
38 | * @param null|string $pathToComposer
39 | *
40 | * @return \Robo\Task\Composer\Init|\Robo\Collection\CollectionBuilder
41 | */
42 | protected function taskComposerInit($pathToComposer = null)
43 | {
44 | return $this->task(Init::class, $pathToComposer);
45 | }
46 |
47 | /**
48 | * @param null|string $pathToComposer
49 | *
50 | * @return \Robo\Task\Composer\Config|\Robo\Collection\CollectionBuilder
51 | */
52 | protected function taskComposerConfig($pathToComposer = null)
53 | {
54 | return $this->task(Config::class, $pathToComposer);
55 | }
56 |
57 | /**
58 | * @param null|string $pathToComposer
59 | *
60 | * @return \Robo\Task\Composer\Validate|\Robo\Collection\CollectionBuilder
61 | */
62 | protected function taskComposerValidate($pathToComposer = null)
63 | {
64 | return $this->task(Validate::class, $pathToComposer);
65 | }
66 |
67 | /**
68 | * @param null|string $pathToComposer
69 | *
70 | * @return \Robo\Task\Composer\Remove|\Robo\Collection\CollectionBuilder
71 | */
72 | protected function taskComposerRemove($pathToComposer = null)
73 | {
74 | return $this->task(Remove::class, $pathToComposer);
75 | }
76 |
77 | /**
78 | * @param null|string $pathToComposer
79 | *
80 | * @return \Robo\Task\Composer\RequireDependency|\Robo\Collection\CollectionBuilder
81 | */
82 | protected function taskComposerRequire($pathToComposer = null)
83 | {
84 | return $this->task(RequireDependency::class, $pathToComposer);
85 | }
86 |
87 | /**
88 | * @param null|string $pathToComposer
89 | *
90 | * @return \Robo\Task\Composer\CreateProject|\Robo\Collection\CollectionBuilder
91 | */
92 | protected function taskComposerCreateProject($pathToComposer = null)
93 | {
94 | return $this->task(CreateProject::class, $pathToComposer);
95 | }
96 |
97 | /**
98 | * @param null|string $pathToComposer
99 | *
100 | * @return \Robo\Task\Composer\CreateProject|\Robo\Collection\CollectionBuilder
101 | */
102 | protected function taskCheckPlatformReqs($pathToComposer = null)
103 | {
104 | return $this->task(CheckPlatformReqs::class, $pathToComposer);
105 | }
106 | }
107 |
--------------------------------------------------------------------------------
/src/Task/Composer/Update.php:
--------------------------------------------------------------------------------
1 | taskComposerUpdate()->run();
12 | *
13 | * // prefer dist with custom path
14 | * $this->taskComposerUpdate('path/to/my/composer.phar')
15 | * ->preferDist()
16 | * ->run();
17 | *
18 | * // optimize autoloader with custom path
19 | * $this->taskComposerUpdate('path/to/my/composer.phar')
20 | * ->optimizeAutoloader()
21 | * ->run();
22 | * ?>
23 | * ```
24 | */
25 | class Update extends Base
26 | {
27 | /**
28 | * {@inheritdoc}
29 | */
30 | protected $action = 'update';
31 |
32 | /**
33 | * adds `no-suggest` option to composer
34 | *
35 | * @param bool $noSuggest
36 | *
37 | * @return $this
38 | */
39 | public function noSuggest($noSuggest = true)
40 | {
41 | $this->option('--no-suggest');
42 | return $this;
43 | }
44 |
45 | /**
46 | * {@inheritdoc}
47 | */
48 | public function run()
49 | {
50 | $command = $this->getCommand();
51 | $this->printTaskInfo('Updating Packages: {command}', ['command' => $command]);
52 | return $this->executeCommand($command);
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/src/Task/Composer/Validate.php:
--------------------------------------------------------------------------------
1 | taskComposerValidate()->run();
12 | * ?>
13 | * ```
14 | */
15 | class Validate extends Base
16 | {
17 | /**
18 | * {@inheritdoc}
19 | */
20 | protected $action = 'validate';
21 |
22 | /**
23 | * @param bool $noCheckAll
24 | *
25 | * @return $this
26 | */
27 | public function noCheckAll($noCheckAll = true)
28 | {
29 | if ($noCheckAll) {
30 | $this->option('--no-check-all');
31 | }
32 | return $this;
33 | }
34 |
35 | /**
36 | * @param bool $noCheckLock
37 | *
38 | * @return $this
39 | */
40 | public function noCheckLock($noCheckLock = true)
41 | {
42 | if ($noCheckLock) {
43 | $this->option('--no-check-lock');
44 | }
45 | return $this;
46 | }
47 |
48 | /**
49 | * @param bool $noCheckPublish
50 | *
51 | * @return $this
52 | */
53 | public function noCheckPublish($noCheckPublish = true)
54 | {
55 | if ($noCheckPublish) {
56 | $this->option('--no-check-publish');
57 | }
58 | return $this;
59 | }
60 |
61 | /**
62 | * @param bool $withDependencies
63 | *
64 | * @return $this
65 | */
66 | public function withDependencies($withDependencies = true)
67 | {
68 | if ($withDependencies) {
69 | $this->option('--with-dependencies');
70 | }
71 | return $this;
72 | }
73 |
74 | /**
75 | * @param bool $strict
76 | *
77 | * @return $this
78 | */
79 | public function strict($strict = true)
80 | {
81 | if ($strict) {
82 | $this->option('--strict');
83 | }
84 | return $this;
85 | }
86 |
87 | /**
88 | * {@inheritdoc}
89 | */
90 | public function run()
91 | {
92 | $command = $this->getCommand();
93 | $this->printTaskInfo('Validating composer.json: {command}', ['command' => $command]);
94 | return $this->executeCommand($command);
95 | }
96 | }
97 |
--------------------------------------------------------------------------------
/src/Task/Development/GitHub.php:
--------------------------------------------------------------------------------
1 | repo = $repo;
45 | return $this;
46 | }
47 |
48 | /**
49 | * @param string $owner
50 | *
51 | * @return $this
52 | */
53 | public function owner($owner)
54 | {
55 | $this->owner = $owner;
56 | return $this;
57 | }
58 |
59 | /**
60 | * @param string $uri
61 | *
62 | * @return $this
63 | */
64 | public function uri($uri)
65 | {
66 | list($this->owner, $this->repo) = explode('/', $uri);
67 | return $this;
68 | }
69 |
70 | /**
71 | * @return string
72 | */
73 | protected function getUri()
74 | {
75 | return $this->owner . '/' . $this->repo;
76 | }
77 |
78 | /**
79 | * @param string $user
80 | *
81 | * @return $this
82 | */
83 | public function user($user)
84 | {
85 | $this->user = $user;
86 | return $this;
87 | }
88 |
89 | /**
90 | * @param string $password
91 | *
92 | * @return $this
93 | */
94 | public function password($password)
95 | {
96 | $this->password = $password;
97 | return $this;
98 | }
99 |
100 | /**
101 | * @param string $token
102 | *
103 | * @return $this
104 | */
105 | public function accessToken($token)
106 | {
107 | $this->accessToken = $token;
108 | return $this;
109 | }
110 |
111 | /**
112 | * @param string $uri
113 | * @param array $params
114 | * @param string $method
115 | *
116 | * @return array
117 | *
118 | * @throws \Robo\Exception\TaskException
119 | */
120 | protected function sendRequest($uri, $params = [], $method = 'POST')
121 | {
122 | if (!$this->owner or !$this->repo) {
123 | throw new TaskException($this, 'Repo URI is not set');
124 | }
125 |
126 | $ch = curl_init();
127 | $url = sprintf('%s/repos/%s/%s', self::GITHUB_URL, $this->getUri(), $uri);
128 | $this->printTaskInfo($url);
129 | $this->printTaskInfo('{method} {url}', ['method' => $method, 'url' => $url]);
130 |
131 | if (!empty($this->user)) {
132 | curl_setopt($ch, CURLOPT_USERPWD, $this->user . ':' . $this->password);
133 | }
134 |
135 | if (!empty($this->accessToken)) {
136 | curl_setopt($ch, CURLOPT_HTTPHEADER, ['Authorization: ' . sprintf('token %s', $this->accessToken)]);
137 | }
138 |
139 | curl_setopt_array(
140 | $ch,
141 | array(
142 | CURLOPT_URL => $url,
143 | CURLOPT_RETURNTRANSFER => true,
144 | CURLOPT_POST => $method != 'GET',
145 | CURLOPT_POSTFIELDS => json_encode($params),
146 | CURLOPT_FOLLOWLOCATION => true,
147 | CURLOPT_USERAGENT => "Robo"
148 | )
149 | );
150 |
151 | $output = curl_exec($ch);
152 | $code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
153 | $response = json_decode($output);
154 |
155 | $this->printTaskInfo($output);
156 | return [$code, $response];
157 | }
158 | }
159 |
--------------------------------------------------------------------------------
/src/Task/Development/OpenBrowser.php:
--------------------------------------------------------------------------------
1 | taskOpenBrowser('http://localhost')
17 | * ->run();
18 | *
19 | * // open two browser windows
20 | * $this->taskOpenBrowser([
21 | * 'http://localhost/mysite',
22 | * 'http://localhost/mysite2'
23 | * ])
24 | * ->run();
25 | * ```
26 | */
27 | class OpenBrowser extends BaseTask
28 | {
29 | /**
30 | * @var string[]
31 | */
32 | protected $urls = [];
33 |
34 | /**
35 | * @param string|string[] $url
36 | */
37 | public function __construct($url)
38 | {
39 | $this->urls = (array) $url;
40 | }
41 |
42 | /**
43 | * {@inheritdoc}
44 | */
45 | public function run()
46 | {
47 | $openCommand = $this->getOpenCommand();
48 |
49 | if (empty($openCommand)) {
50 | return Result::error($this, 'no suitable browser opening command found');
51 | }
52 |
53 | foreach ($this->urls as $url) {
54 | passthru(sprintf($openCommand, ProcessUtils::escapeArgument($url)));
55 | $this->printTaskInfo('Opened {url}', ['url' => $url]);
56 | }
57 |
58 | return Result::success($this);
59 | }
60 |
61 | /**
62 | * @return null|string
63 | */
64 | private function getOpenCommand()
65 | {
66 | if (defined('PHP_WINDOWS_VERSION_MAJOR')) {
67 | return 'start "web" explorer "%s"';
68 | }
69 |
70 | passthru('which xdg-open', $linux);
71 | passthru('which open', $osx);
72 |
73 | if (0 === $linux) {
74 | return 'xdg-open %s';
75 | }
76 |
77 | if (0 === $osx) {
78 | return 'open %s';
79 | }
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/src/Task/Development/PhpServer.php:
--------------------------------------------------------------------------------
1 | taskServer(8000)
14 | * ->dir('public')
15 | * ->run();
16 | *
17 | * // run with IP 0.0.0.0
18 | * $this->taskServer(8000)
19 | * ->host('0.0.0.0')
20 | * ->run();
21 | *
22 | * // execute server in background
23 | * $this->taskServer(8000)
24 | * ->background()
25 | * ->run();
26 | * ?>
27 | * ```
28 | */
29 | class PhpServer extends Exec
30 | {
31 | /**
32 | * @var int
33 | */
34 | protected $port;
35 |
36 | /**
37 | * @var string
38 | */
39 | protected $host = '127.0.0.1';
40 |
41 | /**
42 | * {@inheritdoc}
43 | */
44 | protected $command = 'php -S %s:%d ';
45 |
46 | /**
47 | * @param int $port
48 | */
49 | public function __construct($port)
50 | {
51 | $this->port = $port;
52 |
53 | if (strtolower(PHP_OS) === 'linux') {
54 | $this->command = 'exec php -S %s:%d ';
55 | }
56 | }
57 |
58 | /**
59 | * @param string $host
60 | *
61 | * @return $this
62 | */
63 | public function host($host)
64 | {
65 | $this->host = $host;
66 | return $this;
67 | }
68 |
69 | /**
70 | * @param string $path
71 | *
72 | * @return $this
73 | */
74 | public function dir($path)
75 | {
76 | $this->command .= "-t $path";
77 | return $this;
78 | }
79 |
80 | /**
81 | * {@inheritdoc}
82 | */
83 | public function getCommand()
84 | {
85 | return sprintf($this->command . $this->arguments, $this->host, $this->port);
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/src/Task/Development/Tasks.php:
--------------------------------------------------------------------------------
1 | task(Changelog::class, $filename);
15 | }
16 |
17 | /**
18 | * @param string $filename
19 | *
20 | * @return \Robo\Task\Development\GenerateMarkdownDoc|\Robo\Collection\CollectionBuilder
21 | */
22 | protected function taskGenDoc($filename)
23 | {
24 | return $this->task(GenerateMarkdownDoc::class, $filename);
25 | }
26 |
27 | /**
28 | * @param string $className
29 | * @param string $wrapperClassName
30 | *
31 | * @return \Robo\Task\Development\GenerateTask|\Robo\Collection\CollectionBuilder
32 | */
33 | protected function taskGenTask($className, $wrapperClassName = '')
34 | {
35 | return $this->task(GenerateTask::class, $className, $wrapperClassName);
36 | }
37 |
38 | /**
39 | * @param string $pathToSemVer
40 | *
41 | * @return \Robo\Task\Development\SemVer|\Robo\Collection\CollectionBuilder
42 | */
43 | protected function taskSemVer($pathToSemVer = '.semver')
44 | {
45 | return $this->task(SemVer::class, $pathToSemVer);
46 | }
47 |
48 | /**
49 | * @param int $port
50 | *
51 | * @return \Robo\Task\Development\PhpServer|\Robo\Collection\CollectionBuilder
52 | */
53 | protected function taskServer($port = 8000)
54 | {
55 | return $this->task(PhpServer::class, $port);
56 | }
57 |
58 | /**
59 | * @param string $filename
60 | *
61 | * @return \Robo\Task\Development\PackPhar|\Robo\Collection\CollectionBuilder
62 | */
63 | protected function taskPackPhar($filename)
64 | {
65 | return $this->task(PackPhar::class, $filename);
66 | }
67 |
68 | /**
69 | * @param string $tag
70 | *
71 | * @return \Robo\Task\Development\GitHubRelease|\Robo\Collection\CollectionBuilder
72 | */
73 | protected function taskGitHubRelease($tag)
74 | {
75 | return $this->task(GitHubRelease::class, $tag);
76 | }
77 |
78 | /**
79 | * @param string|array $url
80 | *
81 | * @return \Robo\Task\Development\OpenBrowser|\Robo\Collection\CollectionBuilder
82 | */
83 | protected function taskOpenBrowser($url)
84 | {
85 | return $this->task(OpenBrowser::class, $url);
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/src/Task/Docker/Base.php:
--------------------------------------------------------------------------------
1 | getCommand();
25 | return $this->executeCommand($command);
26 | }
27 |
28 | abstract public function getCommand();
29 | }
30 |
--------------------------------------------------------------------------------
/src/Task/Docker/Build.php:
--------------------------------------------------------------------------------
1 | taskDockerBuild()->run();
11 | *
12 | * $this->taskDockerBuild('path/to/dir')
13 | * ->tag('database')
14 | * ->run();
15 | *
16 | * ?>
17 | *
18 | * ```
19 | *
20 | * Class Build
21 | * @package Robo\Task\Docker
22 | */
23 | class Build extends Base
24 | {
25 | /**
26 | * @var string
27 | */
28 | protected $path;
29 |
30 | /**
31 | * @var bool
32 | */
33 | protected $buildKit = false;
34 |
35 | /**
36 | * @param string $path
37 | */
38 | public function __construct($path = '.')
39 | {
40 | $this->command = "docker build";
41 | $this->path = $path;
42 | }
43 |
44 | /**
45 | * {@inheritdoc}
46 | */
47 | public function getCommand()
48 | {
49 | $command = $this->command;
50 | if ($this->buildKit) {
51 | $command = 'DOCKER_BUILDKIT=1 ' . $command;
52 | }
53 | return $command . ' ' . $this->arguments . ' ' . $this->path;
54 | }
55 |
56 | /**
57 | * @param string $tag
58 | *
59 | * @return $this
60 | */
61 | public function tag($tag)
62 | {
63 | return $this->option('-t', $tag);
64 | }
65 |
66 | /**
67 | * @return $this
68 | */
69 | public function enableBuildKit()
70 | {
71 | $this->buildKit = true;
72 | return $this;
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/src/Task/Docker/Commit.php:
--------------------------------------------------------------------------------
1 | taskDockerCommit($containerId)
10 | * ->name('my/database')
11 | * ->run();
12 | *
13 | * // alternatively you can take the result from DockerRun task:
14 | *
15 | * $result = $this->taskDockerRun('db')
16 | * ->exec('./prepare_database.sh')
17 | * ->run();
18 | *
19 | * $task->dockerCommit($result)
20 | * ->name('my/database')
21 | * ->run();
22 | * ```
23 | */
24 | class Commit extends Base
25 | {
26 | /**
27 | * @var string
28 | */
29 | protected $command = "docker commit";
30 |
31 | /**
32 | * @var string
33 | */
34 | protected $name;
35 |
36 | /**
37 | * @var string
38 | */
39 | protected $cid;
40 |
41 | /**
42 | * @param string|\Robo\Task\Docker\Result $cidOrResult
43 | */
44 | public function __construct($cidOrResult)
45 | {
46 | $this->cid = $cidOrResult instanceof Result ? $cidOrResult->getCid() : $cidOrResult;
47 | }
48 |
49 | /**
50 | * {@inheritdoc}
51 | */
52 | public function getCommand()
53 | {
54 | return $this->command . ' ' . $this->cid . ' ' . $this->name . ' ' . $this->arguments;
55 | }
56 |
57 | /**
58 | * @param string $name
59 | *
60 | * @return $this
61 | */
62 | public function name($name)
63 | {
64 | $this->name = $name;
65 | return $this;
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/src/Task/Docker/Exec.php:
--------------------------------------------------------------------------------
1 | taskDockerRun('test_env')
13 | * ->detached()
14 | * ->run();
15 | *
16 | * $this->taskDockerExec($test)
17 | * ->interactive()
18 | * ->exec('./runtests')
19 | * ->run();
20 | *
21 | * // alternatively use commands from other tasks
22 | *
23 | * $this->taskDockerExec($test)
24 | * ->interactive()
25 | * ->exec($this->taskCodecept()->suite('acceptance'))
26 | * ->run();
27 | * ?>
28 | * ```
29 | *
30 | */
31 | class Exec extends Base
32 | {
33 | use CommandReceiver;
34 |
35 | /**
36 | * @var string
37 | */
38 | protected $command = "docker exec";
39 |
40 | /**
41 | * @var string
42 | */
43 | protected $cid;
44 |
45 | /**
46 | * @var string
47 | */
48 | protected $run = '';
49 |
50 | /**
51 | * @param string|\Robo\Result $cidOrResult
52 | */
53 | public function __construct($cidOrResult)
54 | {
55 | $this->cid = $cidOrResult instanceof Result ? $cidOrResult->getCid() : $cidOrResult;
56 | }
57 |
58 | /**
59 | * @return $this
60 | */
61 | public function detached()
62 | {
63 | $this->option('-d');
64 | return $this;
65 | }
66 |
67 | /**
68 | * {@inheritdoc}
69 | */
70 | public function interactive($interactive = true)
71 | {
72 | if ($interactive) {
73 | $this->option('-i');
74 | }
75 | return parent::interactive($interactive);
76 | }
77 |
78 | /**
79 | * @param string|\Robo\Contract\CommandInterface $command
80 | *
81 | * @return $this
82 | */
83 | public function exec($command)
84 | {
85 | $this->run = $this->receiveCommand($command);
86 | return $this;
87 | }
88 |
89 | /**
90 | * {@inheritdoc}
91 | */
92 | public function getCommand()
93 | {
94 | return $this->command . ' ' . $this->arguments . ' ' . $this->cid . ' ' . $this->run;
95 | }
96 | }
97 |
--------------------------------------------------------------------------------
/src/Task/Docker/Pull.php:
--------------------------------------------------------------------------------
1 | taskDockerPull('wordpress')
11 | * ->run();
12 | *
13 | * ?>
14 | * ```
15 | *
16 | */
17 | class Pull extends Base
18 | {
19 | /**
20 | * @param string $image
21 | */
22 | public function __construct($image)
23 | {
24 | $this->command = "docker pull $image ";
25 | }
26 |
27 | /**
28 | * {@inheritdoc}
29 | */
30 | public function getCommand()
31 | {
32 | return $this->command . ' ' . $this->arguments;
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/Task/Docker/Remove.php:
--------------------------------------------------------------------------------
1 | taskDockerRemove($container)
11 | * ->run();
12 | * ?>
13 | * ```
14 | *
15 | */
16 | class Remove extends Base
17 | {
18 | /**
19 | * @param string $container
20 | */
21 | public function __construct($container)
22 | {
23 | $this->command = "docker rm $container ";
24 | }
25 |
26 | /**
27 | * {@inheritdoc}
28 | */
29 | public function getCommand()
30 | {
31 | return $this->command . ' ' . $this->arguments;
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/Task/Docker/Result.php:
--------------------------------------------------------------------------------
1 | taskDockerStart($cidOrResult)
11 | * ->run();
12 | * ?>
13 | * ```
14 | */
15 | class Start extends Base
16 | {
17 | /**
18 | * @var string
19 | */
20 | protected $command = "docker start";
21 |
22 | /**
23 | * @var null|string
24 | */
25 | protected $cid;
26 |
27 | /**
28 | * @param string|\Robo\Task\Docker\Result $cidOrResult
29 | */
30 | public function __construct($cidOrResult)
31 | {
32 | $this->cid = $cidOrResult instanceof Result ? $cidOrResult->getCid() : $cidOrResult;
33 | }
34 |
35 | /**
36 | * {@inheritdoc}
37 | */
38 | public function getCommand()
39 | {
40 | return $this->command . ' ' . $this->arguments . ' ' . $this->cid;
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/Task/Docker/Stop.php:
--------------------------------------------------------------------------------
1 | taskDockerStop($cidOrResult)
11 | * ->run();
12 | * ?>
13 | * ```
14 | */
15 | class Stop extends Base
16 | {
17 | /**
18 | * @var string
19 | */
20 | protected $command = "docker stop";
21 |
22 | /**
23 | * @var null|string
24 | */
25 | protected $cid;
26 |
27 | /**
28 | * @param string|\Robo\Task\Docker\Result $cidOrResult
29 | */
30 | public function __construct($cidOrResult)
31 | {
32 | $this->cid = $cidOrResult instanceof Result ? $cidOrResult->getCid() : $cidOrResult;
33 | }
34 |
35 | /**
36 | * {@inheritdoc}
37 | */
38 | public function getCommand()
39 | {
40 | return $this->command . ' ' . $this->arguments . ' ' . $this->cid;
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/Task/Docker/Tasks.php:
--------------------------------------------------------------------------------
1 | task(Run::class, $image);
15 | }
16 |
17 | /**
18 | * @param string $image
19 | *
20 | * @return \Robo\Task\Docker\Pull|\Robo\Collection\CollectionBuilder
21 | */
22 | protected function taskDockerPull($image)
23 | {
24 | return $this->task(Pull::class, $image);
25 | }
26 |
27 | /**
28 | * @param string $path
29 | *
30 | * @return \Robo\Task\Docker\Build|\Robo\Collection\CollectionBuilder
31 | */
32 | protected function taskDockerBuild($path = '.')
33 | {
34 | return $this->task(Build::class, $path);
35 | }
36 |
37 | /**
38 | * @param string|\Robo\Task\Docker\Result $cidOrResult
39 | *
40 | * @return \Robo\Task\Docker\Stop|\Robo\Collection\CollectionBuilder
41 | */
42 | protected function taskDockerStop($cidOrResult)
43 | {
44 | return $this->task(Stop::class, $cidOrResult);
45 | }
46 |
47 | /**
48 | * @param string|\Robo\Task\Docker\Result $cidOrResult
49 | *
50 | * @return \Robo\Task\Docker\Commit|\Robo\Collection\CollectionBuilder
51 | */
52 | protected function taskDockerCommit($cidOrResult)
53 | {
54 | return $this->task(Commit::class, $cidOrResult);
55 | }
56 |
57 | /**
58 | * @param string|\Robo\Task\Docker\Result $cidOrResult
59 | *
60 | * @return \Robo\Task\Docker\Start|\Robo\Collection\CollectionBuilder
61 | */
62 | protected function taskDockerStart($cidOrResult)
63 | {
64 | return $this->task(Start::class, $cidOrResult);
65 | }
66 |
67 | /**
68 | * @param string|\Robo\Task\Docker\Result $cidOrResult
69 | *
70 | * @return \Robo\Task\Docker\Remove|\Robo\Collection\CollectionBuilder
71 | */
72 | protected function taskDockerRemove($cidOrResult)
73 | {
74 | return $this->task(Remove::class, $cidOrResult);
75 | }
76 |
77 | /**
78 | * @param string|\Robo\Task\Docker\Result $cidOrResult
79 | *
80 | * @return \Robo\Task\Docker\Exec|\Robo\Collection\CollectionBuilder
81 | */
82 | protected function taskDockerExec($cidOrResult)
83 | {
84 | return $this->task(Exec::class, $cidOrResult);
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/src/Task/File/Concat.php:
--------------------------------------------------------------------------------
1 | taskConcat([
16 | * 'web/assets/screen.css',
17 | * 'web/assets/print.css',
18 | * 'web/assets/theme.css'
19 | * ])
20 | * ->to('web/assets/style.css')
21 | * ->run()
22 | * ?>
23 | * ```
24 | */
25 | class Concat extends BaseTask
26 | {
27 | use ResourceExistenceChecker;
28 |
29 | /**
30 | * @var array|\Iterator
31 | */
32 | protected $files;
33 |
34 | /**
35 | * @var string
36 | */
37 | protected $dst;
38 |
39 | /**
40 | * Constructor.
41 | *
42 | * @param array|\Iterator $files
43 | */
44 | public function __construct($files)
45 | {
46 | $this->files = $files;
47 | }
48 |
49 | /**
50 | * set the destination file
51 | *
52 | * @param string $dst
53 | *
54 | * @return $this
55 | */
56 | public function to($dst)
57 | {
58 | $this->dst = $dst;
59 |
60 | return $this;
61 | }
62 |
63 | /**
64 | * {@inheritdoc}
65 | */
66 | public function run()
67 | {
68 | if (is_null($this->dst) || "" === $this->dst) {
69 | return Result::error($this, 'You must specify a destination file with to() method.');
70 | }
71 |
72 | if (!$this->checkResources($this->files, 'file')) {
73 | return Result::error($this, 'Source files are missing!');
74 | }
75 |
76 | if (file_exists($this->dst) && !is_writable($this->dst)) {
77 | return Result::error($this, 'Destination already exists and cannot be overwritten.');
78 | }
79 |
80 | $dump = '';
81 |
82 | foreach ($this->files as $path) {
83 | foreach (glob($path) as $file) {
84 | $dump .= file_get_contents($file) . "\n";
85 | }
86 | }
87 |
88 | $this->printTaskInfo('Writing {destination}', ['destination' => $this->dst]);
89 |
90 | $dst = $this->dst . '.part';
91 | $write_result = file_put_contents($dst, $dump);
92 |
93 | if (false === $write_result) {
94 | @unlink($dst);
95 | return Result::error($this, 'File write failed.');
96 | }
97 | // Cannot be cross-volume; should always succeed.
98 | @rename($dst, $this->dst);
99 |
100 | return Result::success($this);
101 | }
102 | }
103 |
--------------------------------------------------------------------------------
/src/Task/File/Tasks.php:
--------------------------------------------------------------------------------
1 | task(Concat::class, $files);
15 | }
16 |
17 | /**
18 | * @param string $file
19 | *
20 | * @return \Robo\Task\File\Replace|\Robo\Collection\CollectionBuilder
21 | */
22 | protected function taskReplaceInFile($file)
23 | {
24 | return $this->task(Replace::class, $file);
25 | }
26 |
27 | /**
28 | * @param string $file
29 | *
30 | * @return \Robo\Task\File\Write|\Robo\Collection\CollectionBuilder
31 | */
32 | protected function taskWriteToFile($file)
33 | {
34 | return $this->task(Write::class, $file);
35 | }
36 |
37 | /**
38 | * @param string $filename
39 | * @param string $extension
40 | * @param string $baseDir
41 | * @param bool $includeRandomPart
42 | *
43 | * @return \Robo\Task\File\TmpFile|\Robo\Collection\CollectionBuilder
44 | */
45 | protected function taskTmpFile($filename = 'tmp', $extension = '', $baseDir = '', $includeRandomPart = true)
46 | {
47 | return $this->task(TmpFile::class, $filename, $extension, $baseDir, $includeRandomPart);
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/src/Task/File/TmpFile.php:
--------------------------------------------------------------------------------
1 | collectionBuilder();
19 | * $tmpFilePath = $collection->taskTmpFile()
20 | * ->line('-----')
21 | * ->line(date('Y-m-d').' '.$title)
22 | * ->line('----')
23 | * ->getPath();
24 | * $collection->run();
25 | * ?>
26 | * ```
27 | */
28 | class TmpFile extends Write implements CompletionInterface
29 | {
30 | /**
31 | * @param string $filename
32 | * @param string $extension
33 | * @param string $baseDir
34 | * @param bool $includeRandomPart
35 | */
36 | public function __construct($filename = 'tmp', $extension = '', $baseDir = '', $includeRandomPart = true)
37 | {
38 | if (empty($baseDir)) {
39 | $baseDir = sys_get_temp_dir();
40 | }
41 | if ($includeRandomPart) {
42 | $random = static::randomString();
43 | $filename = "{$filename}_{$random}";
44 | }
45 | $filename .= $extension;
46 | parent::__construct("{$baseDir}/{$filename}");
47 | }
48 |
49 | /**
50 | * Generate a suitably random string to use as the suffix for our
51 | * temporary file.
52 | *
53 | * @param int $length
54 | *
55 | * @return string
56 | */
57 | private static function randomString($length = 12)
58 | {
59 | return substr(str_shuffle('23456789abcdefghjkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ'), 0, $length);
60 | }
61 |
62 | /**
63 | * Delete this file when our collection completes.
64 | * If this temporary file is not part of a collection,
65 | * then it will be deleted when the program terminates,
66 | * presuming that it was created by taskTmpFile() or _tmpFile().
67 | */
68 | public function complete()
69 | {
70 | unlink($this->getPath());
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/src/Task/Filesystem/BaseDir.php:
--------------------------------------------------------------------------------
1 | dirs = $dirs
27 | : $this->dirs[] = $dirs;
28 |
29 | $this->fs = new sfFilesystem();
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/Task/Filesystem/CleanDir.php:
--------------------------------------------------------------------------------
1 | taskCleanDir(['tmp','logs'])->run();
14 | * // as shortcut
15 | * $this->_cleanDir('app/cache');
16 | * ?>
17 | * ```
18 | */
19 | class CleanDir extends BaseDir
20 | {
21 | use ResourceExistenceChecker;
22 |
23 | /**
24 | * {@inheritdoc}
25 | */
26 | public function run()
27 | {
28 | if (!$this->checkResources($this->dirs, 'dir')) {
29 | return Result::error($this, 'Source directories are missing!');
30 | }
31 | foreach ($this->dirs as $dir) {
32 | $this->emptyDir($dir);
33 | $this->printTaskInfo("Cleaned {dir}", ['dir' => $dir]);
34 | }
35 | return Result::success($this);
36 | }
37 |
38 | /**
39 | * @param string $path
40 | */
41 | protected function emptyDir($path)
42 | {
43 | $iterator = new \RecursiveIteratorIterator(
44 | new \RecursiveDirectoryIterator($path),
45 | \RecursiveIteratorIterator::CHILD_FIRST
46 | );
47 |
48 | foreach ($iterator as $path) {
49 | if ($path->isDir()) {
50 | $dir = (string)$path;
51 | if (basename($dir) === '.' || basename($dir) === '..') {
52 | continue;
53 | }
54 | $this->fs->remove($dir);
55 | } else {
56 | $file = (string)$path;
57 | if (basename($file) === '.gitignore' || basename($file) === '.gitkeep') {
58 | continue;
59 | }
60 | $this->fs->remove($file);
61 | }
62 | }
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/src/Task/Filesystem/DeleteDir.php:
--------------------------------------------------------------------------------
1 | taskDeleteDir('tmp')->run();
14 | * // as shortcut
15 | * $this->_deleteDir(['tmp', 'log']);
16 | * ?>
17 | * ```
18 | */
19 | class DeleteDir extends BaseDir
20 | {
21 | use ResourceExistenceChecker;
22 |
23 | /**
24 | * {@inheritdoc}
25 | */
26 | public function run()
27 | {
28 | if (!$this->checkResources($this->dirs, 'dir')) {
29 | return Result::error($this, 'Source directories are missing!');
30 | }
31 | foreach ($this->dirs as $dir) {
32 | $this->fs->remove($dir);
33 | $this->printTaskInfo("Deleted {dir}...", ['dir' => $dir]);
34 | }
35 | return Result::success($this);
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/Task/Filesystem/MirrorDir.php:
--------------------------------------------------------------------------------
1 | taskMirrorDir(['dist/config/' => 'config/'])->run();
13 | * // or use shortcut
14 | * $this->_mirrorDir('dist/config/', 'config/');
15 | *
16 | * ?>
17 | * ```
18 | */
19 | class MirrorDir extends BaseDir
20 | {
21 | /**
22 | * {@inheritdoc}
23 | */
24 | public function run()
25 | {
26 | foreach ($this->dirs as $src => $dst) {
27 | $this->fs->mirror(
28 | $src,
29 | $dst,
30 | null,
31 | [
32 | 'override' => true,
33 | 'copy_on_windows' => true,
34 | 'delete' => true
35 | ]
36 | );
37 | $this->printTaskInfo("Mirrored from {source} to {destination}", ['source' => $src, 'destination' => $dst]);
38 | }
39 | return Result::success($this);
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/Task/Filesystem/Tasks.php:
--------------------------------------------------------------------------------
1 | task(CleanDir::class, $dirs);
15 | }
16 |
17 | /**
18 | * @param string|string[] $dirs
19 | *
20 | * @return \Robo\Task\Filesystem\DeleteDir|\Robo\Collection\CollectionBuilder
21 | */
22 | protected function taskDeleteDir($dirs)
23 | {
24 | return $this->task(DeleteDir::class, $dirs);
25 | }
26 |
27 | /**
28 | * @param string $prefix
29 | * @param string $base
30 | * @param bool $includeRandomPart
31 | *
32 | * @return \Robo\Task\Filesystem\WorkDir|\Robo\Collection\CollectionBuilder
33 | */
34 | protected function taskTmpDir($prefix = 'tmp', $base = '', $includeRandomPart = true)
35 | {
36 | return $this->task(TmpDir::class, $prefix, $base, $includeRandomPart);
37 | }
38 |
39 | /**
40 | * @param string $finalDestination
41 | *
42 | * @return \Robo\Task\Filesystem\TmpDir|\Robo\Collection\CollectionBuilder
43 | */
44 | protected function taskWorkDir($finalDestination)
45 | {
46 | return $this->task(WorkDir::class, $finalDestination);
47 | }
48 |
49 | /**
50 | * @param string|string[] $dirs
51 | *
52 | * @return \Robo\Task\Filesystem\CopyDir|\Robo\Collection\CollectionBuilder
53 | */
54 | protected function taskCopyDir($dirs)
55 | {
56 | return $this->task(CopyDir::class, $dirs);
57 | }
58 |
59 | /**
60 | * @param string|string[] $dirs
61 | *
62 | * @return \Robo\Task\Filesystem\MirrorDir|\Robo\Collection\CollectionBuilder
63 | */
64 | protected function taskMirrorDir($dirs)
65 | {
66 | return $this->task(MirrorDir::class, $dirs);
67 | }
68 |
69 | /**
70 | * @param string|string[] $dirs
71 | *
72 | * @return \Robo\Task\Filesystem\FlattenDir|\Robo\Collection\CollectionBuilder
73 | */
74 | protected function taskFlattenDir($dirs)
75 | {
76 | return $this->task(FlattenDir::class, $dirs);
77 | }
78 |
79 | /**
80 | * @return \Robo\Task\Filesystem\FilesystemStack|\Robo\Collection\CollectionBuilder
81 | */
82 | protected function taskFilesystemStack()
83 | {
84 | return $this->task(FilesystemStack::class);
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/src/Task/Gulp/Base.php:
--------------------------------------------------------------------------------
1 | option('silent');
37 | return $this;
38 | }
39 |
40 | /**
41 | * adds `--no-color` option to gulp
42 | *
43 | * @return $this
44 | */
45 | public function noColor()
46 | {
47 | $this->option('no-color');
48 | return $this;
49 | }
50 |
51 | /**
52 | * adds `--color` option to gulp
53 | *
54 | * @return $this
55 | */
56 | public function color()
57 | {
58 | $this->option('color');
59 | return $this;
60 | }
61 |
62 | /**
63 | * adds `--tasks-simple` option to gulp
64 | *
65 | * @return $this
66 | */
67 | public function simple()
68 | {
69 | $this->option('tasks-simple');
70 | return $this;
71 | }
72 |
73 | /**
74 | * @param string $task
75 | * @param null|string $pathToGulp
76 | *
77 | * @throws \Robo\Exception\TaskException
78 | */
79 | public function __construct($task, $pathToGulp = null)
80 | {
81 | $this->task = $task;
82 | $this->command = $pathToGulp;
83 | if (!$this->command) {
84 | $this->command = $this->findExecutable('gulp');
85 | }
86 | if (!$this->command) {
87 | throw new TaskException(__CLASS__, "Gulp executable not found.");
88 | }
89 | }
90 |
91 | /**
92 | * @return string
93 | */
94 | public function getCommand()
95 | {
96 | return "{$this->command} " . ProcessUtils::escapeArgument($this->task) . "{$this->arguments}";
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/src/Task/Gulp/Run.php:
--------------------------------------------------------------------------------
1 | taskGulpRun()->run();
14 | *
15 | * // run task 'clean' with --silent option
16 | * $this->taskGulpRun('clean')
17 | * ->silent()
18 | * ->run();
19 | * ?>
20 | * ```
21 | */
22 | class Run extends Base implements CommandInterface
23 | {
24 | /**
25 | * {@inheritdoc}
26 | */
27 | public function run()
28 | {
29 | if (strlen($this->arguments)) {
30 | $this->printTaskInfo('Running Gulp task: {gulp_task} with arguments: {arguments}', ['gulp_task' => $this->task, 'arguments' => $this->arguments]);
31 | } else {
32 | $this->printTaskInfo('Running Gulp task: {gulp_task} without arguments', ['gulp_task' => $this->task]);
33 | }
34 | return $this->executeCommand($this->getCommand());
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/Task/Gulp/Tasks.php:
--------------------------------------------------------------------------------
1 | task(Run::class, $task, $pathToGulp);
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/Task/Logfile/BaseLogfile.php:
--------------------------------------------------------------------------------
1 | logfiles = $logfiles
32 | : $this->logfiles[] = $logfiles;
33 |
34 | $this->filesystem = new Filesystem();
35 | }
36 |
37 | /**
38 | * @param int $chmod
39 | * @return $this
40 | */
41 | public function chmod(int $chmod)
42 | {
43 | $this->chmod = $chmod;
44 |
45 | return $this;
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/src/Task/Logfile/Shortcuts.php:
--------------------------------------------------------------------------------
1 | taskRotateLog($logfile)->run();
17 | }
18 |
19 | /**
20 | * @param string|string[] $logfile
21 | *
22 | * @return \Robo\Result
23 | */
24 | protected function _truncateLog($logfile): Result
25 | {
26 | return $this->taskTruncateLog($logfile)->run();
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/Task/Logfile/Tasks.php:
--------------------------------------------------------------------------------
1 | task(RotateLog::class, $logfile);
17 | }
18 |
19 | /**
20 | * @param string|string[] $logfile
21 | *
22 | * @return \Robo\Task\Logfile\TruncateLog|\Robo\Collection\CollectionBuilder
23 | */
24 | protected function taskTruncateLog($logfile): CollectionBuilder
25 | {
26 | return $this->task(TruncateLog::class, $logfile);
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/Task/Logfile/TruncateLog.php:
--------------------------------------------------------------------------------
1 | taskTruncateLog(['logfile.log'])->run();
13 | * // or use shortcut
14 | * $this->_truncateLog(['logfile.log']);
15 | *
16 | * ?>
17 | * ```
18 | */
19 | class TruncateLog extends BaseLogfile
20 | {
21 | /**
22 | * {@inheritdoc}
23 | */
24 | public function run(): Result
25 | {
26 | foreach ($this->logfiles as $logfile) {
27 | $this->filesystem->dumpFile($logfile, false);
28 | if ($this->chmod) {
29 | $this->filesystem->chmod($logfile, $this->chmod);
30 | }
31 | $this->printTaskInfo("Truncated {logfile}", ['logfile' => $logfile]);
32 | }
33 |
34 | return Result::success($this);
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/Task/Npm/Base.php:
--------------------------------------------------------------------------------
1 | option('production');
36 | return $this;
37 | }
38 |
39 | /**
40 | * @param null|string $pathToNpm
41 | *
42 | * @throws \Robo\Exception\TaskException
43 | */
44 | public function __construct($pathToNpm = null)
45 | {
46 | $this->command = $pathToNpm;
47 | if (!$this->command) {
48 | $this->command = $this->findExecutable('npm');
49 | }
50 | if (!$this->command) {
51 | throw new TaskException(__CLASS__, "Npm executable not found.");
52 | }
53 | }
54 |
55 | /**
56 | * @return string
57 | */
58 | public function getCommand()
59 | {
60 | return "{$this->command} {$this->action}{$this->arguments}";
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/src/Task/Npm/Install.php:
--------------------------------------------------------------------------------
1 | taskNpmInstall()->run();
14 | *
15 | * // prefer dist with custom path
16 | * $this->taskNpmInstall('path/to/my/npm')
17 | * ->noDev()
18 | * ->run();
19 | * ?>
20 | * ```
21 | */
22 | class Install extends Base implements CommandInterface
23 | {
24 | /**
25 | * {@inheritdoc}
26 | */
27 | protected $action = 'install';
28 |
29 | /**
30 | * {@inheritdoc}
31 | */
32 | public function run()
33 | {
34 | $this->printTaskInfo('Install Npm packages: {arguments}', ['arguments' => $this->arguments]);
35 | return $this->executeCommand($this->getCommand());
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/Task/Npm/Tasks.php:
--------------------------------------------------------------------------------
1 | task(Install::class, $pathToNpm);
15 | }
16 |
17 | /**
18 | * @param null|string $pathToNpm
19 | *
20 | * @return \Robo\Task\Npm\Update|\Robo\Collection\CollectionBuilder
21 | */
22 | protected function taskNpmUpdate($pathToNpm = null)
23 | {
24 | return $this->task(Update::class, $pathToNpm);
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/Task/Npm/Update.php:
--------------------------------------------------------------------------------
1 | taskNpmUpdate()->run();
12 | *
13 | * // prefer dist with custom path
14 | * $this->taskNpmUpdate('path/to/my/npm')
15 | * ->noDev()
16 | * ->run();
17 | * ?>
18 | * ```
19 | */
20 | class Update extends Base
21 | {
22 | /**
23 | * {@inheritdoc}
24 | */
25 | protected $action = 'update';
26 |
27 | /**
28 | * {@inheritdoc}
29 | */
30 | public function run()
31 | {
32 | $this->printTaskInfo('Update Npm packages: {arguments}', ['arguments' => $this->arguments]);
33 | return $this->executeCommand($this->getCommand());
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/Task/Remote/Tasks.php:
--------------------------------------------------------------------------------
1 | task(Rsync::class);
13 | }
14 |
15 | /**
16 | * @param null|string $hostname
17 | * @param null|string $user
18 | *
19 | * @return \Robo\Task\Remote\Ssh|\Robo\Collection\CollectionBuilder
20 | */
21 | protected function taskSshExec($hostname = null, $user = null)
22 | {
23 | return $this->task(Ssh::class, $hostname, $user);
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/Task/Testing/Phpspec.php:
--------------------------------------------------------------------------------
1 | taskPhpspec()
16 | * ->format('pretty')
17 | * ->noInteraction()
18 | * ->run();
19 | * ?>
20 | * ```
21 | *
22 | */
23 | class Phpspec extends BaseTask implements CommandInterface, PrintedInterface
24 | {
25 | use ExecOneCommand;
26 |
27 | /**
28 | * @var string
29 | */
30 | protected $command;
31 |
32 | /**
33 | * @var string[] $formaters
34 | * Available formaters for format option.
35 | */
36 | protected $formaters = ['progress', 'html', 'pretty', 'junit', 'dot', 'tap'];
37 |
38 | /**
39 | * @var array $verbose_levels
40 | * Available verbose levels.
41 | */
42 | protected $verbose_levels = ['v', 'vv', 'vvv'];
43 |
44 | /**
45 | * Phpspec constructor.
46 | *
47 | * @param null|string $pathToPhpspec
48 | *
49 | * @throws \Robo\Exception\TaskException
50 | */
51 | public function __construct($pathToPhpspec = null)
52 | {
53 | $this->command = $pathToPhpspec;
54 | if (!$this->command) {
55 | $this->command = $this->findExecutable('phpspec');
56 | }
57 | if (!$this->command) {
58 | throw new \Robo\Exception\TaskException(__CLASS__, "Neither composer nor phar installation of Phpspec found");
59 | }
60 | $this->arg('run');
61 | }
62 |
63 | public function stopOnFail()
64 | {
65 | $this->option('stop-on-failure');
66 | return $this;
67 | }
68 |
69 | public function noCodeGeneration()
70 | {
71 | $this->option('no-code-generation');
72 | return $this;
73 | }
74 |
75 | public function quiet()
76 | {
77 | $this->option('quiet');
78 | return $this;
79 | }
80 |
81 | /**
82 | * @param string $level
83 | *
84 | * @return $this
85 | */
86 | public function verbose($level = 'v')
87 | {
88 | if (!in_array($level, $this->verbose_levels)) {
89 | throw new \InvalidArgumentException('expected ' . implode(',', $this->verbose_levels));
90 | }
91 | $this->option('-' . $level);
92 | return $this;
93 | }
94 |
95 | /**
96 | * @return $this
97 | */
98 | public function noAnsi()
99 | {
100 | $this->option('no-ansi');
101 | return $this;
102 | }
103 |
104 | /**
105 | * @return $this
106 | */
107 | public function noInteraction()
108 | {
109 | $this->option('no-interaction');
110 | return $this;
111 | }
112 |
113 | /**
114 | * @param string $config_file
115 | *
116 | * @return $this
117 | */
118 | public function config($config_file)
119 | {
120 | $this->option('config', $config_file);
121 | return $this;
122 | }
123 |
124 | /**
125 | * @param string $formater
126 | *
127 | * @return $this
128 | */
129 | public function format($formater)
130 | {
131 | if (!in_array($formater, $this->formaters)) {
132 | throw new \InvalidArgumentException('expected ' . implode(',', $this->formaters));
133 | }
134 | $this->option('format', $formater);
135 | return $this;
136 | }
137 |
138 | /**
139 | * {@inheritdoc}
140 | */
141 | public function getCommand()
142 | {
143 | return $this->command . $this->arguments;
144 | }
145 |
146 | /**
147 | * {@inheritdoc}
148 | */
149 | public function run()
150 | {
151 | $this->printTaskInfo('Running phpspec {arguments}', ['arguments' => $this->arguments]);
152 | return $this->executeCommand($this->getCommand());
153 | }
154 | }
155 |
--------------------------------------------------------------------------------
/src/Task/Testing/Tasks.php:
--------------------------------------------------------------------------------
1 | task(Codecept::class, $pathToCodeception);
15 | }
16 |
17 | /**
18 | * @param null|string $pathToPhpUnit
19 | *
20 | * @return \Robo\Task\Testing\PHPUnit|\Robo\Collection\CollectionBuilder
21 | */
22 | protected function taskPhpUnit($pathToPhpUnit = null)
23 | {
24 | return $this->task(PHPUnit::class, $pathToPhpUnit);
25 | }
26 |
27 | /**
28 | * @param null|string $pathToPhpspec
29 | *
30 | * @return \Robo\Task\Testing\Phpspec|\Robo\Collection\CollectionBuilder
31 | */
32 | protected function taskPhpspec($pathToPhpspec = null)
33 | {
34 | return $this->task(Phpspec::class, $pathToPhpspec);
35 | }
36 |
37 | /**
38 | * @param null|string $pathToAtoum
39 | *
40 | * @return \Robo\Task\Testing\Atoum|\Robo\Collection\CollectionBuilder
41 | */
42 | protected function taskAtoum($pathToAtoum = null)
43 | {
44 | return $this->task(Atoum::class, $pathToAtoum);
45 | }
46 |
47 | /**
48 | * @param null|string $pathToBehat
49 | *
50 | * @return \Robo\Task\Testing\Behat|\Robo\Collection\CollectionBuilder
51 | */
52 | protected function taskBehat($pathToBehat = null)
53 | {
54 | return $this->task(Behat::class, $pathToBehat);
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/src/Task/Vcs/HgStack.php:
--------------------------------------------------------------------------------
1 | hgStack
13 | * ->cloneRepo('https://bitbucket.org/durin42/hgsubversion')
14 | * ->pull()
15 | * ->add()
16 | * ->commit('changed')
17 | * ->push()
18 | * ->tag('0.6.0')
19 | * ->push('0.6.0')
20 | * ->run();
21 | * ?>
22 | * ```
23 | */
24 | class HgStack extends CommandStack
25 | {
26 |
27 | /**
28 | * @param string $pathToHg
29 | */
30 | public function __construct($pathToHg = 'hg')
31 | {
32 | $this->executable = $pathToHg;
33 | }
34 |
35 | /**
36 | * Executes `hg clone`
37 | *
38 | * @param string $repo
39 | * @param string $to
40 | *
41 | * @return $this
42 | */
43 | public function cloneRepo($repo, $to = '')
44 | {
45 | return $this->exec(['clone', $repo, $to]);
46 | }
47 |
48 | /**
49 | * Executes `hg add` command with files to add by pattern
50 | *
51 | * @param string $include
52 | * @param string $exclude
53 | *
54 | * @return $this
55 | */
56 | public function add($include = '', $exclude = '')
57 | {
58 | if (strlen($include) > 0) {
59 | $include = "-I {$include}";
60 | }
61 |
62 | if (strlen($exclude) > 0) {
63 | $exclude = "-X {$exclude}";
64 | }
65 |
66 | return $this->exec([__FUNCTION__, $include, $exclude]);
67 | }
68 |
69 | /**
70 | * Executes `hg commit` command with a message
71 | *
72 | * @param string $message
73 | * @param string $options
74 | *
75 | * @return $this
76 | */
77 | public function commit($message, $options = '')
78 | {
79 | return $this->exec([__FUNCTION__, "-m '{$message}'", $options]);
80 | }
81 |
82 | /**
83 | * Executes `hg pull` command.
84 | *
85 | * @param string $branch
86 | *
87 | * @return $this
88 | */
89 | public function pull($branch = '')
90 | {
91 | if (strlen($branch) > 0) {
92 | $branch = "-b '{$branch}''";
93 | }
94 |
95 | return $this->exec([__FUNCTION__, $branch]);
96 | }
97 |
98 | /**
99 | * Executes `hg push` command
100 | *
101 | * @param string $branch
102 | *
103 | * @return $this
104 | */
105 | public function push($branch = '')
106 | {
107 | if (strlen($branch) > 0) {
108 | $branch = "-b '{$branch}'";
109 | }
110 |
111 | return $this->exec([__FUNCTION__, $branch]);
112 | }
113 |
114 | /**
115 | * Performs hg merge
116 | *
117 | * @param string $revision
118 | *
119 | * @return $this
120 | */
121 | public function merge($revision = '')
122 | {
123 | if (strlen($revision) > 0) {
124 | $revision = "-r {$revision}";
125 | }
126 |
127 | return $this->exec([__FUNCTION__, $revision]);
128 | }
129 |
130 | /**
131 | * Executes `hg tag` command
132 | *
133 | * @param string $tag_name
134 | * @param string $message
135 | *
136 | * @return $this
137 | */
138 | public function tag($tag_name, $message = '')
139 | {
140 | if ($message !== '') {
141 | $message = "-m '{$message}'";
142 | }
143 | return $this->exec([__FUNCTION__, $message, $tag_name]);
144 | }
145 |
146 | /**
147 | * {@inheritdoc}
148 | */
149 | public function run()
150 | {
151 | $this->printTaskInfo('Running hg commands...');
152 | return parent::run();
153 | }
154 | }
155 |
--------------------------------------------------------------------------------
/src/Task/Vcs/Shortcuts.php:
--------------------------------------------------------------------------------
1 | taskSvnStack()->checkout($url)->run();
15 | }
16 |
17 | /**
18 | * @param string $url
19 | *
20 | * @return \Robo\Result
21 | */
22 | protected function _gitClone($url)
23 | {
24 | return $this->taskGitStack()->cloneRepo($url)->run();
25 | }
26 |
27 | /**
28 | * @param string $url
29 | *
30 | * @return \Robo\Result
31 | */
32 | protected function _hgClone($url)
33 | {
34 | return $this->taskHgStack()->cloneRepo($url)->run();
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/Task/Vcs/SvnStack.php:
--------------------------------------------------------------------------------
1 | taskSvnStack()
15 | * ->checkout('http://svn.collab.net/repos/svn/trunk')
16 | * ->run()
17 | *
18 | * // alternatively
19 | * $this->_svnCheckout('http://svn.collab.net/repos/svn/trunk');
20 | *
21 | * $this->taskSvnStack('username', 'password')
22 | * ->stopOnFail()
23 | * ->update()
24 | * ->add('doc/*')
25 | * ->commit('doc updated')
26 | * ->run();
27 | * ?>
28 | * ```
29 | */
30 | class SvnStack extends CommandStack implements CommandInterface
31 | {
32 | /**
33 | * @var bool
34 | */
35 | protected $stopOnFail = false;
36 |
37 | /**
38 | * {@inheritdoc}
39 | */
40 | protected $result;
41 |
42 | /**
43 | * @param string $username
44 | * @param string $password
45 | * @param string $pathToSvn
46 | */
47 | public function __construct($username = '', $password = '', $pathToSvn = 'svn')
48 | {
49 | $this->executable = $pathToSvn;
50 | if (!empty($username)) {
51 | $this->executable .= " --username $username";
52 | }
53 | if (!empty($password)) {
54 | $this->executable .= " --password $password";
55 | }
56 | $this->result = Result::success($this);
57 | }
58 |
59 | /**
60 | * Updates `svn update` command
61 | *
62 | * @param string $path
63 | *
64 | * @return $this
65 | */
66 | public function update($path = '')
67 | {
68 | return $this->exec("update $path");
69 | }
70 |
71 | /**
72 | * Executes `svn add` command with files to add pattern
73 | *
74 | * @param string $pattern
75 | *
76 | * @return $this
77 | */
78 | public function add($pattern = '')
79 | {
80 | return $this->exec("add $pattern");
81 | }
82 |
83 | /**
84 | * Executes `svn commit` command with a message
85 | *
86 | * @param string $message
87 | * @param string $options
88 | *
89 | * @return $this
90 | */
91 | public function commit($message, $options = "")
92 | {
93 | return $this->exec("commit -m '$message' $options");
94 | }
95 |
96 | /**
97 | * Executes `svn checkout` command
98 | *
99 | * @param string $branch
100 | *
101 | * @return $this
102 | */
103 | public function checkout($branch)
104 | {
105 | return $this->exec("checkout $branch");
106 | }
107 | }
108 |
--------------------------------------------------------------------------------
/src/Task/Vcs/Tasks.php:
--------------------------------------------------------------------------------
1 | task(SvnStack::class, $username, $password, $pathToSvn);
17 | }
18 |
19 | /**
20 | * @param string $pathToGit
21 | *
22 | * @return \Robo\Task\Vcs\GitStack|\Robo\Collection\CollectionBuilder
23 | */
24 | protected function taskGitStack($pathToGit = 'git')
25 | {
26 | return $this->task(GitStack::class, $pathToGit);
27 | }
28 |
29 | /**
30 | * @param string $pathToHg
31 | *
32 | * @return \Robo\Task\Vcs\HgStack|\Robo\Collection\CollectionBuilder
33 | */
34 | protected function taskHgStack($pathToHg = 'hg')
35 | {
36 | return $this->task(HgStack::class, $pathToHg);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/TaskAccessor.php:
--------------------------------------------------------------------------------
1 | task(Foo::class, $a, $b);
31 | *
32 | * instead of:
33 | *
34 | * $this->taskFoo($a, $b);
35 | *
36 | * The later form is preferred.
37 | *
38 | * @return \Robo\Collection\CollectionBuilder
39 | */
40 | protected function task()
41 | {
42 | $args = func_get_args();
43 | $name = array_shift($args);
44 |
45 | $collectionBuilder = $this->collectionBuilder();
46 | return $collectionBuilder->build($name, $args);
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/src/TaskInfo.php:
--------------------------------------------------------------------------------
1 | TaskInfo::formatTaskName($task),
18 | 'task' => $task,
19 | ];
20 | }
21 |
22 | /**
23 | * @param object $task
24 | *
25 | * @return string
26 | */
27 | public static function formatTaskName($task)
28 | {
29 | $name = get_class($task);
30 | $name = preg_replace('~Stack^~', '', $name);
31 | $name = str_replace('Robo\\Task\Base\\', '', $name);
32 | $name = str_replace('Robo\\Task\\', '', $name);
33 | $name = str_replace('Robo\\Collection\\', '', $name);
34 | return $name;
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/Tasks.php:
--------------------------------------------------------------------------------
1 |