taskRsync() * ->fromPath('src/') * ->toHost('localhost') * ->toUser('dev') * ->toPath('/var/www/html/app/') * ->remoteShell('ssh -i public_key') * ->recursive() * ->excludeVcs() * ->checksum() * ->wholeFile() * ->verbose() * ->progress() * ->humanReadable() * ->stats() * ->run(); * ``` * * You could also clone the task and do a dry-run first: * * ``` php * $rsync = $this->taskRsync() * ->fromPath('src/') * ->toPath('example.com:/var/www/html/app/') * ->archive() * ->excludeVcs() * ->progress() * ->stats(); * * $dryRun = clone $rsync; * $dryRun->dryRun()->run(); * if ('y' === $this->ask('Do you want to run (y/n)')) { * $rsync->run(); * } * ``` */ class Rsync extends BaseTask implements CommandInterface { use \Robo\Common\ExecOneCommand; /** * @var string */ protected $command; /** * @var string */ protected $fromUser; /** * @var string */ protected $fromHost; /** * @var string */ protected $fromPath; /** * @var string */ protected $toUser; /** * @var string */ protected $toHost; /** * @var string */ protected $toPath; /** * @return static */ public static function init() { return new static(); } public function __construct() { $this->command = 'rsync'; } /** * This can either be a full rsync path spec (user@host:path) or just a path. * In case of the former do not specify host and user. * * @param string|array $path * * @return $this */ public function fromPath($path) { $this->fromPath = $path; return $this; } /** * This can either be a full rsync path spec (user@host:path) or just a path. * In case of the former do not specify host and user. * * @param string $path * * @return $this */ public function toPath($path) { $this->toPath = $path; return $this; } /** * @param string $fromUser * * @return $this */ public function fromUser($fromUser) { $this->fromUser = $fromUser; return $this; } /** * @param string $fromHost * * @return $this */ public function fromHost($fromHost) { $this->fromHost = $fromHost; return $this; } /** * @param string $toUser * * @return $this */ public function toUser($toUser) { $this->toUser = $toUser; return $this; } /** * @param string $toHost * * @return $this */ public function toHost($toHost) { $this->toHost = $toHost; return $this; } /** * @return $this */ public function progress() { $this->option(__FUNCTION__); return $this; } /** * @return $this */ public function stats() { $this->option(__FUNCTION__); return $this; } /** * @return $this */ public function recursive() { $this->option(__FUNCTION__); return $this; } /** * @return $this */ public function verbose() { $this->option(__FUNCTION__); return $this; } /** * @return $this */ public function checksum() { $this->option(__FUNCTION__); return $this; } /** * @return $this */ public function archive() { $this->option(__FUNCTION__); return $this; } /** * @return $this */ public function compress() { $this->option(__FUNCTION__); return $this; } /** * @return $this */ public function owner() { $this->option(__FUNCTION__); return $this; } /** * @return $this */ public function group() { $this->option(__FUNCTION__); return $this; } /** * @return $this */ public function times() { $this->option(__FUNCTION__); return $this; } /** * @return $this */ public function delete() { $this->option(__FUNCTION__); return $this; } /** * @param int $seconds * * @return $this */ public function timeout($seconds) { $this->option(__FUNCTION__, $seconds); return $this; } /** * @return $this */ public function humanReadable() { $this->option('human-readable'); return $this; } /** * @return $this */ public function wholeFile() { $this->option('whole-file'); return $this; } /** * @return $this */ public function dryRun() { $this->option('dry-run'); return $this; } /** * @return $this */ public function itemizeChanges() { $this->option('itemize-changes'); return $this; } /** * Excludes .git, .svn and .hg items at any depth. * * @return $this */ public function excludeVcs() { return $this->exclude([ '.git', '.svn', '.hg', ]); } /** * @param array|string $pattern * * @return $this */ public function exclude($pattern) { return $this->optionList(__FUNCTION__, $pattern); } /** * @param string $file * * @return $this * * @throws \Robo\Exception\TaskException */ public function excludeFrom($file) { if (!is_readable($file)) { throw new TaskException($this, "Exclude file $file is not readable"); } return $this->option('exclude-from', $file); } /** * @param array|string $pattern * * @return $this */ public function includeFilter($pattern) { return $this->optionList('include', $pattern); } /** * @param array|string $pattern * * @return $this */ public function filter($pattern) { return $this->optionList(__FUNCTION__, $pattern); } /** * @param string $file * * @return $this * * @throws \Robo\Exception\TaskException */ public function filesFrom($file) { if (!is_readable($file)) { throw new TaskException($this, "Files-from file $file is not readable"); } return $this->option('files-from', $file); } /** * @param string $command * * @return $this */ public function remoteShell($command) { $this->option('rsh', "$command"); return $this; } /** * {@inheritdoc} */ public function run() { $command = $this->getCommand(); return $this->executeCommand($command); } /** * Returns command that can be executed. * This method is used to pass generated command from one task to another. * * @return string */ public function getCommand() { foreach ((array)$this->fromPath as $from) { $this->option(null, $this->getFromPathSpec($from)); } $this->option(null, $this->getToPathSpec()); return $this->command . $this->arguments; } /** * @return string */ protected function getFromPathSpec($from) { return $this->getPathSpec($this->fromHost, $this->fromUser, $from); } /** * @return string */ protected function getToPathSpec() { return $this->getPathSpec($this->toHost, $this->toUser, $this->toPath); } /** * @param string $host * @param string $user * @param string $path * * @return string */ protected function getPathSpec($host, $user, $path) { $spec = isset($path) ? $path : ''; if (!empty($host)) { $spec = "{$host}:{$spec}"; } if (!empty($user)) { $spec = "{$user}@{$spec}"; } return $spec; } }