翻译进度
6
分块数量
1
参与人数

3.4. 任务

这是一篇协同翻译的文章,你可以点击『我来翻译』按钮来参与翻译。

请对照 原文链接 进行翻译


Tasks

An important concept in Rocketeer are Tasks. Most of the commands you see right above are using predefined Tasks underneath, like Rocketeer\Tasks\Setup or Rocketeer\Tasks\Deploy. A lot of those are already defined by Rocketeer but you can add your own tasks to Rocketeer to execute custom actions on your server too.

A task can be one of a three things:

  • A simple one-line command which will be executed in the latest release's folder. Like composer install or an array of one-line commands.
  • A closure, giving you access to Rocketeer's core helpers which allow you to perform more advanced actions.
  • And finally a class, extending the Rocketeer\Abstracts\AbstractTask class, giving you full at-home control. All custom-made Tasks must have at least an execute method. And that's all.

Each level gives you a little more control and comfort – this is intentional. If you need more control than what Closures give you then you probably need a class.


Hooking into Rocketeer's Tasks

What most users will do is to hook into existing Rocketeer's Tasks. Rocketeer provides a built-in event system that allows you – at minimum – to execute actions before or after a Task's execution.

Defining Tasks in the config file

You can hook into any task via the hooks.php file in Rocketeer's config file. The syntax is pretty straightforward. Below you can see an example of three types of Tasks mentioned above:

<?php
'after' => array(
  'setup' => array(

    // Commands
    'composer install',

    // Actual Tasks classes
    'Rocketeer\Tasks\Cleanup',
    'MyNamespace\MyTaskClass',

    // Closures
    function($task) {
      $tests = $task->runForCurrentRelease('phpunit --coverage-html=tests/coverage');

      if ($tests) {
        $task->command->info('Tests ran perfectly dude !');
      } else {
        $task->command->error('Aw man, tests failed and stuff');
      }
    },

  ),
?>

Defining Tasks using the facade

Rocketeer also provides you with a facade you can use. It's especially useful if you don't want to put stuff in the config file, as it can get dirty when using closures.

Rocketeer allows two things: creating a .rocketeer/events.php file where all your hooks are contained or if you have more files like classes and want one file per task, you can simply create a .rocketeer/events/ folder and every task you put in it will automatically be loaded by Rocketeer.

<?php
use Rocketeer\Facades\Rocketeer;

Rocketeer::before('deploy', function($task) {
  $task->command->info('Sup guys');
});

Rocketeer::after(['update', 'deploy'], array(
  'composer install',
  'bower install'
));

Rocketeer::after('deploy', 'MyClass');
?>

As a first argument you give the name of a Task (or an array of names) you'd like to act on and then your task. Again, you can use the three types of tasks: strings, closures or classes.

Defining your own Tasks

Rocketeer also provides you with a task-running system to create, manage and run your own tasks. You can put those either in a .rocketeer/tasks.php file or - if you have a lot of them - in a ./rocketeer/tasks/ folder which will load all the files in it.

Via the facade

<?php
Rocketeer::task('composer', 'composer install');

Rocketeer::task('composer', array(
  'composer self-update',
  'composer install',
));

Rocketeer::task('phpunit', function ($task) {
  return $task->runForCurrentRelease('phpunit');
}, 'Runs the PHPUnit tests');
?>

The task method takes three arguments: name of the task, its execution (one-line command, closure, class) and a description of what it does.

These tasks will be automatically registered with Rocketeer. You'll then be able to execute them either via the CLI by doing for example php rocketeer composer or via the facade:

Rocketeer::execute('composer');

Rocketeer::execute(['composer', 'phpunit']);

Via classes

<?php
namespace MyTasks;

class Migrate extends \Rocketeer\Abstracts\AbstractTask
{
  /**
   * Description of the Task
   *
   * @var string
   */
  protected $description = 'Migrates the database';

  /**
   * Executes the Task
   *
   * @return void
   */
  public function execute()
  {
    $this->explainer->line('Running migrations');

    return $this->runForCurrentRelease('php artisan migrate --seed');
  }
}
?>

Classes aren't automatically registered with Rocketeer so you'll need to do that manually. You can either do so via the config file in the tasks.custom array:

'custom' => array(
  'MyTasks\Migrate',
),

or via the facade:

Rocketeer::add('MyTasks\Migrate');

And there you go, tadah!

TASKS

Executing tasks

Once a task is defined, it will be available in two places: the command line interface and the facade.

If you registered a task named composer, e.g. you'll be able to do this:

$ php rocketeer composer

Or in your PHP code (in tasks.php):

Rocketeer::execute('composer');

You can execute multiple tasks by passing an array of tasks. One thing that is crucial to remember is that Rocketeer will always process the queue you pass to it. That means you can pass anything that is considered as a task:

  • A string command.
  • A closure.
  • The name of a task.
  • The class of a task.
<?php
Rocketeer::execute(array(
  'my-task',

  'composer install',

  'Rocketeer\Tasks\Deploy',

  function ($task) {
    return $task->run('ls');
  },
));
?>

Executing tasks in local

In some cases you need to execute a series of commands in local and have the same comfort as you'd have executing things on the local server. This is only possible with actual Tasks classes. All you need to do is to set the local property to true:

class MyTask extends Rocketeer\Abstracts\AbstractTask
{
  protected $local = true;
}

From there, Rocketeer will delegate all calls to a LocalConnection class that acts the same as any Connection class but runs commands in the local system. This is useful for preparing the deploy and is how the Primer task works.


Writing Tasks

Core methods

The core method of any Task is the run method. This is the one that lays at the bottom of nearly every other helper.
It just runs commands on the remote server and returns the output.

<?php
$folders = $this->run('ls');
?>

You can also pass to it an array of commands to execute. Now, note this because it's important: every call to run is self contained. Meaning this (pwd returns the current folder):

<?php
// Returns /
$this->run('cd first-folder');
$folder = $this->run('pwd');

// Returns /first-folder/
$folder = $this->run(array(
  'cd first-folder',
  'pwd',
));
?>

Note also, that as soon as one of the commands fails (the exit status != 0), the rest of the commands passed to the same run call gets aborted. E.g., chown will try chowning everything that was requested, and even if all but just one of the many files does not get chowned because of permissions, the exit status will be 1 (regardless of --silent option), and any following commands will not actually get executed, even if they appear in the Rocketeer output as sent/run.

To automate running of tasks in folders two helpers exist: runInFolder and runForCurrentRelease. The first one will run one or more tasks in a folder, while the other will run one or more tasks in the current release's folder.

<?php
$this->run(array(
  'cd /home/www/website/releases/123456789',
  'ls',
));

// Is the same as

$this->runInFolder('releases/123456789', 'ls');

// Is the same as

$this->runForCurrentRelease('ls');
?>

Folder helpers

A few folder/file manipulation methods are also present. They're very basic and just abstracting low-level bash commands but, hey, they're good to have:

<?php
$this->move('folder/file.php', 'new-folder/file.php');

$array = $this->listContents('folder');

$boolean = $this->fileExists('file.php');
$boolean = $this->fileExists('folder');

$this->createFolder('folder');
$this->removeFolder('folder');

$this->symlink('folder-a', 'folder-b');

$phpunit = $this->which('phpunit', 'vendor/bin/phpunit'); // Second argument is fallback
?>

Tasks-related methods

Some methods are used by other Rocketeer tasks and can be utilized to create your own ones. All of them are relative to the current release.

<?php
// Run tests
$boolean = $this->runTests();
$boolean = $this->runTests('--stop-on-failure');

// Run migrations
$this->runMigrations();
$this->runMigrations(true); // Seeds the database too

// Run Composer
$this->runComposer();

// Set folders as web-writable
$this->setPermissions('public/images/users');
?>

External methods

Tasks also have access to the other classes of Rocketeer. You can call other tasks:

<?php
$this->executeTask('Rollback');

And call other classes's methods. All tasks and strategies have access to the following core classes and their methods:

  • command is the instance of the command currently running, to fetch options and arguments;
  • scm is the binary instance of the current SCM (git, SVN, etc.);
  • rocketeer is responsible for getting information on the current app and its configuration;
  • connections handles getting the current connection/stage/server and its respective credentials;
  • remote is your entry point to the server, it's the class the run method uses;
  • explainer is responsible for displaying the output, you'll use it to display e.g. progress in your tasks;
  • paths finds local and remote paths;
  • releasesManager handles releases and their paths;
  • localStorage class keeps the local storage file up to date, it tracks the remote server's state and credentials;
  • builder allows you to build tasks and strategies on the fly;
  • queue allows you to run tasks in a queue within your tasks;
  • tasks handles registration of tasks and their events, it's the class behind the Rocketeer facade.

你可以直接在 API 文档 中找到每个服务可用的方法列表。
它们可以作为属性访问,例如,要获取当前版本中的文件夹,你可以执行以下操作:

$folder = $task->releasesManager->getCurrentReleasePath('some/folder');
郁雁 翻译于 2年前

本文章首发在 LearnKu.com 网站上。

本文中的所有译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。

thebestxt
贡献者:1
讨论数量: 0
发起讨论 只看当前版本


暂无话题~