/** * @param \Robo\Contract\TaskInterface $task * @param array $constructorParameters */ public function __construct(TaskInterface $task, $constructorParameters) { // TODO: If we ever want to convert the simulated task back into // an executable task, then we should save the wrapped task. $this->task = $task instanceof WrappedTaskInterface ? $task->original() : $task; $this->constructorParameters = $constructorParameters; }
/** * Calling the task builder with methods of the current * task calls through to that method of the task. * * There is extra complexity in this function that could be * simplified if we attached the 'LoadAllTasks' and custom tasks * to the collection builder instead of the RoboFile. While that * change would be a better design overall, it would require that * the user do a lot more work to set up and use custom tasks. * We therefore take on some additional complexity here in order * to allow users to maintain their tasks in their RoboFile, which * is much more convenient. * * Calls to $this->collectionBuilder()->taskFoo() cannot be made * directly because all of the task methods are protected. These * calls will therefore end up here. If the method name begins * with 'task', then it is eligible to be used with the builder. * * When we call getBuiltTask, below, it will use the builder attached * to the commandfile to build the task. However, this is not what we * want: the task needs to be built from THIS collection builder, so that * it will be affected by whatever state is active in this builder. * To do this, we have two choices: 1) save and restore the builder * in the commandfile, or 2) clone the commandfile and set this builder * on the copy. 1) is vulnerable to failure in multithreaded environments * (currently not supported), while 2) might cause confusion if there * is shared state maintained in the commandfile, which is in the * domain of the user. * * Note that even though we are setting up the commandFile to * use this builder, getBuiltTask always creates a new builder * (which is constructed using all of the settings from the * commandFile's builder), and the new task is added to that. * We therefore need to transfer the newly built task into this * builder. The temporary builder is discarded. * * @param string $fn * @param array $args * * @return $this|mixed */ public function __call($fn, $args) { if (preg_match('#^task[A-Z]#', $fn) && method_exists($this->commandFile, 'getBuiltTask')) { $saveBuilder = $this->commandFile->getBuilder(); $this->commandFile->setBuilder($this); $temporaryBuilder = $this->commandFile->getBuiltTask($fn, $args); $this->commandFile->setBuilder($saveBuilder); if (!$temporaryBuilder) { throw new \BadMethodCallException("No such method {$fn}: task does not exist in " . get_class($this->commandFile)); } $temporaryBuilder->getCollection()->transferTasks($this); return $this; } if (!isset($this->currentTask)) { throw new \BadMethodCallException("No such method {$fn}: current task undefined in collection builder."); } // If the method called is a method of the current task, // then call through to the current task's setter method. $result = call_user_func_array([$this->currentTask, $fn], $args); // If something other than a setter method is called, then return its result. $currentTask = $this->currentTask instanceof WrappedTaskInterface ? $this->currentTask->original() : $this->currentTask; if (isset($result) && $result !== $currentTask) { return $result; } return $this; }
/** * Create a CompletionWrapper. * * Temporary tasks are always wrapped in a CompletionWrapper, as are * any tasks that are added to a collection. If a temporary task * is added to a collection, then it is first unwrapped from its * CompletionWrapper (via its original() method), and then added to a * new CompletionWrapper for the collection it is added to. * * In this way, when the CompletionWrapper is finally executed, the * task's rollback and completion handlers will be registered on * whichever collection it was registered on. * * @todo Why not CollectionInterface the type of the $collection argument? * * @param \Robo\Collection\Collection $collection * @param \Robo\Contract\TaskInterface $task * @param \Robo\Contract\TaskInterface|NULL $rollbackTask */ public function __construct(Collection $collection, TaskInterface $task, TaskInterface $rollbackTask = null) { $this->collection = $collection; $this->task = $task instanceof WrappedTaskInterface ? $task->original() : $task; $this->rollbackTask = $rollbackTask; }
/** * @param TaskInterface|NestedCollectionInterface|WrappedTaskInterface $task * * @return \Robo\Result */ protected function runSubtask($task) { $original = $task instanceof WrappedTaskInterface ? $task->original() : $task; $this->setParentCollectionForTask($original, $this->getParentCollection()); if ($original instanceof InflectionInterface) { $original->inflect($this); } $taskResult = $task->run(); return $taskResult; }