consolidation / robo Goto Github PK
View Code? Open in Web Editor NEWModern task runner for PHP
Home Page: http://robo.li
License: Other
Modern task runner for PHP
Home Page: http://robo.li
License: Other
If you want to exclude patterns with a wildcard, e.g. *.scss, it will not exclude these files but (as the shell expands the wildcard) also sync matching files in the current working directory (which is certainly not what you want ;).
In exclude()
method of rsync task (https://github.com/Codegyre/Robo/blob/master/src/Task/Rsync.php#L241), we could add escapeshellarg:
return $this->option('exclude', escapeshellarg($pattern));
This would be a BC break for people who already added ' themselves:
$rsync->exclude("'*.scss'");
But from my point of view, it should be escaped.
With the current implementation of how options are interpreted, empty defaults to options cannot be used.
if (empty($val)) {
$task->addOption($name, '', InputOption::VALUE_NONE, '');
} else {
$task->addOption($name, '', InputOption::VALUE_OPTIONAL, '', $val);
}
With this null
, false
, ''
cannot be used as a default where an argument might be desired.
I would suggest it be changed to
if (is_bool($val)) {
$task->addOption($name, '', InputOption::VALUE_NONE, '');
} else {
$task->addOption($name, '', InputOption::VALUE_OPTIONAL, '', $val);
}
While I'm at it I'd also like to make a feature request.
With a little regex-foo it would be possible to turn
/**
* @argument $name Name to say hello to
* @option $loud Make it yell
*/
public function hello($name = null, $opts = ['loud' => false])
{
}
using something like this
preg_match_all(
'/@option[ \t]+\$(?P<name>[^ \t]+)[ \t]+(?P<description>.*)/',
$this->reflection->getDocComment(),
$matches
);
into
Usage:
hello [--loud] name
Arguments:
name Name to say hello to
Options:
--loud Make it yell
When prompting for sensitive information (like passwords) it would be nice to avoid printing the characters directly on screen. Currently there's no extra argument for the ask() method, perhaps adding an extra optional parameter to make it silent would be nice.
Getting an error whilst using, for example:
$this->taskWriteToFile($this->path($settingsFile))
->text($envSettings)
->append()
->run();
Call to undefined method Robo\Task\WriteToFileTask::append()
Line 211 of Robo\Task\FileSystem suggests it should be a magic method, yet I see no __call() declaration anywhere. Am I missing something?
In my robo-drush update for Robo 0.5.0 I set conflict
in composer.json to ~0.4
.
This did not work as the new Robo version does not follow semantic versioning. It should have been named 1.0.0
.
Had to change it to <0.5.0
.
I think it would be good practice to use semver, what do you think?
Getting following error with semver task:
Warning: implode(): Invalid arguments passed in C:\server\ext\vendor\codegyre\robo\src\Task\Development.php on line 611
[Robo\Task\Shared\TaskException]
in task Robo\Task\SemVerTask
Bad semver file.
The code:
$output = file_get_contents($this->path);
if (!preg_match_all(self::REGEX, implode("\n", $output), $matches)) { // line 611
throw new TaskException($this, 'Bad semver file.');
}
Imploding the string doesn't seem right?..
PS also it always says Error
in result, I think something might be off with that Result($this, (int)($written !== false)
Robofile::__construct() shows up in "Available commands" block. It shouldn't be there.
class Robofile extends \Robo\Tasks
{
public function __construct()
{
$this->stopOnFail();
}
// ... commands ...
}
Available commands:
__construct
build
help Displays help for a command
list Lists commands
optimize
optimize:autoloader
run
run:tests
This is my watch
task:
/**
* Watches for changes.
*/
public function watch() {
$this->taskWatch()->monitor( array( 'css/variables.less', 'css/laps.less' ), function () {
$this->less();
} )->run();
}
It names both files correctly when started:
c:\server\www\dev\wp-content\plugins\laps>robo watch
[Robo\Task\WatchTask] watching css/variables.less for changes...
[Robo\Task\WatchTask] watching css/laps.less for changes...
But only last file is tracked, changes to first file do not trigger task. If I reverse order of files in array it flips and again — only last file in array is tracked, other one is ignored.
Win7x64, PHP 5.5
PS ok, now I am not sure if this is even supposed to work?.. :) For some reason I was under impression it is.
I need some help about using Robo with Bamboo CI to run Codeception tests. Currently status is that everything working fine until Robo finish its own tasks. It finish it successfully but than everything stop. In Bamboo there is one next task to parse xml response generated from tests and merged by Robo, but it never start.
Here is part from log file in Bamboo:
[Robo\Task\ExecTask] running export DISPLAY=:0 && java -jar selenium-server-standalone-2.43.1.jar -port 5555 -role node -hub http://privateIP:4444/hub/register
[Robo\Task\ParallelExecTask] php codecept.phar run --group login -c tests/frontend --no-exit --xml _log/acceptance.login.xml acceptance
[Robo\Task\ParallelExecTask] 1 processes ended in 41.40 s
[Codeception\Task\MergeXmlReportsTask] Merging JUnit XML reports into /home/bamboo/bamboo-agent-home/xml-data/build-dir/RP-AT-JOB1/tests/_output/result.xml
[Codeception\Task\MergeXmlReportsTask] Processing /home/bamboo/bamboo-agent-home/xml-data/build-dir/RP-AT-JOB1/tests/frontend/tests/_output/_log/acceptance.login.xml
[Codeception\Task\MergeXmlReportsTask] File /home/bamboo/bamboo-agent-home/xml-data/build-dir/RP-AT-JOB1/tests/_output/result.xml saved. 1 suites added
[Robo\Task\ExecTask] stopped java -jar selenium-server-standalone-2.43.1.jar -role hub
After this last line 'stopped java -jar selenium...' there is nothing more. Bamboo never move to next task and I need to stop it manually.
Is there anyone who have experience with using Robo/Codeception with Bamboo CI, who can help me with this?
It would be a good feature to have a "global" RoboFile (in home directory?) and have some common tasks used in many projects (eg. watching for changes in [src/lib] folder and running tests on change.
Hi.
I'd love to be able to execute Robo with a custom class instead define a robofile with a Robofile class inside. Even define a custom input. Something like:
use Robo\Runner;
use Symfony\Component\Console\Input\ArgvInput;
$runner = new Runner();
$myTasks = new MyTasks();
$input = new ArgvInput($argv);
$runner->execute($myTasks, $input);
Generated RoboFile.php
lacks PHPDoc for the class.
I took a quick look at implementation for maybe pull requesting something in, but since class file/name are implemented as class constants (for flexibility I assume?) I am not sure what would be the way to go with adding PHPDoc to it.
I have some issues with "CopyDir" task (mkdir in line 35):
ERROR: mkdir(): File exists in vendor/codegyre/robo/src/Task/FileSystem/CopyDir.php:35
using it in a project.Already added some tests and will create a PR in a moment.
Looking at the code however, I do not understand the initial need for a CopyDir
task?
I can use the MirrorDir
task (which deletes files on the destination) or use FilesystemStack
mirror function directly.
Can you bring some light into this?
First time using this cool tool.
I'ts minor but I didn't see an issue about it.
On Windows 7 using cmder(Conemu) I get a funny looking character instead of the arrow.
λ "vendor/bin/robo" say:hello
Γ₧£ What up foo!?
Instead of this from the getting started sample
php vendor/bin/robo hello davert
➜ Hello, davert
Just using a simple function.
class RoboFile extends Tasks {
public function sayHello()
{
$this->say('What up foo!?');
}
}
Would be nice to have an implementation for backup-manager.
In normal case, I would usually contribute, but I am a bit busy right now. I just wanted to mention it, hopefully someone goes for it. :)
If somebody does, please comment here, so I know I shouldn't if I find some time to do it.
@DavertMik is it fitting into Robo at all?
In the change log it mentions: RoboFile can be changed to any provided class.
This is not immediately obvious to me.
Is the idea that I simply create my own custom cut down version of the Robo\Runner
class.
Removing all the logic around loading the RoboFile.php
.
Or is there something I am missing here???
The robo.phar will not work if you use composer with a directory called vendor. Looking at the code below, if you run robo.phar in a top level directory, with composer dependencies in the directory vendor, then the autoloader is always taken from the vendor folder.
This requires Robo as a dependency in composer, and creates a chicken egg situation, when using Composer Task inside Robo.
Do you install robo via composer initially composer install
and then use robo composer tasks to manage other deps afterwardsbin/robo composer:instal
? Or do you download robo.phar and use it to run your initial composer tasks `robo.phar composer:install``
Error below:
PHP Fatal error: Class 'Robo\Runner' not found in /vagrant/robo.phar on line 13
PHP Stack trace:
PHP 1. {main}() /vagrant/robo.phar
, because it's not in the autoloader as it's not a dependency in composer.json .
Shouldn't the robo.phar always use it's own autoloader? It should be left up to the dev to require or autoload additional tasks inside their own Robofile.
#!/usr/bin/env php
<?php
Phar::mapPhar();
if (file_exists(__DIR__.'/vendor/autoload.php')) {
require_once __DIR__.'/vendor/autoload.php';
} elseif (file_exists(__DIR__.'/../../autoload.php')) {
require_once __DIR__ . '/../../autoload.php';
} else {
require_once 'phar://robo.phar/vendor/autoload.php';
}
$runner = new \Robo\Runner();
$runner->execute();
Is it possible to execute FileSystem tasks through the SshExec task, like ReplaceInFile and WriteToFile? I'm getting an error trying to do just that. Apologies if I missed something obvious.
Thanks!
How i can change ExecTask::isPrinted?
May be need add method like as ExecTask::background()?
When robo generates robofile for the first time, file name is "RoboFile.php" (with uppercase F) but class name is "Robofile". How about changing filename to "Robofile.php" for consistency? Or better all lowercase - "robofile.php", like we used to with other tools, such as phpunit.xml, composer.json etc.
There is any point on having multiple classes declared on the same file, breaking PSR-0?
Classes/ Traits / Interfaces Declared | Filename |
---|---|
2 | ./src/Output.php |
2 | ./src/Result.php |
2 | ./src/Runner.php |
5 | ./src/Task/Composer.php |
4 | ./src/Task/Development.php |
2 | ./src/Task/DynamicConfig.php |
4 | ./src/Task/Exec.php |
9 | ./src/Task/FileSystem.php |
3 | ./src/Task/Git.php |
5 | ./src/Task/GitHub.php |
3 | ./src/Task/PackPhar.php |
3 | ./src/Task/PhpServer.php |
3 | ./src/Task/SymfonyCommand.php |
2 | ./src/Task/TaskException.php |
2 | ./src/Task/TaskInterface.php |
3 | ./src/Task/Watch.php |
2 | ./src/TaskInfo.php |
2 | ./src/Tasks.php |
2 | ./src/Util/FileSystem.php |
<?php
taskChangelog::init()
->change('refactored Robo')
->version('0.5.0')
->run();
?>
For one-line tasks are simplified to:
<?php
taskExec::_run('cap production deploy');
// equal to
taskExec::init()
->exec('cap production deploy')
->run();
// also
taskCopyDir::_run(['/var/log', '/backup/log']);
taskCleanDir::_run(['web/assets','tmp/','log/']);
taskRename::_run('Dockerfile', 'tmpDockerfile');
?>
Those commands will initializa and invoke tasks;
4 Stack tasks changes
<?php
// performs actions one by one
taskGit::stack()
->add('-A')
->commit("auto-update")
->pull()
->push()
->run();
// clones repo
taskGit::_clone('[email protected]:php-vcr/php-vcr.git');
// equal to
taskGit::stack()
->clone('[email protected]:php-vcr/php-vcr.git')
->run();
?>
This goes far well for Exec:
<?php
// run 1 command
taskExec::_run('grunt test');
// run 2 commands
taskExec::stack()
->exec('grunt test')
->exec('phpunit')
->run();
?>
5 RoboFile must contain a namespace so FQNs could be simplified by IDE to proposed variants. Namespace can be either:
6 Directory Structure would be following:
src/
Command
RoboUpdate
RoboGlobalInstall
Interfaces
TaskInterface
RunnableInterface
Exception
TaskException
Commons
Executable
DynamicConfig
CommandStack
Output
Task
BaseTask
FileSystem
taskCleanDir
taskDeleteDir
task....
Codeception\
taskCodeceptRun
PhpUnit\
taskPhpUnit
Minify\
taskMinify
Docker\
task....
Npm\
taskNpmInstall
taskNpmUpdate
Rsync\
taskRsync
Svn\
taskSvnStack
Watch\
taskWatch
Exec\
taskExec
taskExecStack
How does this compare to Phake (not the mocking one)?
Also do you have plans to support streams similar to Gulp?
I am toying with adding CSS & JS minification to my robofiles and thinking it should be abstracted into a task for easy reuse. Using JSqueeze and CssMin right now (basically went and looked what Assetic uses).
Any interest / conceptual fit for me to contribute that to Robo as native task?
If not I'll probably develop and release it as standalone task package.
Hi!
I discovered Robo this week. Today I downloaded the phar file from site, but wen I execute php robo.phar I get this message:
PHP Parse error: syntax error, unexpected T_USE, expecting T_FUNCTION in phar:///vagrant/robo.phar/src/Runner.php on line 15
If one of the parallel execution tasks fails, an over success of exit code 0
is return?
Surely if 1 of the tasks fail, it should return an exit code of 1
?
Hi.
I have the following Robofile:
<?php
class RoboFile extends \Robo\Tasks
{
function test()
{
$this->ask('Are you happy?');
}
}
If I execute php robo.phar test
everything works fine, but if the command is executed by composer, defined in a composer.json file:
{
"scripts": {
"post-create-project-cmd": "php robo.phar test"
}
}
I have this error:
Script php robo.phar test handling the post-create-project-cmd event returned with an error
[RuntimeException]
Error Output:
[RuntimeException]
Aborted
test
This does not happens with say()
or other non interactive methods.
Preconditions: executable some-executable
and run exec('status')
:
The way it is implemented now:
All characters from the executable are left stripped from the command, leaving the command empty in the above example.
Will push a test and fix in a minute...
What would be great if you could "cd" to the folder where you have the composer and then do "composer update" for example.
It would come in handy when you would need to update own package on multiple applications and you could do it with one task runner.
Is that a possibility?
They use the wrong constructor arguments for the Robo tasks.
Needs to be an array instead of two params.
Will push a PR soon.
Hello,
I'm wondering if is there any way to provide a description for each public function in RoboFile.php?
e.g. I've added a public function test() {}
, it will be converted to command. when I run robo list
it will show me the test
as command but without description.
Thanks for this amazing project! :)
I have noticed that if I launch long running programs with Exec (for example BrowserSync) then Robo starts to consume a lot of CPU just sitting there and waiting. It's about 12% in my system (Core i7 CPU, Win7x64).
It's clearly on PHP side as shown by Process Explorer and it's not the issue if I run exactly same command directly in console.
We need more examples of various Robo usage. If you use Robo and you have nice build script in your Robofile, please paste it here, and I will add it to site.
Thanks
The documentation says to use "taskCommand" method to execute SymfonyCommands but we actually have to use "taskSymfonyCommand", and it would be good to document how to use the parameters. http://robo.li/tasks.html#symfonycommand
That was my try:
$this->taskSymfonyCommand(new \Symfony\Bundle\FrameworkBundle\Command\AssetsInstallCommand())
->arg('target', 'web')
->opt('symlink')
->run();
But the command can't find the Kernel, because the app is not bootstrapped.
Is the "taskSymfonyCommand" really working or should I use "taskExec" for it?
Is 0.4.6 an official release?
JSqueeze has been updated to 2.0.
Hello, command line options written alone should translate to boolean variables, but they are always false.
From the manual:
function hello($opts = ['silent' => false])
{
if (!$opt['silent']) $this->say("Hello, world");
}
When calling
robo hello --silent
$opts['silent'] should be true, or at least non-empty, but it is simply false.
However when calling
robo hello --silent=foo
$opts['silent'] === 'foo'
In case it's a change in Symfony, I use Symfony 2.5.2.
Btw: There is a typo in the manual example, $opt instead of $opts.
This seems to use some proc functions for background processing. Perhaps that should be mentioned in the readme?
I want to execute a php server using a router script. The command used is something like this:
php -S localhost:8000 -t public public/index.php
But the PhpServer task does not provide any method to add arguments. I've tried this:
$this->taskServer(8000)
->dir('public')
->arg('public/index.php')
->run();
but it does not work.
Some internal changes done to RoboFile.php in between 0.4.6 and 0.4.7 has broken Robo for me. Additionally, the resulting size of robo.phar has blown up to 6.9MB up from 1.6MB in version 0.4.6.
In particular, the 'buildPhar()' task in RoboFile.php has dropped the 'composer --no-dev' and replacement wrappers around the task and replaced them with a single ->exclude('codeception') call.
The short version is: this change does not appear to have been safe and likely needs to be reverted. At the very least, even the downloadable robo.phar (v0.4.7) does not work in my build environment.
PHP Warning: require(phar:///path/to/robo.phar/vendor/codeception/verify/src/Codeception/function.php): failed to open stream: phar error: "vendor/codeception/verify/src/Codeception/function.php" is not a file in phar "/path/to/robo.phar" in phar:///path/to/robo.phar/vendor/composer/autoload_real.php on line 58
PHP Fatal error: require(): Failed opening required 'phar:///path/to/robo.phar/vendor/codeception/verify/src/Codeception/function.php' (include_path='phar:///path/to/robo.phar/vendor/phpunit/php-text-template:phar:///path/to/robo.phar/vendor/phpunit/php-timer:phar:///path/to/robo.phar/vendor/phpunit/php-file-iterator:phar:///path/to/robo.phar/vendor/phpunit/php-code-coverage:.:/usr/share/php:/usr/share/pear') in phar:///path/to/robo.phar/vendor/composer/autoload_real.php on line 58
prompt] $ php ./robo.phar -v
PHP Warning: require(phar:///path/to/robo.phar/vendor/codeception/verify/src/Codeception/function.php): failed to open stream: phar error: "vendor/codeception/verify/src/Codeception/function.php" is not a file in phar "/path/to/robo.phar" in phar:///path/to/robo.phar/vendor/composer/autoload_real.php on line 58
PHP Fatal error: require(): Failed opening required 'phar:///path/to/robo.phar/vendor/codeception/verify/src/Codeception/function.php' (include_path='phar:///path/to/robo.phar/vendor/phpunit/php-text-template:phar:///path/to/robo.phar/vendor/phpunit/php-timer:phar:///path/to/robo.phar/vendor/phpunit/php-file-iterator:phar:///path/to/robo.phar/vendor/phpunit/php-code-coverage:.:/usr/share/php:/usr/share/pear') in phar:///path/to/robo.phar/vendor/composer/autoload_real.php on line 58
Artifact size: 6.9MB robo.phar
[Robo\Task\PackPharTask] creating robo.phar
[Robo\Task\PackPharTask] packing 1725 files into phar
1725/1725 [============================] 100%
[Robo\Task\PackPharTask] robo.phar produced
Artifact size: 6.9MB
prompt] $ ./robo phar:build
[Robo\Task\ComposerInstallTask] Installing Packages: php composer.phar install --no-dev
[Robo\Task\PackPharTask] creating robo.phar
[Robo\Task\PackPharTask] packing 406 files into phar
406/406 [============================] 100%
[Robo\Task\PackPharTask] robo.phar produced
[Robo\Task\ComposerInstallTask] Installing Packages: php composer.phar install
Artifact size: 1.6MB robo.phar
(and it works)
public function watch()
{
$this->taskWatch()->monitor(...
Today I hum Process In Linux crontab What hum run php script in schedule A Day Given Once daily.
I can do this with robo using watch?
if you can help please thank you
As I understand currently there is no way to pass options to task (like in a way this "--opt1 value1 --opt2 value2").
Personally I feel that unordered options are even more preferable input way as for Build script, than ordered Arguments. As there could be very big amount of params needed for some task and it is very easy to get a mess of them.
The issue is that I can't event parse "--" options somewhere inside Task as Symfony Console tries to parse it before and throws exception due to not defined options.
With a very dirty hack of Runner I was able to pass them inside Task
protected function createCommand($taskName)
{
$taskInfo = new TaskInfo(self::ROBOCLASS, $taskName);
$task = new Command($taskInfo->getName());
$task->setDescription($taskInfo->getDescription());
$args = $taskInfo->getArguments();
foreach ($args as $name => $val) {
if ($val === TaskInfo::PARAM_IS_REQUIRED) {
$task->addOption($name, null, InputOption::VALUE_REQUIRED);
} else {
$task->addOption($name, null, InputOption::VALUE_OPTIONAL, '', $val);
}
}
return $task;
}
but I definitely fill that it require better approach. What do you think about having such possibility in Robo ?
Hello,
Just tried to use coverageHtml method for the codeception task and saw that it passes an incorrect option.
https://github.com/Codegyre/Robo/blob/master/src/Task/Codeception.php#L181-185
In my Drush Task (https://github.com/boedah/robo-drush/blob/master/src/Drush.php#L51), I extend from CommandStack (to use exec
and run
) and use Trait Executable (to use option
and arg
).
The task fails with the latest Robo version (works with 0.4.4) with the message:
ERROR: Robo\Task\Shared\CommandStack and Robo\Task\Shared\Executable define the same property ($workingDirectory) in the composition of Boedah\Robo\Task\DrushStackTask
. This might be incompatible, to improve maintainability consider using accessor methods in traits instead.
I could remove the extension from CommandStack but then have to copy and paste all but printed()
and dir()
(which is bad).
I think you could leverage this by renaming workingDirectory
in CommandStack to something else (workingDir
?).
Of course this would mean a BC break, if someone is already setting workingDirectory in CommandStack directly (and not via dir()
).
Maybe you could also make this variable private?
Another option, which comes into my mind:
CommandStack and Executable both define printed()
and dir()
.
Maybe CommandStack can use Executable somehow?
But I think this is not easily possible (too much traits seem to get rather messy...).
What do you think?
Hi,
Is there a way to run a command in the background but wait for it to "start up".
I'm starting a php internal webserver and phantomjs driver, but behat testing fails in the first 5-10 cases because both server and phantomjs aren't started yet.
Or should this be a process in the background?
Thx!
New in Robo 0.5.0 (also see #87).
Prereq:
Task which extends CommandStack and wants to use ExecOneCommand (for arg, args, options).
ERROR: Robo\Task\CommandStack and Robo\Common\ExecOneCommand define the same property ($finishedAt) in the composit
ion of Boedah\Robo\Task\Drush\DrushStack. This might be incompatible, to improve maintainability consider using acc
essor methods in traits instead.
Wow! I found Robo and it's awesome!
I'm searching for a tasker where I can add tasks "on-the-fly", like this:
// manager.php
$manager = new Manager();
foreach (glob('modules/*/scripts/*.installer.php') as $filename) {
call_user_func(function ($manager, $filename) {
include $filename;
}, $manager, $filename);
}
$manager->run();
// modules/admin/scripts/structure.installer.php
use Admin\Installer\Structure as StructureInstaller;
$manager->add(new StructureInstaller());
It's something like add tasks in Robo at the beggining, like:
class RoboFile extends \Robo\Tasks
{
public function install()
{
foreach (glob('modules/*/scripts/*.installer.php') as $filename) {
call_user_func(function ($robo, $filename) {
include $filename;
}, $this, $filename);
}
$this->taskInstall();
}
}
Can I do this?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.