Modern and simple PHP task runner inspired by Gulp and Rake aimed to automate common tasks

Related tags

Task Runners robo
Overview

RoboTask

Modern and simple PHP task runner inspired by Gulp and Rake aimed to automate common tasks:

Gitter Latest Stable Version Latest Unstable Version Total Downloads

ci scrutinizer codecov license

  • writing cross-platform scripts
  • processing assets (less, sass, minification)
  • running tests
  • executing daemons (and workers)
  • watching filesystem changes
  • deployment with sftp/ssh/docker

Branches

Branch Support Level Symfony Versions League Container PHP Versions
3.x Stable 4 & 5 ^3 7.1 - 8.0
2.x Not recommended 4 & 5 ^2 7.1 - 7.4
1.x Not recommended 2 - 4 ^2 5.5 - 7.4

The pre-build robo.phar is built with Symfony 5, and requires PHP 7.2+. Robo also works with Symfony 4 and PHP 7.1.3+ if packaged as a library in another application. For Symfony 2 or 3 support, or PHP versions prior to 7.1, please use the Robo 1.x branch.

All three branches of Robo are currently supported, although the 2.x and 1.x branches receive minimum support. All versions are roughly compatible; the breaking changes introduced at each major version are fairly minor, and typically only affect classes that are not used by most clients.

Installing

Phar

Download robo.phar >

wget https://robo.li/robo.phar

To install globally put robo.phar in /usr/bin. (/usr/local/bin/ in OSX 10.11+)

chmod +x robo.phar && sudo mv robo.phar /usr/bin/robo

OSX 10.11+

chmod +x robo.phar && sudo mv robo.phar /usr/local/bin/robo

Now you can use it simply via robo.

Composer

  • Run composer require consolidation/robo:^3
  • Use vendor/bin/robo to execute Robo tasks.

Usage

All tasks are defined as public methods in RoboFile.php. It can be created by running robo init. All protected methods in traits that start with task prefix are tasks and can be configured and executed in your tasks.

Examples

The best way to learn Robo by example is to take a look into its own RoboFile or RoboFile of Codeception project. There are also some basic example commands in examples/RoboFile.php.

Here are some snippets from them:


Run acceptance test with local server and selenium server started.



use Robo\Symfony\ConsoleIO;

class RoboFile extends \Robo\Tasks
{

    function testAcceptance(ConsoleIO $io, $seleniumPath = '~/selenium-server-standalone-2.39.0.jar')
    {
       // launches PHP server on port 8000 for web dir
       // server will be executed in background and stopped in the end
       $this->collectionBuilder($io)->taskServer(8000)
            ->background()
            ->dir('web')
            ->run();

       // running Selenium server in background
       $this->collectionBuilder($io)->taskExec('java -jar ' . $seleniumPath)
            ->background()
            ->run();

       // loading Symfony Command and running with passed argument
       $this->collectionBuilder($io)->taskSymfonyCommand(new \Codeception\Command\Run('run'))
            ->arg('suite','acceptance')
            ->run();
    }
}

If you execute robo you will see this task added to list of available task with name: test:acceptance. To execute it you should run robo test:acceptance. You may change path to selenium server by passing new path as a argument:

robo test:acceptance "C:\Downloads\selenium.jar"

Using watch task so you can use it for running tests or building assets.


class RoboFile extends \Robo\Tasks {

    function watchComposer(ConsoleIO $io)
    {
        // when composer.json changes `composer update` will be executed
        $this->collectionBuilder($io)->taskWatch()->monitor('composer.json', function() {
            $this->collectionBuilder($io)->taskComposerUpdate()->run();
        })->run();
    }
}

Cleaning logs and cache


class RoboFile extends \Robo\Tasks
{
    public function clean(ConsoleIO $io)
    {
        $this->collectionBuilder($io)->taskCleanDir([
            'app/cache',
            'app/logs'
        ])->run();

        $this->collectionBuilder($io)->taskDeleteDir([
            'web/assets/tmp_uploads',
        ])->run();
    }
}

This task cleans app/cache and app/logs dirs (ignoring .gitignore and .gitkeep files) Can be executed by running:

robo clean

Creating Phar archive

function buildPhar(collectionBuilder $io)
{
    $files = Finder::create()->ignoreVCS(true)->files()->name('*.php')->in(__DIR__);
    $packer = $this->collectionBuilder($io)->taskPackPhar('robo.phar');
    foreach ($files as $file) {
        $packer->addFile($file->getRelativePathname(), $file->getRealPath());
    }
    $packer->addFile('robo','robo')
        ->executable('robo')
        ->run();
}

We need more tasks!

Create your own tasks and send them as Pull Requests or create packages with "type": "robo-tasks" in composer.json on Packagist.

Credits

Follow @robo_php for updates.

Brought to you by Consolidation Team and our awesome contributors.

License

MIT

Comments
  • Add task collections to Robo to support rollbacks and transient objects.

    Add task collections to Robo to support rollbacks and transient objects.

    Motivation

    Robo provides a very useful way to create quick scripts that are easy to write, and easy to read. Exception handling is avoided, so the script flow is generally linear and free from unnecessary conditionals.

    What if you wanted to ensure that a script always cleaned up its transient objects, and did not continue execution after one phase failed? Robo has a useful stop-on-fail mechanism, supported in the Result class (hard exit after any task fails), and some stacks (taskFileSystemStack) also have a stop-on-fail switch. This does not always give the opportunity to clean up easily. More complicated solutions run the risk of adding a lot of conditionals to scripts. We want to keep things simple and linear, even as scripts become more complex.

    Task Collections

    This PR expands on the idea of a task stack (which currently only works for operations that are all of the same kind) to also allow the creation of task collections. Multiple tasks of different types can be queued up in a single collection, and then executed. If one task fails, the rest of the tasks in the chain are not called. Rollback and completion tasks may also be provided to help clean up.

    Example

    $collection = $this->taskCollection();
    $this->taskFileSystemStack()
          ->mkdir('logs')
          ->touch('logs/.gitignore')
          ->chgrp('logs', 'www-data')
          ->symlink('/var/log/nginx/error.log', 'logs/error.log')
          ->collect($collection, $this->taskDeleteDir('logs'));
    /// ... collect other tasks
    $collection->run();
    

    The idea here is not to try to record every last chmod, and roll them back individually, but rather to collect operation results together in a target directory that can be cleaned up if the tasks do not finish, or left intact if all goes well. In the example above, collect() replaces the run() method; it serves the same purpose, except that execution is deferred, and a second task is provided to clean up in the event of a rollback. (n.b. Scripts that do not care about rollback can continue to use direct execution via the run() method.)

    collect() is provided via the Collectable trait, which is used by the BaseTask class, so all Robo tasks are collectable. If the collected task implements the RollbackInterface, then it will be called on any rollback. If the collected task implements the CompletionInterface, then it will be called if all tasks in a collection complete without errors, or if there is a rollback. Rollback and completion tasks are only called if the task itself was executed (or attempted to be executed).

    This PR also provides for transient objects, such as temporary directories, which are always cleaned up at the completion phase of a task collection. Simple single-threaded scripts may create temporary directories without using a collection, and these will be removed when the program terminates.

    Naming Things

    I put the collections in the Robo\TaskCollection namespace, although Robo\Task\Collection might have done as well. A collection of tasks technically isa task, and task collections can be nested; all the same, perhaps $collection = $this->taskCollection(); should just be $collection = new Collection();. Instead of collect(), I might have used defer(); other names might also do here. As it stands, everything fits in nicely with existing Robo code, which can continue to work as it currently does.

    Let me know if you have any suggestions or feedback here.

    WIP 
    opened by greg-1-anderson 41
  • Abstracting process execution logic into ExecTrait.php.

    Abstracting process execution logic into ExecTrait.php.

    • Moved process execution logic outside of ExecCommand.php and Exec.php into ExecTrait.php, which is now used by them both.
    • Added ProcessExecutor, which can be used outside of collection to execute arbitrary commands.
      • ProcessExecutor extends BaseTasks so that it is able to print messages to screen and log messages.
    • Added detectInteractive() method. $this->interactive now defaults to false.
    opened by grasmash 30
  • Recommendations for automated testing of Robo Scripts/Commands?

    Recommendations for automated testing of Robo Scripts/Commands?

    Hey Greg,

    What's the best way to go about testing custom Robo Scripts, or anything extending \Robo\Tasks?

    For example, say I wanted to assert the foo method said This is a Robo script, $name in https://github.com/consolidation/Robo/blob/master/examples/robo.script ?

    Or do any unit/functional tests exist that I can look at that test https://github.com/consolidation/Robo/blob/master/examples/src/Robo/Plugin/Commands/ExampleCommands.php ?

    Thanks!

    opened by defunctl 28
  • Add concept of build properties to Robo

    Add concept of build properties to Robo

    From #509:

    Most task runners incorporate the concept of a "build properties" file, which allows a set of key value pairs to be defined in a file and passed to the task runner at run time. One particularly useful feature of Ant and Phing is that they permit property expansion in such files, see build.yml for example. Additionally, there is a convention for overriding such properties via CLI arguments. E.g., robo -Dkey=value. Is there any precedent for using such a file with Robo?

    I've created a standalone tool that at least handles the property expansion feature: https://github.com/grasmash/yaml-expander

    Requirements:

    • [x] Look for YAML config file in default location and load prior to command execution. E.g., app/config.yml. Config should be parsed, expanded, and made available to commands through a service.
    • [x] Add ability to define runtime values for build properties. E.g., robo my:command --key=value. This would override values loaded from config file.
    opened by grasmash 22
  • Error installing: composer require henrikbjorn/lurker

    Error installing: composer require henrikbjorn/lurker

    Hi, I'm installing this composer require henrikbjorn/lurker, but I have this error:

    You are running composer with xdebug enabled. This has a major impact on runtime performance. See https://getcomposer.org/xdebug
    Do not run Composer as root/super user! See https://getcomposer.org/root for details
    Using version ^1.1 for henrikbjorn/lurker
    ./composer.json has been updated
    Loading composer repositories with package information
    Updating dependencies (including require-dev)
    Your requirements could not be resolved to an installable set of packages.
    
      Problem 1
        - Installation request for henrikbjorn/lurker ^1.1 -> satisfiable by henrikbjorn/lurker[1.1.0].
        - Conclusion: remove symfony/event-dispatcher v3.1.3
        - Conclusion: don't install symfony/event-dispatcher v3.1.3
        - henrikbjorn/lurker 1.1.0 requires symfony/event-dispatcher ~2.2 -> satisfiable by symfony/event-dispatcher[v2.2.0, v2.2.1, v2.2.10, v2.2.11, v2.2.2, v2.2.3, v2.2.4, v2.2.5, v2.2.6, v2.2.7, v2.2.8, v2.2.9, v2.3.0, v2.3.1, v2.3.10, v2.3.11, v2.3.12, v2.3.13, v2.3.14, v2.3.15, v2.3.16, v2.3.17, v2.3.18, v2.3.19, v2.3.2, v2.3.20, v2.3.21, v2.3.22, v2.3.23, v2.3.24, v2.3.25, v2.3.26, v2.3.27, v2.3.28, v2.3.29, v2.3.3, v2.3.30, v2.3.31, v2.3.32, v2.3.33, v2.3.34, v2.3.35, v2.3.36, v2.3.37, v2.3.38, v2.3.39, v2.3.4, v2.3.40, v2.3.41, v2.3.42, v2.3.5, v2.3.6, v2.3.7, v2.3.8, v2.3.9, v2.4.0, v2.4.0-RC1, v2.4.1, v2.4.10, v2.4.2, v2.4.3, v2.4.4, v2.4.5, v2.4.6, v2.4.7, v2.4.8, v2.4.9, v2.5.0, v2.5.0-RC1, v2.5.1, v2.5.10, v2.5.11, v2.5.12, v2.5.2, v2.5.3, v2.5.4, v2.5.5, v2.5.6, v2.5.7, v2.5.8, v2.5.9, v2.6.0, v2.6.1, v2.6.10, v2.6.11, v2.6.12, v2.6.13, v2.6.2, v2.6.3, v2.6.4, v2.6.5, v2.6.6, v2.6.7, v2.6.8, v2.6.9, v2.7.0, v2.7.1, v2.7.10, v2.7.11, v2.7.12, v2.7.13, v2.7.14, v2.7.15, v2.7.16, v2.7.17, v2.7.18, v2.7.19, v2.7.2, v2.7.3, v2.7.4, v2.7.5, v2.7.6, v2.7.7, v2.7.8, v2.7.9, v2.8.0, v2.8.1, v2.8.10, v2.8.11, v2.8.12, v2.8.2, v2.8.3, v2.8.4, v2.8.5, v2.8.6, v2.8.7, v2.8.8, v2.8.9].
        - Can only install one of: symfony/event-dispatcher[v2.5.0, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.5.0-RC1, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.5.1, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.5.10, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.5.11, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.5.12, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.5.2, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.5.3, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.5.4, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.5.5, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.5.6, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.5.7, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.5.8, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.5.9, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.6.0, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.6.1, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.6.10, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.6.11, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.6.12, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.6.13, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.6.2, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.6.3, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.6.4, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.6.5, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.6.6, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.6.7, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.6.8, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.6.9, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.7.0, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.7.1, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.7.10, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.7.11, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.7.12, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.7.13, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.7.14, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.7.15, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.7.16, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.7.17, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.7.18, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.7.19, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.7.2, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.7.3, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.7.4, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.7.5, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.7.6, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.7.7, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.7.8, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.7.9, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.8.0, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.8.1, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.8.10, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.8.11, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.8.12, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.8.2, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.8.3, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.8.4, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.8.5, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.8.6, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.8.7, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.8.8, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.8.9, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.2.0, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.2.1, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.2.10, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.2.11, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.2.2, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.2.3, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.2.4, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.2.5, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.2.6, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.2.7, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.2.8, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.2.9, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.3.0, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.3.1, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.3.10, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.3.11, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.3.12, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.3.13, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.3.14, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.3.15, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.3.16, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.3.17, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.3.18, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.3.19, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.3.2, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.3.20, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.3.21, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.3.22, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.3.23, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.3.24, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.3.25, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.3.26, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.3.27, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.3.28, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.3.29, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.3.3, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.3.30, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.3.31, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.3.32, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.3.33, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.3.34, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.3.35, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.3.36, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.3.37, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.3.38, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.3.39, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.3.4, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.3.40, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.3.41, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.3.42, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.3.5, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.3.6, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.3.7, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.3.8, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.3.9, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.4.0, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.4.0-RC1, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.4.1, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.4.10, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.4.2, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.4.3, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.4.4, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.4.5, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.4.6, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.4.7, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.4.8, v3.1.3].
        - Can only install one of: symfony/event-dispatcher[v2.4.9, v3.1.3].
        - Installation request for symfony/event-dispatcher (locked at v3.1.3) -> satisfiable by symfony/event-dispatcher[v3.1.3].
    
    
    Installation failed, reverting ./composer.json to its original content.
    
    opened by orozco1582 21
  • How to use output from tasks in subsequent tasks

    How to use output from tasks in subsequent tasks

    Steps to reproduce

    1. Task gets the filename of the recent database dump in an AWS S3 bucket using the AWS CLI.
    2. Task downloads the most recent database dump.

    Expected behavior

    I am expecting to be able to read the output of the command to determine the latest database dump and then use it in a second task to download that file.

    $result = $this->taskExec("aws s3 ls $bucket | tail -1 | awk -F ' ' '{print \$4}'")
      ->printOutput(FALSE)
      ->storeState('db-filename')
      ->run();
    $dbFilename = $result->getState('db-filename');
    

    Actual behavior

    I have read the Robo's documentation on chained state but I was unable to piece together how an example like mine would be best implemented. The closest I got was by using storeState() but it is unclear how I would reference that state arbitrarily in a subsequent exec(). Maybe what I am trying to do is possible via this method but if so, I am missing it.

    In the meantime, I have implemented what I need by using the Symfony Process component directly, but that seems less elegant than the functionality that Robo provides in other use cases.

    System Configuration

    macOS 10.15.6 PHP 7.4.9

    opened by markdorison 19
  • Task assembly

    Task assembly

    This PR introduces the concept of task assembly, which is done by way of the TaskAssembler, a helper object that helps do dependency injection on tasks that are created at runtime (as opposed to during container initialization, where the DI container can be used for this purpose).

    The old way to build tasks looks like this:

        protected function taskExtract($filename)
        {
            return new Extract($filename);
        }
    

    With task assembly, it now looks like this:

        protected function taskExtract($filename)
        {
            return $this->taskAssembler()->assemble(
                '\Robo\Task\Archive\Extract',
                [$filename]
            );
        }
    

    The benefit of using the task assembler is threefold:

    1. It will call setLogger & c. as necessary on the task, after it is constructed, reducing coupling between the different areas of the code.
    2. It recognizes tasks that implement CompletionInterface, and ensures their complete() method will be called at shutdown time, if the task is run().
    3. It also supports 'simulated' tasks, which print out what they would do when run() without actually making any persistent changes.

    This PR does not break backwards compatibility with existing external Robo tasks. Existing tasks that continue to use the old builder pattern will still work; however, they will silently ignore the --simulate flag, and execute instead. To break backwards compatibility and force old tasks to update, all that needs to be done is remove one of the last references to the Config class, and then all task printing operations will fail for tasks that have not updated to the new mechanism.

    WIP 
    opened by greg-1-anderson 19
  • Symfony 5 compatibility

    Symfony 5 compatibility

    Steps to reproduce

    Add a Symfony 5 package to your composer.json file:

    {
      "require": {
        "symfony/process": "^5.0.0"
      }
    }
    

    Expected behavior

    The installation of the Symfony 5 package succeeds.

    Actual behavior

    $ composer update
    Loading composer repositories with package information
    Updating dependencies (including require-dev)
    Your requirements could not be resolved to an installable set of packages.
    
      Problem 1
        - consolidation/robo 2.0.0 requires symfony/process ^4 -> satisfiable by symfony/process[4.0.x-dev, 4.1.x-dev, 4.2.x-dev, 4.3.x-dev, 4.4.x-dev, v4.0.0, v4.0.0-BETA1, v4.0.0-BETA2, v4.0.0-BETA3, v4.0.0-BETA4, v4.0.0-RC1, v4.0.0-RC2, v4.0.1, v4.0.10, v4.0.11, v4.0.12, v4.0.13, v4.0.14, v4.0.15, v4.0.2, v4.0.3, v4.0.4, v4.0.5, v4.0.6, v4.0.7, v4.0.8, v4.0.9, v4.1.0, v4.1.0-BETA1, v4.1.0-BETA2, v4.1.0-BETA3, v4.1.1, v4.1.10, v4.1.11, v4.1.12, v4.1.2, v4.1.3, v4.1.4, v4.1.5, v4.1.6, v4.1.7, v4.1.8, v4.1.9, v4.2.0, v4.2.0-BETA1, v4.2.0-BETA2, v4.2.0-RC1, v4.2.1, v4.2.10, v4.2.11, v4.2.12, v4.2.2, v4.2.3, v4.2.4, v4.2.5, v4.2.6, v4.2.7, v4.2.8, v4.2.9, v4.3.0, v4.3.0-BETA1, v4.3.0-BETA2, v4.3.0-RC1, v4.3.1, v4.3.2, v4.3.3, v4.3.4, v4.3.5, v4.3.6, v4.3.7, v4.3.8, v4.4.0, v4.4.0-BETA1, v4.4.0-BETA2, v4.4.0-RC1] but these conflict with your requirements or minimum-stability.
        - Installation request for consolidation/robo ^2.0.0 -> satisfiable by consolidation/robo[2.0.0].
    

    It would be cool if the version constraint of Symfony packages was relaxed. Something like:

    {
      "require": {
        "symfony/console": "^4.3.5 || ^5",
        "symfony/event-dispatcher": "^4 || ^5",
        "symfony/filesystem": "^4 || ^5",
        "symfony/finder": "^4 || ^5",
        "symfony/process": "^4 || ^5"
      }
    }
    

    See the Symfony policy about backward compatibility: https://symfony.com/doc/current/contributing/community/releases.html#backward-compatibility

    bug 
    opened by cedx 18
  • Refactoring for 0.5.0. Comments needed!

    Refactoring for 0.5.0. Comments needed!

    Robo Changes

    1. Tasks are located by following PSR-4 standard
    2. Task loading by traits are removed - this is done to simplify loading of tasks. Instead of declaring tasks in traits you can just call them with static initialization methods. Also you won't need to include lots of traits into RoboFile. Usage of static class calls instead of traits is aimed for simplicity. One task = one class = one file.
    3. Tasks initialization syntax changed to
    <?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:

    • robo
    • Robo
    • ????
    • Robo;

    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
    
    question 
    opened by DavertMik 17
  • Lay the groundwork for Robo plugins #670

    Lay the groundwork for Robo plugins #670

    Overview

    This pull request:

    • [ ] Fixes a bug
    • [x] Adds a feature
    • [x] Breaks backwards compatibility
    • [x] Has tests that cover changes

    Summary

    PR related to #670, current plan is:

    • [x] Add class discovery service + tests
    • [x] Add command discovery to Runner:run()
    • [x] ~Add event subscribers discovery~ This will be discussed in a follow-up issue.
    opened by ademarco 16
  • Adding printMetadata() option to exec command.

    Adding printMetadata() option to exec command.

    This PR introduces two new abilities:

    • Use exec task without printing command, working directory, and timer. This allows the task to be truly silent.$this->taskExec("something")->silent(true)->run();
    • Use exec task to print output but not print metadata, like the timer. This makes the call a bit more "passthru". $this->taskExec("something")->printOutput(true)->printMetadata(false)->run();
    opened by grasmash 15
  • Extended robo files are not parsed for commands for consolidation/annotated-command >= 4.5.7

    Extended robo files are not parsed for commands for consolidation/annotated-command >= 4.5.7

    Steps to reproduce

    1. Upgraded consolidation/annotated-command to a version >= 4.5.7 (4.6.0, in my case).
    2. Run vendor/bin/robo list

    I've tracked down the issue to this commit from this list of commits. I can see it skip over the command in my debugger because the class of the initially loaded robo file does not match the extended one.

    I believe it boils down to the way I've structured the RoboFile, which may be an anti-pattern, and I'm open to any suggestions.

    In the RoboFile, I extend another RoboFile. The original RoboFile is used to to override methods from the extended file. This wasn't done so much to completely replace a command but instead override the helper functions that were not commands but had full access to robo.

    RoboFile.php

    
    require_once 'RoboFileSite.php';
    
    class RoboFile extends \RoboFileSite
    {
        
    }
    

    RoboFileSite.php

    
    class RoboFileSite
    {
    
      function hello(\Robo\Symfony\ConsoleIO $io, array $world)
      {
        $io->say("Hello, " . implode(', ', $world));
      }
    }
    

    Expected behavior

    The 'hello' command is listed.

    Actual behavior

    The 'hello' command is not listed.

    System Configuration

    Linux PHP 8.1 wodby/php:8.1-dev-4.32.7

    opened by mattsqd 3
  • Incompatibility with PSR\Log

    Incompatibility with PSR\Log

    Setting up a new Drupal 10 project using Acquia BLT (which is built using Robo 3.x) I am noticing that...

    Drupal 10.x requires psr/log 3.x. However, robo has a setLogger method (https://github.com/consolidation/robo/blob/3.x/src/Common/TaskIO.php#L30) that isn't compatible with the psr/log 3.x (https://github.com/php-fig/log/blob/master/src/LoggerInterface.php#L124). So, spinning up a new codebase that has robo 3.x and Drupal 10.x I am hitting:

    PHP Fatal error:  Declaration of Robo\Task\BaseTask::setLogger(Psr\Log\LoggerInterface $logger) must be compatible with Psr\Log\LoggerAwareInterface::setLogger(Psr\Log\LoggerInterface $logger): void in /Users/mike.madison/git/examples/drupal10/vendor/consolidation/robo/src/Common/TaskIO.php on line 30
    
    Fatal error: Declaration of Robo\Task\BaseTask::setLogger(Psr\Log\LoggerInterface $logger) must be compatible with Psr\Log\LoggerAwareInterface::setLogger(Psr\Log\LoggerInterface $logger): void in /Users/mike.madison/git/examples/drupal10/vendor/consolidation/robo/src/Common/TaskIO.php on line 30
    
    

    Steps to reproduce

    In this case, I'm using... acquia/blt and drupal/10 and hitting this.

    Expected behavior

    If robo has a specific version of psr/log it is functional with, I would expect a version constraint in composer.json

    Actual behavior

    Robo requires consolidation/log which allows psr/log 3.x which itself isn't compatible with consolidation/robo 3.0.10

    opened by mikemadison13 3
  • How to get _exec return Message & Data for task capturing??  (Feature Request)

    How to get _exec return Message & Data for task capturing?? (Feature Request)

    I wrote a "acquia_deploy.php" that uses blt and robo to launch deploys. It works great except I can't seem to do simple things like get the task UUID back from an acquia launched task. Since I am a command line junky I like to do all things Acquia admin via the command line even though the Acquia web interface does all this for you.

    For example I have this batch script that copies the prod db down to the dev db as well as the files. After it launches those tasks it extracts the returned task UUID and launches another (sleep & and check status) bash script that will tell me when the task is done. This is very handy and I use it all the time

    
    #!/bin/bash -xv
    # Copy the database and files from production to dev.
    # Arg 1 should be either "dev" or "test" to specify a destination.
    
    db_copy_task=$(acli api:environments:database-copy @xxxx.$1 xxxxx @xxxx.prod | jq '._links.notification.href')
    file_copy_task=$(acli api:environments:file-copy @xxxxx.$1 --source=xxxxx-26f2-8a24-9d30-ad706573714a | jq '.links.notification.href')
    
    bin/acli_task_mon \"${db_copy_task##*/}
    bin/acli_task_mon \"${file_copy_task##*/}
    
    

    I'd love to be able to capture the returned task ID from the acli command WITHIN ROBO but from what I can tell there is no return data returned.

    So for example here is the code-switch call in robo:

          $this->_exec('acli api:environments:code-switch ' . $destEnvAlias . ' tags/' . $aTag . ' | jq \'._links.notification.href\'');
    

    Can I get a returned string from the _exec call?

    Possibly from: https://github.com/consolidation/robo/blob/4.x/src/Task/Base/Shortcuts.php#L16 or https://github.com/consolidation/robo/blob/4.x/src/Task/Base/Tasks.php#L14 or https://github.com/consolidation/robo/blob/4.x/src/Task/Base/Exec.php#L140

    It looks like what I want is in the Result data? or Result message?

    But it's not clear exactly how to get the data or message. Can anyone provide an example please?

    https://github.com/consolidation/robo/blob/4.x/src/ResultData.php

    Thank you.

    opened by danshumaker 0
  • Allow Parallelization Core Limits

    Allow Parallelization Core Limits

    Steps to reproduce

    When you run a command with parallelization it uses all of the CPU cores, which puts a higher than wanted load on our QA server that is already running builds for multiple environments in parallel at the Docker level (outside the scope of Robo).

    Expected behavior

    When you run a command with parallelization you can specify how many cores you want to use.

    Actual behavior

    I am unable to specify the number of cores I want to use.

    System Configuration

    This is all likely N/A to this issue, but I'm providing it anyways

    Proposed Change

    I assume such a change would be done in ParallelExec::run, presumably via a new property on the class with a setter method?

    • Has this been discussed before? (I couldn't find anything in the issue queue).
    • Would you be open to a PR that adds this functionality
    • Are there any gotchas or wisdom that you could share before I try to build something?
    opened by adamzimmermann 2
  • GenerateMarkdownDoc renders Boolean default values incorrectly

    GenerateMarkdownDoc renders Boolean default values incorrectly

    Steps to reproduce

    I generated markdown of public static function addNamespace(string $prefix, string $baseDir, bool $prepend = false): void

    Expected behavior

    *public static* addNamespace($prefix, $baseDir, $prepend = false)

    Actual behavior

    *public static* addNamespace($prefix, $baseDir, $prepend = )

    System Configuration

    Ubuntu 20.04, PHP 8.0.21

    The problem is that GenerateMarkdown uses print_r for rendering default values. print_r is completely unsuitable for printing Boolean values because it renders false as empty string and true as 1.

    I think that it would be better to use var_export instead.

    opened by Naktibalda 0
  • GenerateMarkdownDoc crashes if method parameter contains union or intersection type

    GenerateMarkdownDoc crashes if method parameter contains union or intersection type

    Steps to reproduce

    Try to generate markdown of method having union or intersection type.

    Expected behavior

    At the very least it shouldn't crash, bonus points if it generates correct documentation

    Actual behavior

    https://github.com/Codeception/codeception.github.com/runs/7592669736?check_suite_focus=true#step:6:112

     [Development\GenerateMarkdownDoc] Processing \Codeception\Util\Locator
    PHP Fatal error:  Uncaught Error: Call to undefined method ReflectionUnionType::getName() in /home/runner/work/codeception.github.com/codeception.github.com/vendor/consolidation/robo/src/Task/Development/GenerateMarkdownDoc.php:677
    Stack trace:
    #0 /home/runner/work/codeception.github.com/codeception.github.com/vendor/consolidation/robo/src/Task/Development/GenerateMarkdownDoc.php(732): Robo\Task\Development\GenerateMarkdownDoc->documentParam()
    

    Type Error happens because of public static function isPrecise(WebDriverBy|array|string $locator): bool

    System Configuration

    Ubuntu 20.04, PHP 8.0.21

    I will investigate this issue and raise PR to fix it.

    opened by Naktibalda 0
Releases(3.0.4)
Owner
Consolidation
Common projects for use by various command line / console tools.
Consolidation
Modern task runner for PHP

RoboTask Modern and simple PHP task runner inspired by Gulp and Rake aimed to automate common tasks: writing cross-platform scripts processing assets

Consolidation 2.6k Dec 4, 2022
A versatile and lightweight PHP task runner, designed with simplicity in mind.

Blend A versatile and lightweight PHP task runner, designed with simplicity in mind. Table of Contents About Blend Installation Config Examples API Ch

Marwan Al-Soltany 42 Sep 29, 2022
Pure PHP task runner

task/task Got a PHP project? Heard of Grunt and Gulp but don't use NodeJS? Task is a pure PHP task runner. Leverage PHP as a scripting language, and a

null 184 Sep 28, 2022
Awesome Task Runner

Bldr Simplified Build System/Task Runner Uses Yaml, JSON, XML, PHP, or INI for configs Quick Usage To develop, run ./script/bootstrap, and then ./scri

null 223 Nov 20, 2022
Laravel-Tasks is a Complete Build of Laravel 5.2 with Individual User Task Lists

An app of tasks lists for each individual user. Built on Laravel 5.2, using 5.2 authentication and middleware. This has robust verbose examples using Laravel best practices.

Jeremy Kenedy 26 Aug 27, 2022
Fluent API for Gulp.

Laravel Elixir Please note that this project has been archived. Instead, we recommend that you transition to Laravel Mix. Introduction Laravel Elixir

The Laravel Framework 1.1k Nov 4, 2022
Yii application runner

Yii application runner The package defines Yii application runner. Requirements PHP 7.4 or higher. Installation The package could be installed with co

Yii Software 9 Oct 15, 2022
🐺 Asynchronous Task Queue Based on Distributed Message Passing for PHP.

?? Asynchronous Task Queue Based on Distributed Message Passing for PHP.

Ahmed 36 Aug 11, 2022
A PHP implementation of a bare task loop.

TaskLoop A PHP implementation of a bare task loop. Installation. $ composer require thenlabs/task-loop 1.0.x-dev Usage. The file example.php contains

ThenLabs 1 Oct 17, 2022
Elegant SSH tasks for PHP.

Laravel Envoy Introduction Laravel Envoy provides a clean, minimal syntax for defining common tasks you run on your remote servers. Using Blade style

The Laravel Framework 1.5k Nov 25, 2022
Crunz is a framework-agnostic package to schedule periodic tasks (cron jobs) in PHP using a fluent API.

Crunz Install a cron job once and for all, manage the rest from the code. Crunz is a framework-agnostic package to schedule periodic tasks (cron jobs)

Reza Lavarian 1.4k Dec 1, 2022
xcron - the souped up, modernized cron/Task Scheduler for Windows, Mac OSX, Linux, and FreeBSD server and desktop operating systems.

xcron is the souped up, modernized cron/Task Scheduler for Windows, Mac OSX, Linux, and FreeBSD server and desktop operating systems. MIT or LGPL.

CubicleSoft 6 Oct 5, 2022
Manage your Laravel Task Scheduling in a friendly interface and save schedules to the database.

Documentation This librarian creates a route(default: /schedule) in your application where it is possible to manage which schedules will be executed a

Roberson Faria 252 Dec 1, 2022
Flow Framework Task Scheduler

This package provides a simple to use task scheduler for Neos Flow. Tasks are configured via settings, recurring tasks can be configured using cron syntax. Detailed options configure the first and last executions as well as options for the class handling the task.

Flowpack 10 Nov 7, 2022
Task Scheduling with Cron Job in Laravel

About Laravel Laravel is a web application framework with expressive, elegant syntax. We believe development must be an enjoyable and creative experie

Shariful Islam 1 Oct 16, 2021
Laravel Cron Scheduling - The ability to run the Laravel task scheduler using different crons

Laravel Cron Scheduling Laravel Task Scheduling is a great way to manage the cron. But the documentation contains the following warning: By default, m

Sergey Zhidkov 4 Sep 9, 2022
Reset the live preset for debug settings with a task

Debug Settings Task This TYPO3 extension resets TYPO3 debug settings to the »live« preset on production using a scheduler task. Vision “Better safe th

webit! Gesellschaft für neue Medien mbH 1 Aug 15, 2022
Create a docker container where various tasks are performed with different frequencies

?? Docker with task scheduler Introduction The goal is to create a docker container where various tasks are performed with different frequencies. For

Green.Mod 3 Jun 7, 2022
PHP port of resque (Workers and Queueing)

php-resque: PHP Resque Worker (and Enqueue) Resque is a Redis-backed library for creating background jobs, placing those jobs on one or more queues, a

Chris Boulton 3.5k Nov 23, 2022