Skip to content

Instantly share code, notes, and snippets.

@crisu83
Created July 23, 2013 14:59
Show Gist options
  • Save crisu83/6063014 to your computer and use it in GitHub Desktop.
Save crisu83/6063014 to your computer and use it in GitHub Desktop.
Console command for creating, activating and deleting environments.
<?php
/**
* DeployCommand class file.
* @author Christoffer Niska <christoffer.niska@gmail.com>
* @copyright Copyright &copy; Christoffer Niska 2013-
* @license http://www.opensource.org/licenses/bsd-license.php New BSD License
* @package crisu83.yii-deploy.commands
*/
/**
* Console command for creating, activating and deleting environments.
*/
class DeployCommand extends CConsoleCommand
{
/**
* @var string the base path.
*/
public $basePath;
/**
* @var string the name of the owner user.
*/
public $user;
/**
* @var string the name of the owner group.
*/
public $group;
/**
* @var array list of directories that should be flushed.
*/
public $runtimeDirs = array(
'protected/runtime',
'assets',
);
/**
* @var array list of directories that should be writable.
*/
public $writable = array(
'protected/runtime',
'assets',
);
/**
* @var array list of directories that should be executable.
*/
public $executable = array(
'protected/yiic',
);
/**
* @var integer the permission for files that should be writable.
*/
public $writableMode = 0777;
/**
* @var integer the permission for files that should be executable.
*/
public $executableMode = 0755;
/**
* Provides the command description.
* @return string the command description.
*/
public function getHelp()
{
return <<<EOD
USAGE
yiic deploy <action> <options>
DESCRIPTION
Activates a specific environment by copying the associated files into the application.
EXAMPLES
* yiic deploy set prod
Activates the "prod" environment.
* yiic deploy create prod
Creates a "prod" environment.
* yiic deploy delete prod
Deletes the "prod" environment.
EOD;
}
public function init()
{
parent::init();
if (!isset($this->basePath)) {
$this->basePath = Yii::getPathOfAlias('webroot');
}
$this->basePath = rtrim($this->basePath, '/');
}
public function actionCreate($args)
{
// todo: write this
}
/**
* Executes the command.
* @param array $args command line parameters for this command.
* @return integer application exit code.
*/
public function actionSet($args)
{
if (!isset($args[0])) {
$this->usageError('The environment id is not specified.');
}
$id = $args[0];
$environmentPath = $this->basePath . '/environments/' . $id;
echo "\nCopying environment files... ";
$this->copyDirectory($environmentPath, $this->basePath);
echo "done\n";
foreach ($this->writable as $dir) {
$path = realpath($this->basePath . '/' . $dir);
$this->changeOwnership($path);
$this->changePermission($path, $this->writableMode);
}
foreach ($this->executable as $dir) {
$path = realpath($this->basePath . '/' . $dir);
$this->changeOwnership($path);
$this->changePermission($path, $this->executableMode);
}
echo "Flushing directories... ";
foreach ($this->runtimeDirs as $dir) {
$path = realpath($this->basePath . '/' . $dir);
$this->deleteDirectory($path, true);
$this->createDirectory($path);
}
echo "done\n";
echo "Environment successfully changed to '{$id}'.\n";
}
public function actionDelete($args)
{
// todo: write this
}
/**
* Creates a directory recursively.
* @param string $path the directory path.
* @param integer $mode the permission mode (default to 0777).
* @param boolean $recursive whether to create the directory recursively.
* @return boolean the result.
*/
protected function createDirectory($path, $mode = 0777, $recursive = true)
{
return !file_exists($path) ? mkdir($path, $mode, $recursive) : true;
}
/**
* Deletes a directory recursively.
* @param string $path the directory path.
* @param boolean $flushOnly whether to keep the root directory.
*/
protected function deleteDirectory($path, $flushOnly = false)
{
if (is_dir($path)) {
$files = scandir($path);
foreach ($files as $file) {
if (strpos($file, '.') !== 0) {
$filePath = $path . '/' . $file;
if (is_dir($filePath)) {
$this->deleteDirectory($filePath);
} else {
unlink($filePath);
}
}
}
if (!$flushOnly) {
rmdir($path);
}
}
}
/**
* Copies one directory to another recursively.
* @param string $source the source directory path.
* @param string $destination the destination directory path.
*/
protected function copyDirectory($source, $destination)
{
if (is_dir($source)) {
$handle = opendir($source);
while (($file = readdir($handle)) !== false) {
if (strpos($file, '.') !== 0) {
$sourcePath = $source . '/' . $file;
$destinationPath = $destination . '/' . $file;
if (is_dir($sourcePath)) {
$this->createDirectory($destinationPath);
$this->copyDirectory($sourcePath, $destinationPath);
} else {
copy($sourcePath, $destinationPath);
}
}
}
closedir($handle);
} else {
copy($source, $destination);
}
}
/**
* Changes both the owner and group for a directory is applicable.
* @param string $path the directory path.
*/
protected function changeOwnership($path)
{
if (isset($this->user)) {
$this->changeOwner($path, $this->user);
}
if (isset($this->group)) {
$this->changeGroup($path, $this->group);
}
}
/**
* Changes the owner for a directory.
* @param string $path the directory path.
* @param string $newOwner the name of the new owner.
*/
protected function changeOwner($path, $newOwner)
{
$ownerUid = fileowner($path);
$ownerData = posix_getpwuid($ownerUid);
$oldOwner = $ownerData['name'];
if ($oldOwner !== $this->user) {
echo sprintf("Changing ownership of %s (%s => %s)... ", $path, $oldOwner, $newOwner);
chown($path, $newOwner);
echo "done\n";
}
}
/**
* Changes the group for a directory.
* @param string $path the directory path.
* @param string $newGroup the name of the new group.
*/
protected function changeGroup($path, $newGroup)
{
$groupGid = filegroup($path);
$groupData = posix_getgrgid($groupGid);
$oldGroup = $groupData['name'];
if ($oldGroup !== $newGroup) {
echo sprintf("Changing group of %s (%s => %s)... ", $path, $oldGroup, $newGroup);
chgrp($path, $newGroup);
echo "done\n";
}
}
/**
* Changes the permissions for a directory.
* @param string $path the directory path.
* @param integer $mode the permission.
*/
protected function changePermission($path, $mode)
{
$oldPermission = substr(sprintf('%o', fileperms($path)), -4);
$newPermission = sprintf('%04o', $mode);
if ($oldPermission !== $newPermission) {
echo sprintf("Changing permissions of %s (%s => %s)... ", $path, $oldPermission, $newPermission);
chmod($path, $mode);
echo "done\n";
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment