mirror of
https://github.com/deployphp/deployer.git
synced 2025-02-23 00:32:25 +01:00
Refactor Deployer 🐘
This commit is contained in:
parent
1bb8fb38f2
commit
eb95635eba
2
bin/dep
2
bin/dep
@ -22,5 +22,5 @@ if(is_file($deployFile) && is_readable($deployFile)) {
|
||||
|
||||
$deployer->run();
|
||||
} else {
|
||||
echo "deploy.php file does not found.";
|
||||
echo "deploy.php file does not found.\n";
|
||||
}
|
@ -9,10 +9,12 @@ namespace Deployer\Console;
|
||||
|
||||
use Deployer\Deployer;
|
||||
use Deployer\Server\Current;
|
||||
use Deployer\Server\DryRun;
|
||||
use Deployer\TaskInterface;
|
||||
use Symfony\Component\Console\Command\Command as BaseCommand;
|
||||
use Symfony\Component\Console\Input\InputDefinition;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
class Command extends BaseCommand
|
||||
@ -30,12 +32,52 @@ class Command extends BaseCommand
|
||||
{
|
||||
parent::__construct($name);
|
||||
$this->task = $task;
|
||||
$this->setDescription($task->getDescription());
|
||||
$this->addOption(
|
||||
'dry-run',
|
||||
null,
|
||||
InputOption::VALUE_NONE,
|
||||
'Run without execution command on servers.'
|
||||
);
|
||||
$this->addOption(
|
||||
'server',
|
||||
null,
|
||||
InputOption::VALUE_OPTIONAL,
|
||||
'Run tasks only on ths server.',
|
||||
null
|
||||
);
|
||||
}
|
||||
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
if (OutputInterface::VERBOSITY_NORMAL <= $output->getVerbosity()) {
|
||||
$output->writeln("<info>"
|
||||
. (empty($this->getDescription()) ? $this->getName() : $this->getDescription())
|
||||
. "</info>"
|
||||
);
|
||||
}
|
||||
|
||||
foreach (Deployer::$servers as $name => $server) {
|
||||
|
||||
if (OutputInterface::VERBOSITY_VERY_VERBOSE <= $output->getVerbosity()) {
|
||||
$output->writeln("Run task <info>{$this->getName()}</info> on server <info>{$name}</info>");
|
||||
}
|
||||
|
||||
// Skip to specified server.
|
||||
$onServer = $input->getOption('server');
|
||||
if (null !== $onServer && $onServer !== $name) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Convert to dry run.
|
||||
if ($input->getOption('dry-run')) {
|
||||
$server = new DryRun($server->getConfiguration());
|
||||
}
|
||||
|
||||
// Set current server.
|
||||
Current::setServer($name, $server);
|
||||
|
||||
// Run task.
|
||||
$this->task->run();
|
||||
}
|
||||
}
|
||||
|
@ -35,6 +35,12 @@ class Configuration
|
||||
*/
|
||||
private $port;
|
||||
|
||||
/**
|
||||
* Base path of server.
|
||||
* @var string
|
||||
*/
|
||||
private $path;
|
||||
|
||||
/**
|
||||
* User of remote server.
|
||||
* @var string
|
||||
@ -81,6 +87,16 @@ class Configuration
|
||||
$this->setPort($port);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $path
|
||||
* @return $this
|
||||
*/
|
||||
public function path($path)
|
||||
{
|
||||
$this->path = $path;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Define user name for authentication.
|
||||
* @param string $name
|
||||
@ -158,6 +174,14 @@ class Configuration
|
||||
return $this->password;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getPath()
|
||||
{
|
||||
return $this->path;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
|
64
src/Server/DryRun.php
Normal file
64
src/Server/DryRun.php
Normal file
@ -0,0 +1,64 @@
|
||||
<?php
|
||||
/* (c) Anton Medvedev <anton@elfet.ru>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Deployer\Server;
|
||||
|
||||
class DryRun implements ServerInterface
|
||||
{
|
||||
/**
|
||||
* @var Configuration
|
||||
*/
|
||||
private $config;
|
||||
|
||||
/**
|
||||
* @param Configuration $config
|
||||
*/
|
||||
public function __construct(Configuration $config)
|
||||
{
|
||||
$this->config = $config;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function connect()
|
||||
{
|
||||
writeln("[{$this->config->getHost()}] Connecting to server.");
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function run($command)
|
||||
{
|
||||
writeln("[{$this->config->getHost()}] Run command: {$command}.");
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function upload($local, $remote)
|
||||
{
|
||||
writeln("[{$this->config->getHost()}] Upload file {$local} to {$remote}");
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function download($local, $remote)
|
||||
{
|
||||
writeln("[{$this->config->getHost()}] Download file {$remote} to {$local}");
|
||||
}
|
||||
|
||||
/**
|
||||
*{@inheritdoc}
|
||||
*/
|
||||
public function getConfiguration()
|
||||
{
|
||||
return $this->config;
|
||||
}
|
||||
}
|
@ -119,4 +119,11 @@ class PhpSecLib implements ServerInterface
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*{@inheritdoc}
|
||||
*/
|
||||
public function getConfiguration()
|
||||
{
|
||||
return $this->config;
|
||||
}
|
||||
}
|
@ -34,4 +34,9 @@ interface ServerInterface
|
||||
* @param string $remote Which file to download from remote server.
|
||||
*/
|
||||
public function download($local, $remote);
|
||||
|
||||
/**
|
||||
* @return Configuration
|
||||
*/
|
||||
public function getConfiguration();
|
||||
}
|
@ -133,4 +133,12 @@ class Ssh2 implements ServerInterface
|
||||
throw new \RuntimeException('Can not download file.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*{@inheritdoc}
|
||||
*/
|
||||
public function getConfiguration()
|
||||
{
|
||||
return $this->config;
|
||||
}
|
||||
}
|
@ -7,7 +7,9 @@
|
||||
|
||||
namespace Deployer;
|
||||
|
||||
class Task implements TaskInterface
|
||||
use Deployer\Task\AbstractTask;
|
||||
|
||||
class Task extends AbstractTask
|
||||
{
|
||||
/**
|
||||
* Callable body of current task.
|
||||
@ -24,7 +26,7 @@ class Task implements TaskInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* Run callback of current task.
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
|
38
src/Task/AbstractTask.php
Normal file
38
src/Task/AbstractTask.php
Normal file
@ -0,0 +1,38 @@
|
||||
<?php
|
||||
/* (c) Anton Medvedev <anton@elfet.ru>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Deployer\Task;
|
||||
|
||||
use Deployer\TaskInterface;
|
||||
|
||||
abstract class AbstractTask implements TaskInterface
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $description;
|
||||
|
||||
/**
|
||||
* Set task description
|
||||
* @param string $description
|
||||
* @return $this
|
||||
*/
|
||||
public function description($description)
|
||||
{
|
||||
$this->description = $description;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Description of task.
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription()
|
||||
{
|
||||
return $this->description;
|
||||
}
|
||||
}
|
@ -17,7 +17,7 @@ class TaskFactory
|
||||
* Create task and save to tasks list.
|
||||
* @param string $name Task name.
|
||||
* @param callable|array $callback Code of task or array of other tasks.
|
||||
* @return TaskInterface
|
||||
* @return AbstractTask
|
||||
*/
|
||||
public static function create($name, $callback)
|
||||
{
|
||||
|
@ -9,5 +9,8 @@ namespace Deployer;
|
||||
|
||||
interface TaskInterface
|
||||
{
|
||||
/**
|
||||
* Run current task.
|
||||
*/
|
||||
public function run();
|
||||
}
|
81
src/Utils/Path.php
Normal file
81
src/Utils/Path.php
Normal file
@ -0,0 +1,81 @@
|
||||
<?php
|
||||
/* (c) Anton Medvedev <anton@elfet.ru>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Deployer\Utils;
|
||||
|
||||
/**
|
||||
* Path utils
|
||||
*
|
||||
* @package Gaufrette
|
||||
* @author Antoine Hérault <antoine.herault@gmail.com>
|
||||
*/
|
||||
class Path
|
||||
{
|
||||
/**
|
||||
* Normalizes the given path
|
||||
*
|
||||
* @param string $path
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function normalize($path)
|
||||
{
|
||||
$path = str_replace('\\', '/', $path);
|
||||
$prefix = static::getAbsolutePrefix($path);
|
||||
$path = substr($path, strlen($prefix));
|
||||
$parts = array_filter(explode('/', $path), 'strlen');
|
||||
$tokens = array();
|
||||
|
||||
foreach ($parts as $part) {
|
||||
switch ($part) {
|
||||
case '.':
|
||||
continue;
|
||||
case '..':
|
||||
if (0 !== count($tokens)) {
|
||||
array_pop($tokens);
|
||||
continue;
|
||||
} elseif (!empty($prefix)) {
|
||||
continue;
|
||||
}
|
||||
default:
|
||||
$tokens[] = $part;
|
||||
}
|
||||
}
|
||||
|
||||
return $prefix . implode('/', $tokens);
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates whether the given path is absolute or not
|
||||
*
|
||||
* @param string $path A normalized path
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public static function isAbsolute($path)
|
||||
{
|
||||
return '' !== static::getAbsolutePrefix($path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the absolute prefix of the given path
|
||||
*
|
||||
* @param string $path A normalized path
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function getAbsolutePrefix($path)
|
||||
{
|
||||
preg_match('|^(?P<prefix>([a-zA-Z]+:)?//?)|', $path, $matches);
|
||||
|
||||
if (empty($matches['prefix'])) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return strtolower($matches['prefix']);
|
||||
}
|
||||
}
|
@ -5,9 +5,9 @@
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
use Deployer\Deployer;
|
||||
use Deployer\Parameter;
|
||||
use Deployer\Server;
|
||||
use Deployer\Task;
|
||||
use Deployer\Utils\Path;
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
@ -24,7 +24,7 @@ function server($name, $domain, $port = 22)
|
||||
* Define a new task and save to tasks list.
|
||||
* @param string $name Name of current task.
|
||||
* @param callable|array $callback Callable task or array of names of other tasks.
|
||||
* @return \Deployer\TaskInterface
|
||||
* @return \Deployer\Task\AbstractTask
|
||||
*/
|
||||
function task($name, $callback)
|
||||
{
|
||||
@ -39,6 +39,11 @@ function task($name, $callback)
|
||||
function run($command)
|
||||
{
|
||||
$server = Server\Current::getServer();
|
||||
|
||||
if (output()->isDebug()) {
|
||||
writeln("[{$server->getConfiguration()->getHost()}] $command");
|
||||
}
|
||||
|
||||
return $server->run($command);
|
||||
}
|
||||
|
||||
@ -50,7 +55,47 @@ function run($command)
|
||||
function upload($local, $remote)
|
||||
{
|
||||
$server = Server\Current::getServer();
|
||||
$server->upload($local, $remote);
|
||||
|
||||
$remote = $server->getConfiguration()->getPath() . '/' . $remote;
|
||||
|
||||
if (is_file($local)) {
|
||||
|
||||
writeln("Upload file <info>$local</info> to <info>$remote</info>");
|
||||
|
||||
$server->upload($local, $remote);
|
||||
|
||||
} elseif (is_dir($local)) {
|
||||
|
||||
writeln("Upload from <info>$local</info> to <info>$remote</info>");
|
||||
|
||||
$finder = new Symfony\Component\Finder\Finder();
|
||||
$files = $finder
|
||||
->files()
|
||||
->ignoreUnreadableDirs()
|
||||
->ignoreVCS(true)
|
||||
->ignoreDotFiles(false)
|
||||
->in($local);
|
||||
|
||||
if (output()->isVerbose()) {
|
||||
$progress = progressHelper($files->count());
|
||||
}
|
||||
|
||||
/** @var $file \Symfony\Component\Finder\SplFileInfo */
|
||||
foreach ($files as $file) {
|
||||
|
||||
$server->upload(
|
||||
$file->getRealPath(),
|
||||
Path::normalize($remote . '/' . $file->getRelativePathname())
|
||||
);
|
||||
|
||||
if (output()->isVerbose()) {
|
||||
$progress->advance();
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
throw new \RuntimeException("Uploading path '$local' does not exist.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -108,12 +153,15 @@ function get($key, $default)
|
||||
*/
|
||||
function ask($message, $default)
|
||||
{
|
||||
$output = Deployer::get()->getOutput();
|
||||
if (output()->isQuiet()) {
|
||||
return $default;
|
||||
}
|
||||
|
||||
$dialog = Deployer::get()->getConsole()->getHelperSet()->get('dialog');
|
||||
|
||||
$message = "<question>$message [$default]</question> ";
|
||||
|
||||
return $dialog->ask($output, $message, $default);
|
||||
return $dialog->ask(output(), $message, $default);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -123,12 +171,15 @@ function ask($message, $default)
|
||||
*/
|
||||
function askConfirmation($message, $default = false)
|
||||
{
|
||||
$output = Deployer::get()->getOutput();
|
||||
if (output()->isQuiet()) {
|
||||
return $default;
|
||||
}
|
||||
|
||||
$dialog = Deployer::get()->getConsole()->getHelperSet()->get('dialog');
|
||||
|
||||
$message = "<question>$message [y/n]</question> ";
|
||||
|
||||
if (!$dialog->askConfirmation($output, $message, $default)) {
|
||||
if (!$dialog->askConfirmation(output(), $message, $default)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -141,10 +192,28 @@ function askConfirmation($message, $default = false)
|
||||
*/
|
||||
function askHiddenResponse($message)
|
||||
{
|
||||
$output = Deployer::get()->getOutput();
|
||||
$dialog = Deployer::get()->getConsole()->getHelperSet()->get('dialog');
|
||||
|
||||
$message = "<question>$message</question> ";
|
||||
|
||||
return $dialog->askHiddenResponse($output, $message);
|
||||
return $dialog->askHiddenResponse(output(), $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $count
|
||||
* @return \Symfony\Component\Console\Helper\ProgressHelper
|
||||
*/
|
||||
function progressHelper($count)
|
||||
{
|
||||
$progress = Deployer::get()->getConsole()->getHelperSet()->get('progress');
|
||||
$progress->start(output(), $count);
|
||||
return $progress;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Symfony\Component\Console\Output\Output
|
||||
*/
|
||||
function output()
|
||||
{
|
||||
return Deployer::get()->getOutput();
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user