@@ -9,94 +9,94 @@ |
||
| 9 | 9 | */ |
| 10 | 10 | class Args |
| 11 | 11 | { |
| 12 | - protected $namedArgs = array(); |
|
| 13 | - protected $unnamedArgs = array(); |
|
| 14 | - protected $action = null; |
|
| 12 | + protected $namedArgs = array(); |
|
| 13 | + protected $unnamedArgs = array(); |
|
| 14 | + protected $action = null; |
|
| 15 | 15 | |
| 16 | - public function __construct($args) |
|
| 17 | - { |
|
| 18 | - array_shift($args); |
|
| 16 | + public function __construct($args) |
|
| 17 | + { |
|
| 18 | + array_shift($args); |
|
| 19 | 19 | |
| 20 | - foreach ($args as $arg) { |
|
| 21 | - if (preg_match('/^--([^=]+)=(.*)$/', $arg, $matches)) { |
|
| 22 | - $this->namedArgs[$matches[1]] = $matches[2]; |
|
| 23 | - } elseif (preg_match('/^--([^=]+)$/', $arg, $matches)) { |
|
| 24 | - $this->namedArgs[$matches[1]] = true; |
|
| 25 | - } else { |
|
| 26 | - $this->unnamedArgs[] = $arg; |
|
| 27 | - } |
|
| 28 | - } |
|
| 20 | + foreach ($args as $arg) { |
|
| 21 | + if (preg_match('/^--([^=]+)=(.*)$/', $arg, $matches)) { |
|
| 22 | + $this->namedArgs[$matches[1]] = $matches[2]; |
|
| 23 | + } elseif (preg_match('/^--([^=]+)$/', $arg, $matches)) { |
|
| 24 | + $this->namedArgs[$matches[1]] = true; |
|
| 25 | + } else { |
|
| 26 | + $this->unnamedArgs[] = $arg; |
|
| 27 | + } |
|
| 28 | + } |
|
| 29 | 29 | |
| 30 | - $this->action = array_shift($this->unnamedArgs); |
|
| 31 | - } |
|
| 30 | + $this->action = array_shift($this->unnamedArgs); |
|
| 31 | + } |
|
| 32 | 32 | |
| 33 | - public function unshiftUnnamed($arg) |
|
| 34 | - { |
|
| 35 | - array_unshift($this->unnamedArgs, $arg); |
|
| 36 | - } |
|
| 33 | + public function unshiftUnnamed($arg) |
|
| 34 | + { |
|
| 35 | + array_unshift($this->unnamedArgs, $arg); |
|
| 36 | + } |
|
| 37 | 37 | |
| 38 | - public function getNamedArgs() |
|
| 39 | - { |
|
| 40 | - return $this->namedArgs; |
|
| 41 | - } |
|
| 38 | + public function getNamedArgs() |
|
| 39 | + { |
|
| 40 | + return $this->namedArgs; |
|
| 41 | + } |
|
| 42 | 42 | |
| 43 | - public function getUnnamedArgs() |
|
| 44 | - { |
|
| 45 | - return $this->unnamedArgs; |
|
| 46 | - } |
|
| 43 | + public function getUnnamedArgs() |
|
| 44 | + { |
|
| 45 | + return $this->unnamedArgs; |
|
| 46 | + } |
|
| 47 | 47 | |
| 48 | - public function getAction() |
|
| 49 | - { |
|
| 50 | - return $this->action; |
|
| 51 | - } |
|
| 48 | + public function getAction() |
|
| 49 | + { |
|
| 50 | + return $this->action; |
|
| 51 | + } |
|
| 52 | 52 | |
| 53 | - /** |
|
| 54 | - * Return the unnamed arg of the given index (0 = first) |
|
| 55 | - */ |
|
| 56 | - public function unnamed($idx) |
|
| 57 | - { |
|
| 58 | - return isset($this->unnamedArgs[$idx]) ? $this->unnamedArgs[$idx] : null; |
|
| 59 | - } |
|
| 53 | + /** |
|
| 54 | + * Return the unnamed arg of the given index (0 = first) |
|
| 55 | + */ |
|
| 56 | + public function unnamed($idx) |
|
| 57 | + { |
|
| 58 | + return isset($this->unnamedArgs[$idx]) ? $this->unnamedArgs[$idx] : null; |
|
| 59 | + } |
|
| 60 | 60 | |
| 61 | - /** |
|
| 62 | - * Return the sudo argument, preferring a more specific one with the given optional prefix |
|
| 63 | - */ |
|
| 64 | - public function sudo($optionalPrefix) |
|
| 65 | - { |
|
| 66 | - if (!empty($this->namedArgs[$optionalPrefix . '-sudo'])) { |
|
| 67 | - return $this->namedArgs[$optionalPrefix . '-sudo']; |
|
| 68 | - } elseif (!empty($this->namedArgs['sudo'])) { |
|
| 69 | - return $this->namedArgs['sudo']; |
|
| 70 | - } else { |
|
| 71 | - return null; |
|
| 72 | - } |
|
| 73 | - } |
|
| 61 | + /** |
|
| 62 | + * Return the sudo argument, preferring a more specific one with the given optional prefix |
|
| 63 | + */ |
|
| 64 | + public function sudo($optionalPrefix) |
|
| 65 | + { |
|
| 66 | + if (!empty($this->namedArgs[$optionalPrefix . '-sudo'])) { |
|
| 67 | + return $this->namedArgs[$optionalPrefix . '-sudo']; |
|
| 68 | + } elseif (!empty($this->namedArgs['sudo'])) { |
|
| 69 | + return $this->namedArgs['sudo']; |
|
| 70 | + } else { |
|
| 71 | + return null; |
|
| 72 | + } |
|
| 73 | + } |
|
| 74 | 74 | |
| 75 | - /** |
|
| 76 | - * Return the pak-parks arguments, as a map of part => boolean |
|
| 77 | - */ |
|
| 78 | - public function pakParts() |
|
| 79 | - { |
|
| 80 | - // Look up which parts of the sspak are going to be saved |
|
| 81 | - $pakParks = array(); |
|
| 82 | - foreach (array('assets','db','git-remote') as $part) { |
|
| 83 | - $pakParts[$part] = !empty($this->namedArgs[$part]); |
|
| 84 | - } |
|
| 75 | + /** |
|
| 76 | + * Return the pak-parks arguments, as a map of part => boolean |
|
| 77 | + */ |
|
| 78 | + public function pakParts() |
|
| 79 | + { |
|
| 80 | + // Look up which parts of the sspak are going to be saved |
|
| 81 | + $pakParks = array(); |
|
| 82 | + foreach (array('assets','db','git-remote') as $part) { |
|
| 83 | + $pakParts[$part] = !empty($this->namedArgs[$part]); |
|
| 84 | + } |
|
| 85 | 85 | |
| 86 | - // Default to db and assets |
|
| 87 | - if (!array_filter($pakParts)) { |
|
| 88 | - $pakParts = array('db' => true, 'assets' => true, 'git-remote' => true); |
|
| 89 | - } |
|
| 90 | - return $pakParts; |
|
| 91 | - } |
|
| 86 | + // Default to db and assets |
|
| 87 | + if (!array_filter($pakParts)) { |
|
| 88 | + $pakParts = array('db' => true, 'assets' => true, 'git-remote' => true); |
|
| 89 | + } |
|
| 90 | + return $pakParts; |
|
| 91 | + } |
|
| 92 | 92 | |
| 93 | - public function requireUnnamed($items) |
|
| 94 | - { |
|
| 95 | - if (sizeof($this->unnamedArgs) < sizeof($items)) { |
|
| 96 | - echo "Usage: {$_SERVER['argv'][0]} " . $this->action . " ("; |
|
| 97 | - echo implode(") (", $items); |
|
| 98 | - echo ")\n"; |
|
| 99 | - throw new Exception('Arguments missing.'); |
|
| 100 | - } |
|
| 101 | - } |
|
| 93 | + public function requireUnnamed($items) |
|
| 94 | + { |
|
| 95 | + if (sizeof($this->unnamedArgs) < sizeof($items)) { |
|
| 96 | + echo "Usage: {$_SERVER['argv'][0]} " . $this->action . " ("; |
|
| 97 | + echo implode(") (", $items); |
|
| 98 | + echo ")\n"; |
|
| 99 | + throw new Exception('Arguments missing.'); |
|
| 100 | + } |
|
| 101 | + } |
|
| 102 | 102 | } |
@@ -63,8 +63,8 @@ discard block |
||
| 63 | 63 | */ |
| 64 | 64 | public function sudo($optionalPrefix) |
| 65 | 65 | { |
| 66 | - if (!empty($this->namedArgs[$optionalPrefix . '-sudo'])) { |
|
| 67 | - return $this->namedArgs[$optionalPrefix . '-sudo']; |
|
| 66 | + if (!empty($this->namedArgs[$optionalPrefix.'-sudo'])) { |
|
| 67 | + return $this->namedArgs[$optionalPrefix.'-sudo']; |
|
| 68 | 68 | } elseif (!empty($this->namedArgs['sudo'])) { |
| 69 | 69 | return $this->namedArgs['sudo']; |
| 70 | 70 | } else { |
@@ -79,7 +79,7 @@ discard block |
||
| 79 | 79 | { |
| 80 | 80 | // Look up which parts of the sspak are going to be saved |
| 81 | 81 | $pakParks = array(); |
| 82 | - foreach (array('assets','db','git-remote') as $part) { |
|
| 82 | + foreach (array('assets', 'db', 'git-remote') as $part) { |
|
| 83 | 83 | $pakParts[$part] = !empty($this->namedArgs[$part]); |
| 84 | 84 | } |
| 85 | 85 | |
@@ -93,7 +93,7 @@ discard block |
||
| 93 | 93 | public function requireUnnamed($items) |
| 94 | 94 | { |
| 95 | 95 | if (sizeof($this->unnamedArgs) < sizeof($items)) { |
| 96 | - echo "Usage: {$_SERVER['argv'][0]} " . $this->action . " ("; |
|
| 96 | + echo "Usage: {$_SERVER['argv'][0]} ".$this->action." ("; |
|
| 97 | 97 | echo implode(") (", $items); |
| 98 | 98 | echo ")\n"; |
| 99 | 99 | throw new Exception('Arguments missing.'); |
@@ -9,209 +9,209 @@ |
||
| 9 | 9 | */ |
| 10 | 10 | class Webroot extends FilesystemEntity |
| 11 | 11 | { |
| 12 | - protected $sudo = null; |
|
| 13 | - protected $details = null; |
|
| 14 | - |
|
| 15 | - public function setSudo($sudo) |
|
| 16 | - { |
|
| 17 | - $this->sudo = $sudo; |
|
| 18 | - } |
|
| 19 | - |
|
| 20 | - /** |
|
| 21 | - * Return a map of the db & asset config details. |
|
| 22 | - * Calls sniff once and then caches |
|
| 23 | - */ |
|
| 24 | - public function details() |
|
| 25 | - { |
|
| 26 | - if (!$this->details) { |
|
| 27 | - $this->details = $this->sniff(); |
|
| 28 | - } |
|
| 29 | - return $this->details; |
|
| 30 | - } |
|
| 31 | - |
|
| 32 | - /** |
|
| 33 | - * Return a map of the db & asset config details, acquired with ssnap-sniffer |
|
| 34 | - */ |
|
| 35 | - public function sniff() |
|
| 36 | - { |
|
| 37 | - global $snifferFileContent; |
|
| 38 | - |
|
| 39 | - if (!$snifferFileContent) { |
|
| 40 | - $snifferFileContent = file_get_contents(PACKAGE_ROOT . 'src/sspak-sniffer.php'); |
|
| 41 | - } |
|
| 42 | - |
|
| 43 | - $remoteSniffer = '/tmp/sspak-sniffer-' . rand(100000, 999999) . '.php'; |
|
| 44 | - $this->uploadContent($snifferFileContent, $remoteSniffer); |
|
| 45 | - |
|
| 46 | - $result = $this->execSudo(array('/usr/bin/env', 'php', $remoteSniffer, $this->path)); |
|
| 47 | - $this->unlink($remoteSniffer); |
|
| 48 | - |
|
| 49 | - $parsed = @unserialize($result['output']); |
|
| 50 | - if (!$parsed) { |
|
| 51 | - throw new Exception("Could not parse sspak-sniffer content:\n{$result['output']}\n"); |
|
| 52 | - } |
|
| 53 | - return $parsed; |
|
| 54 | - } |
|
| 55 | - |
|
| 56 | - /** |
|
| 57 | - * Execute a command on the relevant server, using the given sudo option |
|
| 58 | - * @param string|array $command Shell command, either a fully escaped string or an array |
|
| 59 | - * @see Process::exec @param $options (optional) Extra options |
|
| 60 | - * @return array A map containing 'return', 'output', and 'error' |
|
| 61 | - */ |
|
| 62 | - public function execSudo($command, $options = array()) |
|
| 63 | - { |
|
| 64 | - if ($this->sudo) { |
|
| 65 | - if (is_array($command)) { |
|
| 66 | - $command = $this->executor->commandArrayToString($command); |
|
| 67 | - } |
|
| 68 | - // Try running sudo without asking for a password |
|
| 69 | - try { |
|
| 70 | - return $this->exec("sudo -n -u " . escapeshellarg($this->sudo) . " " . $command, $options); |
|
| 71 | - |
|
| 72 | - // Otherwise capture SUDO password ourselves and pass it in through STDIN |
|
| 73 | - } catch (Exception $e) { |
|
| 74 | - echo "[sspak sudo] Enter your password: "; |
|
| 75 | - $stdin = fopen('php://stdin', 'r'); |
|
| 76 | - $password = fgets($stdin); |
|
| 77 | - |
|
| 78 | - return $this->exec( |
|
| 79 | - "sudo -S -p '' -u " . escapeshellarg($this->sudo) . " " . $command, |
|
| 80 | - array('inputContent' => $password) |
|
| 81 | - ); |
|
| 82 | - } |
|
| 83 | - } else { |
|
| 84 | - return $this->exec($command, $options); |
|
| 85 | - } |
|
| 86 | - } |
|
| 87 | - |
|
| 88 | - /** |
|
| 89 | - * Put the database from the given sspak file into this webroot. |
|
| 90 | - * @param array $details The previously sniffed details of this webroot |
|
| 91 | - * @param bool $dropdb Drop the DB prior to install |
|
| 92 | - * @param string $sspakFile Filename |
|
| 93 | - */ |
|
| 94 | - public function putdb($sspak, $dropdb) |
|
| 95 | - { |
|
| 96 | - $details = $this->details(); |
|
| 97 | - |
|
| 98 | - // Check the database type |
|
| 99 | - $dbFunction = 'putdb_'.$details['db_type']; |
|
| 100 | - if (!method_exists($this, $dbFunction)) { |
|
| 101 | - throw new Exception("Can't process database type '" . $details['db_type'] . "'"); |
|
| 102 | - } |
|
| 103 | - |
|
| 104 | - // Extract DB direct from sspak file |
|
| 105 | - return $this->$dbFunction($details, $sspak, $dropdb); |
|
| 106 | - } |
|
| 107 | - |
|
| 108 | - public function putdb_MySQLPDODatabase($conf, $sspak, $dropdb) |
|
| 109 | - { |
|
| 110 | - return $this->putdb_MySQLDatabase($conf, $sspak, $dropdb); |
|
| 111 | - } |
|
| 112 | - |
|
| 113 | - public function putdb_MySQLDatabase($conf, $sspak, $dropdb) |
|
| 114 | - { |
|
| 115 | - $usernameArg = escapeshellarg("--user=".$conf['db_username']); |
|
| 116 | - $passwordArg = escapeshellarg("--password=".$conf['db_password']); |
|
| 117 | - $databaseArg = escapeshellarg($conf['db_database']); |
|
| 118 | - |
|
| 119 | - $hostArg = ''; |
|
| 120 | - $portArg = ''; |
|
| 121 | - if (!empty($conf['db_server']) && $conf['db_server'] != 'localhost') { |
|
| 122 | - if (strpos($conf['db_server'], ':')!==false) { |
|
| 123 | - // Handle "server:port" format. |
|
| 124 | - $server = explode(':', $conf['db_server'], 2); |
|
| 125 | - $hostArg = escapeshellarg("--host=".$server[0]); |
|
| 126 | - $portArg = escapeshellarg("--port=".$server[1]); |
|
| 127 | - } else { |
|
| 128 | - $hostArg = escapeshellarg("--host=".$conf['db_server']); |
|
| 129 | - } |
|
| 130 | - } |
|
| 131 | - $dbCommand = "create database if not exists `" . addslashes($conf['db_database']) . "`"; |
|
| 132 | - if ($dropdb) { |
|
| 133 | - $dbCommand = "drop database if exists `" . addslashes($conf['db_database']) . "`; " . $dbCommand; |
|
| 134 | - } |
|
| 135 | - |
|
| 136 | - $this->exec("echo '$dbCommand' | mysql $usernameArg $passwordArg $hostArg $portArg"); |
|
| 137 | - |
|
| 138 | - $stream = $sspak->readStreamForFile('database.sql.gz'); |
|
| 139 | - $this->exec("gunzip -c | sed '/^CREATE DATABASE/d;/^USE/d' | mysql --default-character-set=utf8 " . |
|
| 140 | - "$usernameArg $passwordArg $hostArg $portArg $databaseArg", array('inputStream' => $stream)); |
|
| 141 | - fclose($stream); |
|
| 142 | - return true; |
|
| 143 | - } |
|
| 144 | - |
|
| 145 | - public function putdb_PostgreSQLDatabase($conf, $sspak, $dropdb) |
|
| 146 | - { |
|
| 147 | - // TODO: Support dropdb for postgresql |
|
| 148 | - $usernameArg = escapeshellarg("--username=".$conf['db_username']); |
|
| 149 | - $passwordArg = "PGPASSWORD=".escapeshellarg($conf['db_password']); |
|
| 150 | - $databaseArg = escapeshellarg($conf['db_database']); |
|
| 151 | - $hostArg = escapeshellarg("--host=".$conf['db_server']); |
|
| 152 | - |
|
| 153 | - // Create database if needed |
|
| 154 | - $result = $this->exec("echo \"select count(*) from pg_catalog.pg_database where datname = $databaseArg\" | " . |
|
| 155 | - "$passwordArg psql $usernameArg $hostArg $databaseArg -qt"); |
|
| 156 | - if (trim($result['output']) == '0') { |
|
| 157 | - $this->exec("$passwordArg createdb $usernameArg $hostArg $databaseArg"); |
|
| 158 | - } |
|
| 159 | - |
|
| 160 | - $stream = $sspak->readStreamForFile('database.sql.gz'); |
|
| 161 | - return $this->exec( |
|
| 162 | - "gunzip -c | $passwordArg psql $usernameArg $hostArg $databaseArg", |
|
| 163 | - array('inputStream' => $stream) |
|
| 164 | - ); |
|
| 165 | - fclose($stream); |
|
| 166 | - } |
|
| 167 | - |
|
| 168 | - /** |
|
| 169 | - * @param $sspak SSPakFile SSPak file to extract assets from |
|
| 170 | - * @todo There should be a return value or exception thrown to indicate success or failure to put assets |
|
| 171 | - */ |
|
| 172 | - public function putassets($sspak) |
|
| 173 | - { |
|
| 174 | - $details = $this->details(); |
|
| 175 | - $assetsPath = $details['assets_path']; |
|
| 176 | - $assetsPath = escapeshellarg($assetsPath); |
|
| 177 | - |
|
| 178 | - // Check for symlink - this was more reliable than is_link |
|
| 179 | - $assetsPathExec = $this->exec( |
|
| 180 | - "if [ -L {$assetsPath} ]; then readlink -f {$assetsPath}; else echo {$assetsPath}; fi" |
|
| 181 | - ); |
|
| 182 | - $assetsPath = trim($assetsPathExec["output"]); |
|
| 183 | - |
|
| 184 | - $assetsOldPath = $assetsPath . '.old'; |
|
| 185 | - $assetsParentArg = escapeshellarg(dirname($assetsPath)); |
|
| 186 | - |
|
| 187 | - // Move existing assets to assets.old |
|
| 188 | - $assetsExist = $this->execSudo("test -d '$assetsPath'", ['throwException' => false]); |
|
| 189 | - if ($assetsExist['return'] == 0) { |
|
| 190 | - $this->execSudo("mv {$assetsPath} {$assetsOldPath}"); |
|
| 191 | - } |
|
| 192 | - |
|
| 193 | - // Extract assets |
|
| 194 | - $stream = $sspak->readStreamForFile('assets.tar.gz'); |
|
| 195 | - $this->execSudo("tar xzf - -C {$assetsParentArg}", array('inputStream' => $stream)); |
|
| 196 | - fclose($stream); |
|
| 197 | - |
|
| 198 | - // Remove assets.old |
|
| 199 | - $oldAssetsExist = $this->execSudo("test -d '$assetsOldPath'", ['throwException' => false]); |
|
| 200 | - if ($oldAssetsExist['return'] == 0) { |
|
| 201 | - $this->execSudo("rm -rf {$assetsOldPath}"); |
|
| 202 | - } |
|
| 203 | - } |
|
| 204 | - |
|
| 205 | - /** |
|
| 206 | - * Load a git remote into this webroot. |
|
| 207 | - * It expects that this remote is an empty directory. |
|
| 208 | - * |
|
| 209 | - * @param array $details Map of git details |
|
| 210 | - */ |
|
| 211 | - public function putgit($details) |
|
| 212 | - { |
|
| 213 | - $this->exec(array('git', 'clone', $details['remote'], $this->path)); |
|
| 214 | - $this->exec("cd $this->path && git checkout " . escapeshellarg($details['branch'])); |
|
| 215 | - return true; |
|
| 216 | - } |
|
| 12 | + protected $sudo = null; |
|
| 13 | + protected $details = null; |
|
| 14 | + |
|
| 15 | + public function setSudo($sudo) |
|
| 16 | + { |
|
| 17 | + $this->sudo = $sudo; |
|
| 18 | + } |
|
| 19 | + |
|
| 20 | + /** |
|
| 21 | + * Return a map of the db & asset config details. |
|
| 22 | + * Calls sniff once and then caches |
|
| 23 | + */ |
|
| 24 | + public function details() |
|
| 25 | + { |
|
| 26 | + if (!$this->details) { |
|
| 27 | + $this->details = $this->sniff(); |
|
| 28 | + } |
|
| 29 | + return $this->details; |
|
| 30 | + } |
|
| 31 | + |
|
| 32 | + /** |
|
| 33 | + * Return a map of the db & asset config details, acquired with ssnap-sniffer |
|
| 34 | + */ |
|
| 35 | + public function sniff() |
|
| 36 | + { |
|
| 37 | + global $snifferFileContent; |
|
| 38 | + |
|
| 39 | + if (!$snifferFileContent) { |
|
| 40 | + $snifferFileContent = file_get_contents(PACKAGE_ROOT . 'src/sspak-sniffer.php'); |
|
| 41 | + } |
|
| 42 | + |
|
| 43 | + $remoteSniffer = '/tmp/sspak-sniffer-' . rand(100000, 999999) . '.php'; |
|
| 44 | + $this->uploadContent($snifferFileContent, $remoteSniffer); |
|
| 45 | + |
|
| 46 | + $result = $this->execSudo(array('/usr/bin/env', 'php', $remoteSniffer, $this->path)); |
|
| 47 | + $this->unlink($remoteSniffer); |
|
| 48 | + |
|
| 49 | + $parsed = @unserialize($result['output']); |
|
| 50 | + if (!$parsed) { |
|
| 51 | + throw new Exception("Could not parse sspak-sniffer content:\n{$result['output']}\n"); |
|
| 52 | + } |
|
| 53 | + return $parsed; |
|
| 54 | + } |
|
| 55 | + |
|
| 56 | + /** |
|
| 57 | + * Execute a command on the relevant server, using the given sudo option |
|
| 58 | + * @param string|array $command Shell command, either a fully escaped string or an array |
|
| 59 | + * @see Process::exec @param $options (optional) Extra options |
|
| 60 | + * @return array A map containing 'return', 'output', and 'error' |
|
| 61 | + */ |
|
| 62 | + public function execSudo($command, $options = array()) |
|
| 63 | + { |
|
| 64 | + if ($this->sudo) { |
|
| 65 | + if (is_array($command)) { |
|
| 66 | + $command = $this->executor->commandArrayToString($command); |
|
| 67 | + } |
|
| 68 | + // Try running sudo without asking for a password |
|
| 69 | + try { |
|
| 70 | + return $this->exec("sudo -n -u " . escapeshellarg($this->sudo) . " " . $command, $options); |
|
| 71 | + |
|
| 72 | + // Otherwise capture SUDO password ourselves and pass it in through STDIN |
|
| 73 | + } catch (Exception $e) { |
|
| 74 | + echo "[sspak sudo] Enter your password: "; |
|
| 75 | + $stdin = fopen('php://stdin', 'r'); |
|
| 76 | + $password = fgets($stdin); |
|
| 77 | + |
|
| 78 | + return $this->exec( |
|
| 79 | + "sudo -S -p '' -u " . escapeshellarg($this->sudo) . " " . $command, |
|
| 80 | + array('inputContent' => $password) |
|
| 81 | + ); |
|
| 82 | + } |
|
| 83 | + } else { |
|
| 84 | + return $this->exec($command, $options); |
|
| 85 | + } |
|
| 86 | + } |
|
| 87 | + |
|
| 88 | + /** |
|
| 89 | + * Put the database from the given sspak file into this webroot. |
|
| 90 | + * @param array $details The previously sniffed details of this webroot |
|
| 91 | + * @param bool $dropdb Drop the DB prior to install |
|
| 92 | + * @param string $sspakFile Filename |
|
| 93 | + */ |
|
| 94 | + public function putdb($sspak, $dropdb) |
|
| 95 | + { |
|
| 96 | + $details = $this->details(); |
|
| 97 | + |
|
| 98 | + // Check the database type |
|
| 99 | + $dbFunction = 'putdb_'.$details['db_type']; |
|
| 100 | + if (!method_exists($this, $dbFunction)) { |
|
| 101 | + throw new Exception("Can't process database type '" . $details['db_type'] . "'"); |
|
| 102 | + } |
|
| 103 | + |
|
| 104 | + // Extract DB direct from sspak file |
|
| 105 | + return $this->$dbFunction($details, $sspak, $dropdb); |
|
| 106 | + } |
|
| 107 | + |
|
| 108 | + public function putdb_MySQLPDODatabase($conf, $sspak, $dropdb) |
|
| 109 | + { |
|
| 110 | + return $this->putdb_MySQLDatabase($conf, $sspak, $dropdb); |
|
| 111 | + } |
|
| 112 | + |
|
| 113 | + public function putdb_MySQLDatabase($conf, $sspak, $dropdb) |
|
| 114 | + { |
|
| 115 | + $usernameArg = escapeshellarg("--user=".$conf['db_username']); |
|
| 116 | + $passwordArg = escapeshellarg("--password=".$conf['db_password']); |
|
| 117 | + $databaseArg = escapeshellarg($conf['db_database']); |
|
| 118 | + |
|
| 119 | + $hostArg = ''; |
|
| 120 | + $portArg = ''; |
|
| 121 | + if (!empty($conf['db_server']) && $conf['db_server'] != 'localhost') { |
|
| 122 | + if (strpos($conf['db_server'], ':')!==false) { |
|
| 123 | + // Handle "server:port" format. |
|
| 124 | + $server = explode(':', $conf['db_server'], 2); |
|
| 125 | + $hostArg = escapeshellarg("--host=".$server[0]); |
|
| 126 | + $portArg = escapeshellarg("--port=".$server[1]); |
|
| 127 | + } else { |
|
| 128 | + $hostArg = escapeshellarg("--host=".$conf['db_server']); |
|
| 129 | + } |
|
| 130 | + } |
|
| 131 | + $dbCommand = "create database if not exists `" . addslashes($conf['db_database']) . "`"; |
|
| 132 | + if ($dropdb) { |
|
| 133 | + $dbCommand = "drop database if exists `" . addslashes($conf['db_database']) . "`; " . $dbCommand; |
|
| 134 | + } |
|
| 135 | + |
|
| 136 | + $this->exec("echo '$dbCommand' | mysql $usernameArg $passwordArg $hostArg $portArg"); |
|
| 137 | + |
|
| 138 | + $stream = $sspak->readStreamForFile('database.sql.gz'); |
|
| 139 | + $this->exec("gunzip -c | sed '/^CREATE DATABASE/d;/^USE/d' | mysql --default-character-set=utf8 " . |
|
| 140 | + "$usernameArg $passwordArg $hostArg $portArg $databaseArg", array('inputStream' => $stream)); |
|
| 141 | + fclose($stream); |
|
| 142 | + return true; |
|
| 143 | + } |
|
| 144 | + |
|
| 145 | + public function putdb_PostgreSQLDatabase($conf, $sspak, $dropdb) |
|
| 146 | + { |
|
| 147 | + // TODO: Support dropdb for postgresql |
|
| 148 | + $usernameArg = escapeshellarg("--username=".$conf['db_username']); |
|
| 149 | + $passwordArg = "PGPASSWORD=".escapeshellarg($conf['db_password']); |
|
| 150 | + $databaseArg = escapeshellarg($conf['db_database']); |
|
| 151 | + $hostArg = escapeshellarg("--host=".$conf['db_server']); |
|
| 152 | + |
|
| 153 | + // Create database if needed |
|
| 154 | + $result = $this->exec("echo \"select count(*) from pg_catalog.pg_database where datname = $databaseArg\" | " . |
|
| 155 | + "$passwordArg psql $usernameArg $hostArg $databaseArg -qt"); |
|
| 156 | + if (trim($result['output']) == '0') { |
|
| 157 | + $this->exec("$passwordArg createdb $usernameArg $hostArg $databaseArg"); |
|
| 158 | + } |
|
| 159 | + |
|
| 160 | + $stream = $sspak->readStreamForFile('database.sql.gz'); |
|
| 161 | + return $this->exec( |
|
| 162 | + "gunzip -c | $passwordArg psql $usernameArg $hostArg $databaseArg", |
|
| 163 | + array('inputStream' => $stream) |
|
| 164 | + ); |
|
| 165 | + fclose($stream); |
|
| 166 | + } |
|
| 167 | + |
|
| 168 | + /** |
|
| 169 | + * @param $sspak SSPakFile SSPak file to extract assets from |
|
| 170 | + * @todo There should be a return value or exception thrown to indicate success or failure to put assets |
|
| 171 | + */ |
|
| 172 | + public function putassets($sspak) |
|
| 173 | + { |
|
| 174 | + $details = $this->details(); |
|
| 175 | + $assetsPath = $details['assets_path']; |
|
| 176 | + $assetsPath = escapeshellarg($assetsPath); |
|
| 177 | + |
|
| 178 | + // Check for symlink - this was more reliable than is_link |
|
| 179 | + $assetsPathExec = $this->exec( |
|
| 180 | + "if [ -L {$assetsPath} ]; then readlink -f {$assetsPath}; else echo {$assetsPath}; fi" |
|
| 181 | + ); |
|
| 182 | + $assetsPath = trim($assetsPathExec["output"]); |
|
| 183 | + |
|
| 184 | + $assetsOldPath = $assetsPath . '.old'; |
|
| 185 | + $assetsParentArg = escapeshellarg(dirname($assetsPath)); |
|
| 186 | + |
|
| 187 | + // Move existing assets to assets.old |
|
| 188 | + $assetsExist = $this->execSudo("test -d '$assetsPath'", ['throwException' => false]); |
|
| 189 | + if ($assetsExist['return'] == 0) { |
|
| 190 | + $this->execSudo("mv {$assetsPath} {$assetsOldPath}"); |
|
| 191 | + } |
|
| 192 | + |
|
| 193 | + // Extract assets |
|
| 194 | + $stream = $sspak->readStreamForFile('assets.tar.gz'); |
|
| 195 | + $this->execSudo("tar xzf - -C {$assetsParentArg}", array('inputStream' => $stream)); |
|
| 196 | + fclose($stream); |
|
| 197 | + |
|
| 198 | + // Remove assets.old |
|
| 199 | + $oldAssetsExist = $this->execSudo("test -d '$assetsOldPath'", ['throwException' => false]); |
|
| 200 | + if ($oldAssetsExist['return'] == 0) { |
|
| 201 | + $this->execSudo("rm -rf {$assetsOldPath}"); |
|
| 202 | + } |
|
| 203 | + } |
|
| 204 | + |
|
| 205 | + /** |
|
| 206 | + * Load a git remote into this webroot. |
|
| 207 | + * It expects that this remote is an empty directory. |
|
| 208 | + * |
|
| 209 | + * @param array $details Map of git details |
|
| 210 | + */ |
|
| 211 | + public function putgit($details) |
|
| 212 | + { |
|
| 213 | + $this->exec(array('git', 'clone', $details['remote'], $this->path)); |
|
| 214 | + $this->exec("cd $this->path && git checkout " . escapeshellarg($details['branch'])); |
|
| 215 | + return true; |
|
| 216 | + } |
|
| 217 | 217 | } |
@@ -37,10 +37,10 @@ discard block |
||
| 37 | 37 | global $snifferFileContent; |
| 38 | 38 | |
| 39 | 39 | if (!$snifferFileContent) { |
| 40 | - $snifferFileContent = file_get_contents(PACKAGE_ROOT . 'src/sspak-sniffer.php'); |
|
| 40 | + $snifferFileContent = file_get_contents(PACKAGE_ROOT.'src/sspak-sniffer.php'); |
|
| 41 | 41 | } |
| 42 | 42 | |
| 43 | - $remoteSniffer = '/tmp/sspak-sniffer-' . rand(100000, 999999) . '.php'; |
|
| 43 | + $remoteSniffer = '/tmp/sspak-sniffer-'.rand(100000, 999999).'.php'; |
|
| 44 | 44 | $this->uploadContent($snifferFileContent, $remoteSniffer); |
| 45 | 45 | |
| 46 | 46 | $result = $this->execSudo(array('/usr/bin/env', 'php', $remoteSniffer, $this->path)); |
@@ -67,7 +67,7 @@ discard block |
||
| 67 | 67 | } |
| 68 | 68 | // Try running sudo without asking for a password |
| 69 | 69 | try { |
| 70 | - return $this->exec("sudo -n -u " . escapeshellarg($this->sudo) . " " . $command, $options); |
|
| 70 | + return $this->exec("sudo -n -u ".escapeshellarg($this->sudo)." ".$command, $options); |
|
| 71 | 71 | |
| 72 | 72 | // Otherwise capture SUDO password ourselves and pass it in through STDIN |
| 73 | 73 | } catch (Exception $e) { |
@@ -76,7 +76,7 @@ discard block |
||
| 76 | 76 | $password = fgets($stdin); |
| 77 | 77 | |
| 78 | 78 | return $this->exec( |
| 79 | - "sudo -S -p '' -u " . escapeshellarg($this->sudo) . " " . $command, |
|
| 79 | + "sudo -S -p '' -u ".escapeshellarg($this->sudo)." ".$command, |
|
| 80 | 80 | array('inputContent' => $password) |
| 81 | 81 | ); |
| 82 | 82 | } |
@@ -98,7 +98,7 @@ discard block |
||
| 98 | 98 | // Check the database type |
| 99 | 99 | $dbFunction = 'putdb_'.$details['db_type']; |
| 100 | 100 | if (!method_exists($this, $dbFunction)) { |
| 101 | - throw new Exception("Can't process database type '" . $details['db_type'] . "'"); |
|
| 101 | + throw new Exception("Can't process database type '".$details['db_type']."'"); |
|
| 102 | 102 | } |
| 103 | 103 | |
| 104 | 104 | // Extract DB direct from sspak file |
@@ -119,7 +119,7 @@ discard block |
||
| 119 | 119 | $hostArg = ''; |
| 120 | 120 | $portArg = ''; |
| 121 | 121 | if (!empty($conf['db_server']) && $conf['db_server'] != 'localhost') { |
| 122 | - if (strpos($conf['db_server'], ':')!==false) { |
|
| 122 | + if (strpos($conf['db_server'], ':') !== false) { |
|
| 123 | 123 | // Handle "server:port" format. |
| 124 | 124 | $server = explode(':', $conf['db_server'], 2); |
| 125 | 125 | $hostArg = escapeshellarg("--host=".$server[0]); |
@@ -128,15 +128,15 @@ discard block |
||
| 128 | 128 | $hostArg = escapeshellarg("--host=".$conf['db_server']); |
| 129 | 129 | } |
| 130 | 130 | } |
| 131 | - $dbCommand = "create database if not exists `" . addslashes($conf['db_database']) . "`"; |
|
| 131 | + $dbCommand = "create database if not exists `".addslashes($conf['db_database'])."`"; |
|
| 132 | 132 | if ($dropdb) { |
| 133 | - $dbCommand = "drop database if exists `" . addslashes($conf['db_database']) . "`; " . $dbCommand; |
|
| 133 | + $dbCommand = "drop database if exists `".addslashes($conf['db_database'])."`; ".$dbCommand; |
|
| 134 | 134 | } |
| 135 | 135 | |
| 136 | 136 | $this->exec("echo '$dbCommand' | mysql $usernameArg $passwordArg $hostArg $portArg"); |
| 137 | 137 | |
| 138 | 138 | $stream = $sspak->readStreamForFile('database.sql.gz'); |
| 139 | - $this->exec("gunzip -c | sed '/^CREATE DATABASE/d;/^USE/d' | mysql --default-character-set=utf8 " . |
|
| 139 | + $this->exec("gunzip -c | sed '/^CREATE DATABASE/d;/^USE/d' | mysql --default-character-set=utf8 ". |
|
| 140 | 140 | "$usernameArg $passwordArg $hostArg $portArg $databaseArg", array('inputStream' => $stream)); |
| 141 | 141 | fclose($stream); |
| 142 | 142 | return true; |
@@ -151,7 +151,7 @@ discard block |
||
| 151 | 151 | $hostArg = escapeshellarg("--host=".$conf['db_server']); |
| 152 | 152 | |
| 153 | 153 | // Create database if needed |
| 154 | - $result = $this->exec("echo \"select count(*) from pg_catalog.pg_database where datname = $databaseArg\" | " . |
|
| 154 | + $result = $this->exec("echo \"select count(*) from pg_catalog.pg_database where datname = $databaseArg\" | ". |
|
| 155 | 155 | "$passwordArg psql $usernameArg $hostArg $databaseArg -qt"); |
| 156 | 156 | if (trim($result['output']) == '0') { |
| 157 | 157 | $this->exec("$passwordArg createdb $usernameArg $hostArg $databaseArg"); |
@@ -181,7 +181,7 @@ discard block |
||
| 181 | 181 | ); |
| 182 | 182 | $assetsPath = trim($assetsPathExec["output"]); |
| 183 | 183 | |
| 184 | - $assetsOldPath = $assetsPath . '.old'; |
|
| 184 | + $assetsOldPath = $assetsPath.'.old'; |
|
| 185 | 185 | $assetsParentArg = escapeshellarg(dirname($assetsPath)); |
| 186 | 186 | |
| 187 | 187 | // Move existing assets to assets.old |
@@ -211,7 +211,7 @@ discard block |
||
| 211 | 211 | public function putgit($details) |
| 212 | 212 | { |
| 213 | 213 | $this->exec(array('git', 'clone', $details['remote'], $this->path)); |
| 214 | - $this->exec("cd $this->path && git checkout " . escapeshellarg($details['branch'])); |
|
| 214 | + $this->exec("cd $this->path && git checkout ".escapeshellarg($details['branch'])); |
|
| 215 | 215 | return true; |
| 216 | 216 | } |
| 217 | 217 | } |
@@ -13,68 +13,68 @@ discard block |
||
| 13 | 13 | */ |
| 14 | 14 | class SSPak |
| 15 | 15 | { |
| 16 | - protected $executor; |
|
| 17 | - |
|
| 18 | - /** |
|
| 19 | - * Create a new handler |
|
| 20 | - * @param Executor $executor The Executor object to handle command execution |
|
| 21 | - */ |
|
| 22 | - public function __construct($executor) |
|
| 23 | - { |
|
| 24 | - $this->executor = $executor; |
|
| 25 | - } |
|
| 26 | - |
|
| 27 | - public function getActions() |
|
| 28 | - { |
|
| 29 | - return array( |
|
| 30 | - "help" => array( |
|
| 31 | - "description" => "Show this help message.", |
|
| 32 | - "method" => "help", |
|
| 33 | - ), |
|
| 34 | - "save" => array( |
|
| 35 | - "description" => "Save an .sspak file from a SilverStripe site.", |
|
| 36 | - "unnamedArgs" => array("webroot", "sspak file"), |
|
| 37 | - "namedArgs" => array("identity"), |
|
| 38 | - "method" => "save", |
|
| 39 | - ), |
|
| 40 | - "load" => array( |
|
| 41 | - "description" => "Load an .sspak file into a SilverStripe site. Does not backup - be careful!", |
|
| 42 | - "unnamedArgs" => array("sspak file", "[webroot]"), |
|
| 43 | - "namedArgs" => array("identity"), |
|
| 44 | - "namedFlags" => array("drop-db"), |
|
| 45 | - "method" => "load", |
|
| 46 | - ), |
|
| 47 | - "saveexisting" => array( |
|
| 48 | - "description" => "Create an .sspak file from database SQL dump and/or assets. " . |
|
| 49 | - "Does not require a SilverStripe site.", |
|
| 50 | - "unnamedArgs" => array("sspak file"), |
|
| 51 | - "namedArgs" => array("db", "assets"), |
|
| 52 | - "method" => "saveexisting" |
|
| 53 | - ), |
|
| 54 | - "extract" => array( |
|
| 55 | - "description" => "Extract an .sspak file into the current working directory. Does not require a " . |
|
| 56 | - "SilverStripe site.", |
|
| 57 | - "unnamedArgs" => array("sspak file", "destination path"), |
|
| 58 | - "method" => "extract" |
|
| 59 | - ), |
|
| 60 | - "listtables" => array( |
|
| 61 | - "description" => "List tables in the database", |
|
| 62 | - "unnamedArgs" => array("webroot"), |
|
| 63 | - "method" => "listTables" |
|
| 64 | - ), |
|
| 65 | - |
|
| 66 | - "savecsv" => array( |
|
| 67 | - "description" => "Save tables in the database to a collection of CSV files", |
|
| 68 | - "unnamedArgs" => array("webroot", "output-path"), |
|
| 69 | - "method" => "saveCsv" |
|
| 70 | - ), |
|
| 71 | - |
|
| 72 | - "loadcsv" => array( |
|
| 73 | - "description" => "Load tables from collection of CSV files to a webroot", |
|
| 74 | - "unnamedArgs" => array("input-path", "webroot"), |
|
| 75 | - "method" => "loadCsv" |
|
| 76 | - ), |
|
| 77 | - /* |
|
| 16 | + protected $executor; |
|
| 17 | + |
|
| 18 | + /** |
|
| 19 | + * Create a new handler |
|
| 20 | + * @param Executor $executor The Executor object to handle command execution |
|
| 21 | + */ |
|
| 22 | + public function __construct($executor) |
|
| 23 | + { |
|
| 24 | + $this->executor = $executor; |
|
| 25 | + } |
|
| 26 | + |
|
| 27 | + public function getActions() |
|
| 28 | + { |
|
| 29 | + return array( |
|
| 30 | + "help" => array( |
|
| 31 | + "description" => "Show this help message.", |
|
| 32 | + "method" => "help", |
|
| 33 | + ), |
|
| 34 | + "save" => array( |
|
| 35 | + "description" => "Save an .sspak file from a SilverStripe site.", |
|
| 36 | + "unnamedArgs" => array("webroot", "sspak file"), |
|
| 37 | + "namedArgs" => array("identity"), |
|
| 38 | + "method" => "save", |
|
| 39 | + ), |
|
| 40 | + "load" => array( |
|
| 41 | + "description" => "Load an .sspak file into a SilverStripe site. Does not backup - be careful!", |
|
| 42 | + "unnamedArgs" => array("sspak file", "[webroot]"), |
|
| 43 | + "namedArgs" => array("identity"), |
|
| 44 | + "namedFlags" => array("drop-db"), |
|
| 45 | + "method" => "load", |
|
| 46 | + ), |
|
| 47 | + "saveexisting" => array( |
|
| 48 | + "description" => "Create an .sspak file from database SQL dump and/or assets. " . |
|
| 49 | + "Does not require a SilverStripe site.", |
|
| 50 | + "unnamedArgs" => array("sspak file"), |
|
| 51 | + "namedArgs" => array("db", "assets"), |
|
| 52 | + "method" => "saveexisting" |
|
| 53 | + ), |
|
| 54 | + "extract" => array( |
|
| 55 | + "description" => "Extract an .sspak file into the current working directory. Does not require a " . |
|
| 56 | + "SilverStripe site.", |
|
| 57 | + "unnamedArgs" => array("sspak file", "destination path"), |
|
| 58 | + "method" => "extract" |
|
| 59 | + ), |
|
| 60 | + "listtables" => array( |
|
| 61 | + "description" => "List tables in the database", |
|
| 62 | + "unnamedArgs" => array("webroot"), |
|
| 63 | + "method" => "listTables" |
|
| 64 | + ), |
|
| 65 | + |
|
| 66 | + "savecsv" => array( |
|
| 67 | + "description" => "Save tables in the database to a collection of CSV files", |
|
| 68 | + "unnamedArgs" => array("webroot", "output-path"), |
|
| 69 | + "method" => "saveCsv" |
|
| 70 | + ), |
|
| 71 | + |
|
| 72 | + "loadcsv" => array( |
|
| 73 | + "description" => "Load tables from collection of CSV files to a webroot", |
|
| 74 | + "unnamedArgs" => array("input-path", "webroot"), |
|
| 75 | + "method" => "loadCsv" |
|
| 76 | + ), |
|
| 77 | + /* |
|
| 78 | 78 | |
| 79 | 79 | "install" => array( |
| 80 | 80 | "description" => "Install a .sspak file into a new environment.", |
@@ -92,89 +92,89 @@ discard block |
||
| 92 | 92 | "method" => "transfer", |
| 93 | 93 | ), |
| 94 | 94 | */ |
| 95 | - ); |
|
| 96 | - } |
|
| 97 | - |
|
| 98 | - public function help($args) |
|
| 99 | - { |
|
| 100 | - echo "SSPak: manage SilverStripe .sspak archives.\n\nUsage:\n"; |
|
| 101 | - foreach ($this->getActions() as $action => $info) { |
|
| 102 | - echo "sspak $action"; |
|
| 103 | - if (!empty($info['unnamedArgs'])) { |
|
| 104 | - foreach ($info['unnamedArgs'] as $arg) { |
|
| 105 | - echo " ($arg)"; |
|
| 106 | - } |
|
| 107 | - } |
|
| 108 | - if (!empty($info['namedFlags'])) { |
|
| 109 | - foreach ($info['namedFlags'] as $arg) { |
|
| 110 | - echo " (--$arg)"; |
|
| 111 | - } |
|
| 112 | - } |
|
| 113 | - if (!empty($info['namedArgs'])) { |
|
| 114 | - foreach ($info['namedArgs'] as $arg) { |
|
| 115 | - echo " --$arg=\"$arg value\""; |
|
| 116 | - } |
|
| 117 | - } |
|
| 118 | - echo "\n {$info['description']}\n\n"; |
|
| 119 | - } |
|
| 120 | - } |
|
| 121 | - |
|
| 122 | - /** |
|
| 123 | - * Save an existing database and/or assets into an .sspak.phar file. |
|
| 124 | - * Does the same as {@link save()} but doesn't require an existing site. |
|
| 125 | - */ |
|
| 126 | - public function saveexisting($args) |
|
| 127 | - { |
|
| 128 | - $executor = $this->executor; |
|
| 129 | - |
|
| 130 | - $args->requireUnnamed(array('sspak file')); |
|
| 131 | - $unnamedArgs = $args->getUnnamedArgs(); |
|
| 132 | - $namedArgs = $args->getNamedArgs(); |
|
| 133 | - |
|
| 134 | - $sspak = new SSPakFile($unnamedArgs[0], $executor); |
|
| 135 | - |
|
| 136 | - // Look up which parts of the sspak are going to be saved |
|
| 137 | - $pakParts = $args->pakParts(); |
|
| 138 | - |
|
| 139 | - $filesystem = new FilesystemEntity(null, $executor); |
|
| 140 | - |
|
| 141 | - if ($pakParts['db']) { |
|
| 142 | - $dbPath = escapeshellarg($namedArgs['db']); |
|
| 143 | - $process = $filesystem->createProcess("cat $dbPath | gzip -c"); |
|
| 144 | - $sspak->writeFileFromProcess('database.sql.gz', $process); |
|
| 145 | - } |
|
| 146 | - |
|
| 147 | - if ($pakParts['assets']) { |
|
| 148 | - $assetsParentArg = escapeshellarg(dirname($namedArgs['assets'])); |
|
| 149 | - $assetsBaseArg = escapeshellarg(basename($namedArgs['assets'])); |
|
| 150 | - $process = $filesystem->createProcess("cd $assetsParentArg && tar cfh - $assetsBaseArg | gzip -c"); |
|
| 151 | - $sspak->writeFileFromProcess('assets.tar.gz', $process); |
|
| 152 | - } |
|
| 153 | - } |
|
| 154 | - |
|
| 155 | - /** |
|
| 156 | - * Extracts an existing database and/or assets from a sspak into the given directory, |
|
| 157 | - * defaulting the current working directory if the destination is not given. |
|
| 158 | - */ |
|
| 159 | - public function extract($args) |
|
| 160 | - { |
|
| 161 | - $executor = $this->executor; |
|
| 162 | - |
|
| 163 | - $args->requireUnnamed(array('source sspak file')); |
|
| 164 | - $unnamedArgs = $args->getUnnamedArgs(); |
|
| 165 | - $file = $unnamedArgs[0]; |
|
| 166 | - $dest = !empty($unnamedArgs[1]) ? $unnamedArgs[1] : getcwd(); |
|
| 167 | - |
|
| 168 | - // Phar and PharData use "ustar" format for tar archives (http://php.net/manual/pl/phar.fileformat.tar.php). |
|
| 169 | - // Ustar does not support files larger than 8 GB. |
|
| 170 | - // If the sspak has been created through tar and gz directly, it will probably be in POSIX, PAX or GNU formats, |
|
| 171 | - // which do support >8 GB files. Such archive cannot be accessed by Phar/PharData, and needs to be handled |
|
| 172 | - // manually - it will just spew checksum errors where PHP expects to see ustar headers, but finds garbage |
|
| 173 | - // from other formats. |
|
| 174 | - // There is no cross-platform way of checking the assets.tar.gz size without unpacking, so we assume the size |
|
| 175 | - // of database is negligible which lets us approximate the size of assets. |
|
| 176 | - if (filesize($file) > 8*1024*1024*1024) { |
|
| 177 | - $msg = <<<EOM |
|
| 95 | + ); |
|
| 96 | + } |
|
| 97 | + |
|
| 98 | + public function help($args) |
|
| 99 | + { |
|
| 100 | + echo "SSPak: manage SilverStripe .sspak archives.\n\nUsage:\n"; |
|
| 101 | + foreach ($this->getActions() as $action => $info) { |
|
| 102 | + echo "sspak $action"; |
|
| 103 | + if (!empty($info['unnamedArgs'])) { |
|
| 104 | + foreach ($info['unnamedArgs'] as $arg) { |
|
| 105 | + echo " ($arg)"; |
|
| 106 | + } |
|
| 107 | + } |
|
| 108 | + if (!empty($info['namedFlags'])) { |
|
| 109 | + foreach ($info['namedFlags'] as $arg) { |
|
| 110 | + echo " (--$arg)"; |
|
| 111 | + } |
|
| 112 | + } |
|
| 113 | + if (!empty($info['namedArgs'])) { |
|
| 114 | + foreach ($info['namedArgs'] as $arg) { |
|
| 115 | + echo " --$arg=\"$arg value\""; |
|
| 116 | + } |
|
| 117 | + } |
|
| 118 | + echo "\n {$info['description']}\n\n"; |
|
| 119 | + } |
|
| 120 | + } |
|
| 121 | + |
|
| 122 | + /** |
|
| 123 | + * Save an existing database and/or assets into an .sspak.phar file. |
|
| 124 | + * Does the same as {@link save()} but doesn't require an existing site. |
|
| 125 | + */ |
|
| 126 | + public function saveexisting($args) |
|
| 127 | + { |
|
| 128 | + $executor = $this->executor; |
|
| 129 | + |
|
| 130 | + $args->requireUnnamed(array('sspak file')); |
|
| 131 | + $unnamedArgs = $args->getUnnamedArgs(); |
|
| 132 | + $namedArgs = $args->getNamedArgs(); |
|
| 133 | + |
|
| 134 | + $sspak = new SSPakFile($unnamedArgs[0], $executor); |
|
| 135 | + |
|
| 136 | + // Look up which parts of the sspak are going to be saved |
|
| 137 | + $pakParts = $args->pakParts(); |
|
| 138 | + |
|
| 139 | + $filesystem = new FilesystemEntity(null, $executor); |
|
| 140 | + |
|
| 141 | + if ($pakParts['db']) { |
|
| 142 | + $dbPath = escapeshellarg($namedArgs['db']); |
|
| 143 | + $process = $filesystem->createProcess("cat $dbPath | gzip -c"); |
|
| 144 | + $sspak->writeFileFromProcess('database.sql.gz', $process); |
|
| 145 | + } |
|
| 146 | + |
|
| 147 | + if ($pakParts['assets']) { |
|
| 148 | + $assetsParentArg = escapeshellarg(dirname($namedArgs['assets'])); |
|
| 149 | + $assetsBaseArg = escapeshellarg(basename($namedArgs['assets'])); |
|
| 150 | + $process = $filesystem->createProcess("cd $assetsParentArg && tar cfh - $assetsBaseArg | gzip -c"); |
|
| 151 | + $sspak->writeFileFromProcess('assets.tar.gz', $process); |
|
| 152 | + } |
|
| 153 | + } |
|
| 154 | + |
|
| 155 | + /** |
|
| 156 | + * Extracts an existing database and/or assets from a sspak into the given directory, |
|
| 157 | + * defaulting the current working directory if the destination is not given. |
|
| 158 | + */ |
|
| 159 | + public function extract($args) |
|
| 160 | + { |
|
| 161 | + $executor = $this->executor; |
|
| 162 | + |
|
| 163 | + $args->requireUnnamed(array('source sspak file')); |
|
| 164 | + $unnamedArgs = $args->getUnnamedArgs(); |
|
| 165 | + $file = $unnamedArgs[0]; |
|
| 166 | + $dest = !empty($unnamedArgs[1]) ? $unnamedArgs[1] : getcwd(); |
|
| 167 | + |
|
| 168 | + // Phar and PharData use "ustar" format for tar archives (http://php.net/manual/pl/phar.fileformat.tar.php). |
|
| 169 | + // Ustar does not support files larger than 8 GB. |
|
| 170 | + // If the sspak has been created through tar and gz directly, it will probably be in POSIX, PAX or GNU formats, |
|
| 171 | + // which do support >8 GB files. Such archive cannot be accessed by Phar/PharData, and needs to be handled |
|
| 172 | + // manually - it will just spew checksum errors where PHP expects to see ustar headers, but finds garbage |
|
| 173 | + // from other formats. |
|
| 174 | + // There is no cross-platform way of checking the assets.tar.gz size without unpacking, so we assume the size |
|
| 175 | + // of database is negligible which lets us approximate the size of assets. |
|
| 176 | + if (filesize($file) > 8*1024*1024*1024) { |
|
| 177 | + $msg = <<<EOM |
|
| 178 | 178 | |
| 179 | 179 | ERROR: SSPak is unable to extract archives over 8 GB. |
| 180 | 180 | |
@@ -187,388 +187,388 @@ discard block |
||
| 187 | 187 | See http://silverstripe.github.io/sspak/, "Manual access" for more information. |
| 188 | 188 | |
| 189 | 189 | EOM; |
| 190 | - printf($msg, $file); |
|
| 191 | - die(1); |
|
| 192 | - } |
|
| 193 | - |
|
| 194 | - $sspak = new SSPakFile($file, $executor); |
|
| 195 | - |
|
| 196 | - // Validation |
|
| 197 | - if (!$sspak->exists()) { |
|
| 198 | - throw new Exception("File '$file' doesn't exist."); |
|
| 199 | - } |
|
| 200 | - |
|
| 201 | - $phar = $sspak->getPhar(); |
|
| 202 | - $phar->extractTo($dest); |
|
| 203 | - } |
|
| 204 | - |
|
| 205 | - public function listTables($args) |
|
| 206 | - { |
|
| 207 | - $args->requireUnnamed(array('webroot')); |
|
| 208 | - $unnamedArgs = $args->getUnnamedArgs(); |
|
| 209 | - $webroot = $unnamedArgs[0]; |
|
| 210 | - |
|
| 211 | - $db = new DatabaseConnector($webroot); |
|
| 212 | - |
|
| 213 | - print_r($db->getTables()); |
|
| 214 | - } |
|
| 215 | - |
|
| 216 | - public function saveCsv($args) |
|
| 217 | - { |
|
| 218 | - $args->requireUnnamed(array('webroot', 'path')); |
|
| 219 | - $unnamedArgs = $args->getUnnamedArgs(); |
|
| 220 | - $webroot = $unnamedArgs[0]; |
|
| 221 | - $destPath = $unnamedArgs[1]; |
|
| 222 | - |
|
| 223 | - if (!file_exists($destPath)) { |
|
| 224 | - mkdir($destPath) || die("Can't create $destPath"); |
|
| 225 | - } |
|
| 226 | - if (!is_dir($destPath)) { |
|
| 227 | - die("$destPath isn't a directory"); |
|
| 228 | - } |
|
| 229 | - |
|
| 230 | - $db = new DatabaseConnector($webroot); |
|
| 231 | - |
|
| 232 | - foreach ($db->getTables() as $table) { |
|
| 233 | - $filename = $destPath . '/' . $table . '.csv'; |
|
| 234 | - echo $filename . "...\n"; |
|
| 235 | - touch($filename); |
|
| 236 | - $writer = new CsvTableWriter($filename); |
|
| 237 | - $db->saveTable($table, $writer); |
|
| 238 | - } |
|
| 239 | - echo "Done!"; |
|
| 240 | - } |
|
| 241 | - |
|
| 242 | - public function loadCsv($args) |
|
| 243 | - { |
|
| 244 | - $args->requireUnnamed(array('input-path', 'webroot')); |
|
| 245 | - $unnamedArgs = $args->getUnnamedArgs(); |
|
| 246 | - |
|
| 247 | - $srcPath = $unnamedArgs[0]; |
|
| 248 | - $webroot = $unnamedArgs[1]; |
|
| 249 | - |
|
| 250 | - if (!is_dir($srcPath)) { |
|
| 251 | - die("$srcPath isn't a directory"); |
|
| 252 | - } |
|
| 253 | - |
|
| 254 | - $db = new DatabaseConnector($webroot); |
|
| 255 | - |
|
| 256 | - foreach ($db->getTables() as $table) { |
|
| 257 | - $filename = $srcPath . '/' . $table . '.csv'; |
|
| 258 | - if (file_exists($filename)) { |
|
| 259 | - echo $filename . "...\n"; |
|
| 260 | - $reader = new CsvTableReader($filename); |
|
| 261 | - $db->loadTable($table, $reader); |
|
| 262 | - } else { |
|
| 263 | - echo "$filename doesn't exist; skipping.\n"; |
|
| 264 | - } |
|
| 265 | - } |
|
| 266 | - echo "Done!"; |
|
| 267 | - } |
|
| 268 | - /** |
|
| 269 | - * Save a .sspak.phar file |
|
| 270 | - */ |
|
| 271 | - public function save($args) |
|
| 272 | - { |
|
| 273 | - $executor = $this->executor; |
|
| 274 | - |
|
| 275 | - $args->requireUnnamed(array('source webroot', 'dest sspak file')); |
|
| 276 | - |
|
| 277 | - $unnamedArgs = $args->getUnnamedArgs(); |
|
| 278 | - $namedArgs = $args->getNamedArgs(); |
|
| 279 | - |
|
| 280 | - $webroot = new Webroot($unnamedArgs[0], $executor); |
|
| 281 | - $file = $unnamedArgs[1]; |
|
| 282 | - if (file_exists($file)) { |
|
| 283 | - throw new Exception("File '$file' already exists."); |
|
| 284 | - } |
|
| 285 | - |
|
| 286 | - $sspak = new SSPakFile($file, $executor); |
|
| 287 | - |
|
| 288 | - if (!empty($namedArgs['identity'])) { |
|
| 289 | - // SSH private key |
|
| 290 | - $webroot->setSSHItentityFile($namedArgs['identity']); |
|
| 291 | - } |
|
| 292 | - if (!empty($namedArgs['from-sudo'])) { |
|
| 293 | - $webroot->setSudo($namedArgs['from-sudo']); |
|
| 294 | - } elseif (!empty($namedArgs['sudo'])) { |
|
| 295 | - $webroot->setSudo($namedArgs['sudo']); |
|
| 296 | - } |
|
| 297 | - |
|
| 298 | - // Look up which parts of the sspak are going to be saved |
|
| 299 | - $pakParts = $args->pakParts(); |
|
| 300 | - |
|
| 301 | - // Get the environment details |
|
| 302 | - $details = $webroot->sniff(); |
|
| 303 | - |
|
| 304 | - // Create a build folder for the sspak file |
|
| 305 | - $buildFolder = sprintf("%s/sspak-%d", sys_get_temp_dir(), rand(100000, 999999)); |
|
| 306 | - $webroot->exec(array('mkdir', $buildFolder)); |
|
| 307 | - |
|
| 308 | - $dbFile = "$buildFolder/database.sql.gz"; |
|
| 309 | - $assetsFile = "$buildFolder/assets.tar.gz"; |
|
| 310 | - $gitRemoteFile = "$buildFolder/git-remote"; |
|
| 311 | - |
|
| 312 | - // Files to include in the .sspak.phar file |
|
| 313 | - $fileList = array(); |
|
| 314 | - |
|
| 315 | - // Save DB |
|
| 316 | - if ($pakParts['db']) { |
|
| 317 | - // Check the database type |
|
| 318 | - $dbFunction = 'getdb_'.$details['db_type']; |
|
| 319 | - if (!method_exists($this, $dbFunction)) { |
|
| 320 | - throw new Exception("Can't process database type '" . $details['db_type'] . "'"); |
|
| 321 | - } |
|
| 322 | - $this->$dbFunction($webroot, $details, $sspak, basename($dbFile)); |
|
| 323 | - } |
|
| 324 | - |
|
| 325 | - // Save Assets |
|
| 326 | - if ($pakParts['assets']) { |
|
| 327 | - $this->getassets($webroot, $details['assets_path'], $sspak, basename($assetsFile)); |
|
| 328 | - } |
|
| 329 | - |
|
| 330 | - // Save git-remote |
|
| 331 | - if ($pakParts['git-remote']) { |
|
| 332 | - $this->getgitremote($webroot, $sspak, basename($gitRemoteFile)); |
|
| 333 | - } |
|
| 334 | - |
|
| 335 | - // Remove the build folder |
|
| 336 | - $webroot->unlink($buildFolder); |
|
| 337 | - } |
|
| 338 | - |
|
| 339 | - public function getdb_MySQLPDODatabase($webroot, $conf, $sspak, $filename) |
|
| 340 | - { |
|
| 341 | - return $this->getdb_MySQLDatabase($webroot, $conf, $sspak, $filename); |
|
| 342 | - } |
|
| 343 | - |
|
| 344 | - public function getdb_MySQLDatabase($webroot, $conf, $sspak, $filename) |
|
| 345 | - { |
|
| 346 | - $usernameArg = escapeshellarg("--user=".$conf['db_username']); |
|
| 347 | - $passwordArg = escapeshellarg("--password=".$conf['db_password']); |
|
| 348 | - $databaseArg = escapeshellarg($conf['db_database']); |
|
| 349 | - |
|
| 350 | - $hostArg = ''; |
|
| 351 | - $portArg = ''; |
|
| 352 | - if (!empty($conf['db_server']) && $conf['db_server'] != 'localhost') { |
|
| 353 | - if (strpos($conf['db_server'], ':')!==false) { |
|
| 354 | - // Handle "server:port" format. |
|
| 355 | - $server = explode(':', $conf['db_server'], 2); |
|
| 356 | - $hostArg = escapeshellarg("--host=".$server[0]); |
|
| 357 | - $portArg = escapeshellarg("--port=".$server[1]); |
|
| 358 | - } else { |
|
| 359 | - $hostArg = escapeshellarg("--host=".$conf['db_server']); |
|
| 360 | - } |
|
| 361 | - } |
|
| 362 | - |
|
| 363 | - $filenameArg = escapeshellarg($filename); |
|
| 364 | - |
|
| 365 | - $process = $webroot->createProcess( |
|
| 366 | - "mysqldump --no-tablespaces --skip-opt --add-drop-table --extended-insert --create-options --quick " . |
|
| 367 | - "--set-charset --default-character-set=utf8 --column-statistics=0 $usernameArg $passwordArg $hostArg " . |
|
| 368 | - "$portArg $databaseArg | gzip -c" |
|
| 369 | - ); |
|
| 370 | - $sspak->writeFileFromProcess($filename, $process); |
|
| 371 | - return true; |
|
| 372 | - } |
|
| 373 | - |
|
| 374 | - public function getdb_PostgreSQLDatabase($webroot, $conf, $sspak, $filename) |
|
| 375 | - { |
|
| 376 | - $usernameArg = escapeshellarg("--username=".$conf['db_username']); |
|
| 377 | - $passwordArg = "PGPASSWORD=".escapeshellarg($conf['db_password']); |
|
| 378 | - $databaseArg = escapeshellarg($conf['db_database']); |
|
| 379 | - $hostArg = escapeshellarg("--host=".$conf['db_server']); |
|
| 380 | - $filenameArg = escapeshellarg($filename); |
|
| 381 | - |
|
| 382 | - $process = $webroot->createProcess( |
|
| 383 | - "$passwordArg pg_dump --clean --no-owner --no-tablespaces $usernameArg $hostArg $databaseArg | gzip -c" |
|
| 384 | - ); |
|
| 385 | - $sspak->writeFileFromProcess($filename, $process); |
|
| 386 | - return true; |
|
| 387 | - } |
|
| 388 | - |
|
| 389 | - public function getassets($webroot, $assetsPath, $sspak, $filename) |
|
| 390 | - { |
|
| 391 | - $assetsParentArg = escapeshellarg(dirname($assetsPath)); |
|
| 392 | - $assetsBaseArg = escapeshellarg(basename($assetsPath)); |
|
| 393 | - |
|
| 394 | - $process = $webroot->createProcess("cd $assetsParentArg && tar cfh - $assetsBaseArg | gzip -c"); |
|
| 395 | - $sspak->writeFileFromProcess($filename, $process); |
|
| 396 | - } |
|
| 397 | - |
|
| 398 | - public function getgitremote($webroot, $sspak, $gitRemoteFile) |
|
| 399 | - { |
|
| 400 | - // Only do anything if we're copying from a git checkout |
|
| 401 | - $gitRepo = $webroot->getPath() .'/.git'; |
|
| 402 | - if ($webroot->exists($gitRepo)) { |
|
| 403 | - // Identify current branch |
|
| 404 | - $output = $webroot->exec(array('git', '--git-dir='.$gitRepo, 'branch')); |
|
| 405 | - if (preg_match("/\* ([^ \n]*)/", $output['output'], $matches) && |
|
| 406 | - strpos("(no branch)", $matches[1])===false |
|
| 407 | - ) { |
|
| 408 | - // If there is a current branch, use that branch's remove |
|
| 409 | - $currentBranch = trim($matches[1]); |
|
| 410 | - $output = $webroot->exec( |
|
| 411 | - array('git', '--git-dir='.$gitRepo, 'config','--get',"branch.$currentBranch.remote") |
|
| 412 | - ); |
|
| 413 | - $remoteName = trim($output['output']); |
|
| 414 | - if (!$remoteName) { |
|
| 415 | - $remoteName = 'origin'; |
|
| 416 | - } |
|
| 417 | - |
|
| 418 | - // Default to origin |
|
| 419 | - } else { |
|
| 420 | - $currentBranch = null; |
|
| 421 | - $remoteName = 'origin'; |
|
| 422 | - } |
|
| 423 | - |
|
| 424 | - // Determine the URL of that remote |
|
| 425 | - $output = $webroot->exec(array('git', '--git-dir='.$gitRepo, 'config','--get',"remote.$remoteName.url")); |
|
| 426 | - $remoteURL = trim($output['output']); |
|
| 427 | - |
|
| 428 | - // Determine the current SHA |
|
| 429 | - $output = $webroot->exec(array('git', '--git-dir='.$gitRepo, 'log','-1','--format=%H')); |
|
| 430 | - $sha = trim($output['output']); |
|
| 431 | - |
|
| 432 | - $content = "remote = $remoteURL\nbranch = $currentBranch\nsha = $sha\n"; |
|
| 433 | - |
|
| 434 | - $sspak->writeFile($gitRemoteFile, $content); |
|
| 435 | - |
|
| 436 | - return true; |
|
| 437 | - } |
|
| 438 | - return false; |
|
| 439 | - } |
|
| 440 | - |
|
| 441 | - /** |
|
| 442 | - * Load an .sspak into an environment. |
|
| 443 | - * Does not backup - be careful! */ |
|
| 444 | - public function load($args) |
|
| 445 | - { |
|
| 446 | - $executor = $this->executor; |
|
| 447 | - |
|
| 448 | - $args->requireUnnamed(array('source sspak file')); |
|
| 449 | - |
|
| 450 | - // Set-up |
|
| 451 | - $file = $args->unnamed(0); |
|
| 452 | - $sspak = new SSPakFile($file, $executor); |
|
| 453 | - $webroot = new Webroot(($args->unnamed(1) ?: '.'), $executor); |
|
| 454 | - $webroot->setSudo($args->sudo('to')); |
|
| 455 | - $pakParts = $args->pakParts(); |
|
| 456 | - |
|
| 457 | - $namedArgs = $args->getNamedArgs(); |
|
| 458 | - if (!empty($namedArgs['identity'])) { |
|
| 459 | - // SSH private key |
|
| 460 | - $webroot->setSSHItentityFile($namedArgs['identity']); |
|
| 461 | - } |
|
| 462 | - |
|
| 463 | - // Validation |
|
| 464 | - if (!$sspak->exists()) { |
|
| 465 | - throw new Exception("File '$file' doesn't exist."); |
|
| 466 | - } |
|
| 467 | - |
|
| 468 | - // Push database, if necessary |
|
| 469 | - $namedArgs = $args->getNamedArgs(); |
|
| 470 | - if ($pakParts['db'] && $sspak->contains('database.sql.gz')) { |
|
| 471 | - $webroot->putdb($sspak, isset($namedArgs['drop-db'])); |
|
| 472 | - } |
|
| 473 | - |
|
| 474 | - // Push assets, if neccessary |
|
| 475 | - if ($pakParts['assets'] && $sspak->contains('assets.tar.gz')) { |
|
| 476 | - $webroot->putassets($sspak); |
|
| 477 | - } |
|
| 478 | - } |
|
| 479 | - |
|
| 480 | - /** |
|
| 481 | - * Install an .sspak into a new environment. |
|
| 482 | - */ |
|
| 483 | - public function install($args) |
|
| 484 | - { |
|
| 485 | - $executor = $this->executor; |
|
| 486 | - |
|
| 487 | - $args->requireUnnamed(array('source sspak file', 'dest new webroot')); |
|
| 488 | - |
|
| 489 | - // Set-up |
|
| 490 | - $file = $args->unnamed(0); |
|
| 491 | - $webrootDir = $args->unnamed(1); |
|
| 492 | - $sspak = new SSPakFile($file, $executor); |
|
| 493 | - $webroot = new Webroot($webrootDir, $executor); |
|
| 494 | - $webroot->setSudo($args->sudo('to')); |
|
| 495 | - $pakParts = $args->pakParts(); |
|
| 496 | - |
|
| 497 | - // Validation |
|
| 498 | - if ($webroot->exists($webroot->getPath())) { |
|
| 499 | - throw new Exception("Webroot '$webrootDir' already exists."); |
|
| 500 | - } |
|
| 501 | - if (!$sspak->exists()) { |
|
| 502 | - throw new Exception("File '$file' doesn't exist."); |
|
| 503 | - } |
|
| 504 | - |
|
| 505 | - // Create new dir |
|
| 506 | - $webroot->exec(array('mkdir', $webroot->getPath())); |
|
| 507 | - |
|
| 508 | - if ($sspak->contains('git-remote')) { |
|
| 509 | - $details = $sspak->gitRemoteDetails(); |
|
| 510 | - $webroot->putgit($details); |
|
| 511 | - } |
|
| 512 | - |
|
| 513 | - // TODO: composer install needed. |
|
| 514 | - |
|
| 515 | - // Push database, if necessary |
|
| 516 | - $namedArgs = $args->getNamedArgs(); |
|
| 517 | - if ($pakParts['db'] && $sspak->contains('database.sql.gz')) { |
|
| 518 | - $webroot->putdb($sspak, isset($namedArgs['drop-db'])); |
|
| 519 | - } |
|
| 520 | - |
|
| 521 | - // Push assets, if neccessary |
|
| 522 | - if ($pakParts['assets'] && $sspak->contains('assets.tar.gz')) { |
|
| 523 | - $webroot->putassets($sspak); |
|
| 524 | - } |
|
| 525 | - } |
|
| 526 | - |
|
| 527 | - /** |
|
| 528 | - * Bundle a .sspak into a self-extracting executable installer. |
|
| 529 | - */ |
|
| 530 | - public function bundle($args) |
|
| 531 | - { |
|
| 532 | - // TODO: throws require_once errors, fix before re-enabling. |
|
| 533 | - |
|
| 534 | - $executor = $this->executor; |
|
| 535 | - |
|
| 536 | - $args->requireUnnamed(array('source sspak file', 'dest executable file')); |
|
| 537 | - |
|
| 538 | - // Set-up |
|
| 539 | - $sourceFile = $args->unnamed(0); |
|
| 540 | - $destFile = $args->unnamed(1); |
|
| 541 | - |
|
| 542 | - $sspakScript = file_get_contents($_SERVER['argv'][0]); |
|
| 543 | - // Broken up to not get detected by our sed command |
|
| 544 | - $sspakScript .= "\n__halt_compiler();\n"."//"." TAR START?>\n"; |
|
| 545 | - |
|
| 546 | - // Mark as self-extracting |
|
| 547 | - $sspakScript = str_replace('$isSelfExtracting = false;', '$isSelfExtracting = true;', $sspakScript); |
|
| 548 | - |
|
| 549 | - // Load the sniffer file |
|
| 550 | - $snifferFile = dirname(__FILE__) . '/sspak-sniffer.php'; |
|
| 551 | - $sspakScript = str_replace( |
|
| 552 | - "\$snifferFileContent = '';\n", |
|
| 553 | - "\$snifferFileContent = '" |
|
| 554 | - . str_replace(array("\\","'"), array("\\\\", "\\'"), file_get_contents($snifferFile)) . "';\n", |
|
| 555 | - $sspakScript |
|
| 556 | - ); |
|
| 557 | - |
|
| 558 | - file_put_contents($destFile, $sspakScript); |
|
| 559 | - chmod($destFile, 0775); |
|
| 560 | - |
|
| 561 | - $executor->execLocal(array('cat', $sourceFile), array( |
|
| 562 | - 'outputFile' => $destFile, |
|
| 563 | - 'outputFileAppend' => true |
|
| 564 | - )); |
|
| 565 | - } |
|
| 566 | - |
|
| 567 | - /** |
|
| 568 | - * Transfer between environments without creating an sspak file |
|
| 569 | - */ |
|
| 570 | - public function transfer($args) |
|
| 571 | - { |
|
| 572 | - echo "Not implemented yet.\n"; |
|
| 573 | - } |
|
| 190 | + printf($msg, $file); |
|
| 191 | + die(1); |
|
| 192 | + } |
|
| 193 | + |
|
| 194 | + $sspak = new SSPakFile($file, $executor); |
|
| 195 | + |
|
| 196 | + // Validation |
|
| 197 | + if (!$sspak->exists()) { |
|
| 198 | + throw new Exception("File '$file' doesn't exist."); |
|
| 199 | + } |
|
| 200 | + |
|
| 201 | + $phar = $sspak->getPhar(); |
|
| 202 | + $phar->extractTo($dest); |
|
| 203 | + } |
|
| 204 | + |
|
| 205 | + public function listTables($args) |
|
| 206 | + { |
|
| 207 | + $args->requireUnnamed(array('webroot')); |
|
| 208 | + $unnamedArgs = $args->getUnnamedArgs(); |
|
| 209 | + $webroot = $unnamedArgs[0]; |
|
| 210 | + |
|
| 211 | + $db = new DatabaseConnector($webroot); |
|
| 212 | + |
|
| 213 | + print_r($db->getTables()); |
|
| 214 | + } |
|
| 215 | + |
|
| 216 | + public function saveCsv($args) |
|
| 217 | + { |
|
| 218 | + $args->requireUnnamed(array('webroot', 'path')); |
|
| 219 | + $unnamedArgs = $args->getUnnamedArgs(); |
|
| 220 | + $webroot = $unnamedArgs[0]; |
|
| 221 | + $destPath = $unnamedArgs[1]; |
|
| 222 | + |
|
| 223 | + if (!file_exists($destPath)) { |
|
| 224 | + mkdir($destPath) || die("Can't create $destPath"); |
|
| 225 | + } |
|
| 226 | + if (!is_dir($destPath)) { |
|
| 227 | + die("$destPath isn't a directory"); |
|
| 228 | + } |
|
| 229 | + |
|
| 230 | + $db = new DatabaseConnector($webroot); |
|
| 231 | + |
|
| 232 | + foreach ($db->getTables() as $table) { |
|
| 233 | + $filename = $destPath . '/' . $table . '.csv'; |
|
| 234 | + echo $filename . "...\n"; |
|
| 235 | + touch($filename); |
|
| 236 | + $writer = new CsvTableWriter($filename); |
|
| 237 | + $db->saveTable($table, $writer); |
|
| 238 | + } |
|
| 239 | + echo "Done!"; |
|
| 240 | + } |
|
| 241 | + |
|
| 242 | + public function loadCsv($args) |
|
| 243 | + { |
|
| 244 | + $args->requireUnnamed(array('input-path', 'webroot')); |
|
| 245 | + $unnamedArgs = $args->getUnnamedArgs(); |
|
| 246 | + |
|
| 247 | + $srcPath = $unnamedArgs[0]; |
|
| 248 | + $webroot = $unnamedArgs[1]; |
|
| 249 | + |
|
| 250 | + if (!is_dir($srcPath)) { |
|
| 251 | + die("$srcPath isn't a directory"); |
|
| 252 | + } |
|
| 253 | + |
|
| 254 | + $db = new DatabaseConnector($webroot); |
|
| 255 | + |
|
| 256 | + foreach ($db->getTables() as $table) { |
|
| 257 | + $filename = $srcPath . '/' . $table . '.csv'; |
|
| 258 | + if (file_exists($filename)) { |
|
| 259 | + echo $filename . "...\n"; |
|
| 260 | + $reader = new CsvTableReader($filename); |
|
| 261 | + $db->loadTable($table, $reader); |
|
| 262 | + } else { |
|
| 263 | + echo "$filename doesn't exist; skipping.\n"; |
|
| 264 | + } |
|
| 265 | + } |
|
| 266 | + echo "Done!"; |
|
| 267 | + } |
|
| 268 | + /** |
|
| 269 | + * Save a .sspak.phar file |
|
| 270 | + */ |
|
| 271 | + public function save($args) |
|
| 272 | + { |
|
| 273 | + $executor = $this->executor; |
|
| 274 | + |
|
| 275 | + $args->requireUnnamed(array('source webroot', 'dest sspak file')); |
|
| 276 | + |
|
| 277 | + $unnamedArgs = $args->getUnnamedArgs(); |
|
| 278 | + $namedArgs = $args->getNamedArgs(); |
|
| 279 | + |
|
| 280 | + $webroot = new Webroot($unnamedArgs[0], $executor); |
|
| 281 | + $file = $unnamedArgs[1]; |
|
| 282 | + if (file_exists($file)) { |
|
| 283 | + throw new Exception("File '$file' already exists."); |
|
| 284 | + } |
|
| 285 | + |
|
| 286 | + $sspak = new SSPakFile($file, $executor); |
|
| 287 | + |
|
| 288 | + if (!empty($namedArgs['identity'])) { |
|
| 289 | + // SSH private key |
|
| 290 | + $webroot->setSSHItentityFile($namedArgs['identity']); |
|
| 291 | + } |
|
| 292 | + if (!empty($namedArgs['from-sudo'])) { |
|
| 293 | + $webroot->setSudo($namedArgs['from-sudo']); |
|
| 294 | + } elseif (!empty($namedArgs['sudo'])) { |
|
| 295 | + $webroot->setSudo($namedArgs['sudo']); |
|
| 296 | + } |
|
| 297 | + |
|
| 298 | + // Look up which parts of the sspak are going to be saved |
|
| 299 | + $pakParts = $args->pakParts(); |
|
| 300 | + |
|
| 301 | + // Get the environment details |
|
| 302 | + $details = $webroot->sniff(); |
|
| 303 | + |
|
| 304 | + // Create a build folder for the sspak file |
|
| 305 | + $buildFolder = sprintf("%s/sspak-%d", sys_get_temp_dir(), rand(100000, 999999)); |
|
| 306 | + $webroot->exec(array('mkdir', $buildFolder)); |
|
| 307 | + |
|
| 308 | + $dbFile = "$buildFolder/database.sql.gz"; |
|
| 309 | + $assetsFile = "$buildFolder/assets.tar.gz"; |
|
| 310 | + $gitRemoteFile = "$buildFolder/git-remote"; |
|
| 311 | + |
|
| 312 | + // Files to include in the .sspak.phar file |
|
| 313 | + $fileList = array(); |
|
| 314 | + |
|
| 315 | + // Save DB |
|
| 316 | + if ($pakParts['db']) { |
|
| 317 | + // Check the database type |
|
| 318 | + $dbFunction = 'getdb_'.$details['db_type']; |
|
| 319 | + if (!method_exists($this, $dbFunction)) { |
|
| 320 | + throw new Exception("Can't process database type '" . $details['db_type'] . "'"); |
|
| 321 | + } |
|
| 322 | + $this->$dbFunction($webroot, $details, $sspak, basename($dbFile)); |
|
| 323 | + } |
|
| 324 | + |
|
| 325 | + // Save Assets |
|
| 326 | + if ($pakParts['assets']) { |
|
| 327 | + $this->getassets($webroot, $details['assets_path'], $sspak, basename($assetsFile)); |
|
| 328 | + } |
|
| 329 | + |
|
| 330 | + // Save git-remote |
|
| 331 | + if ($pakParts['git-remote']) { |
|
| 332 | + $this->getgitremote($webroot, $sspak, basename($gitRemoteFile)); |
|
| 333 | + } |
|
| 334 | + |
|
| 335 | + // Remove the build folder |
|
| 336 | + $webroot->unlink($buildFolder); |
|
| 337 | + } |
|
| 338 | + |
|
| 339 | + public function getdb_MySQLPDODatabase($webroot, $conf, $sspak, $filename) |
|
| 340 | + { |
|
| 341 | + return $this->getdb_MySQLDatabase($webroot, $conf, $sspak, $filename); |
|
| 342 | + } |
|
| 343 | + |
|
| 344 | + public function getdb_MySQLDatabase($webroot, $conf, $sspak, $filename) |
|
| 345 | + { |
|
| 346 | + $usernameArg = escapeshellarg("--user=".$conf['db_username']); |
|
| 347 | + $passwordArg = escapeshellarg("--password=".$conf['db_password']); |
|
| 348 | + $databaseArg = escapeshellarg($conf['db_database']); |
|
| 349 | + |
|
| 350 | + $hostArg = ''; |
|
| 351 | + $portArg = ''; |
|
| 352 | + if (!empty($conf['db_server']) && $conf['db_server'] != 'localhost') { |
|
| 353 | + if (strpos($conf['db_server'], ':')!==false) { |
|
| 354 | + // Handle "server:port" format. |
|
| 355 | + $server = explode(':', $conf['db_server'], 2); |
|
| 356 | + $hostArg = escapeshellarg("--host=".$server[0]); |
|
| 357 | + $portArg = escapeshellarg("--port=".$server[1]); |
|
| 358 | + } else { |
|
| 359 | + $hostArg = escapeshellarg("--host=".$conf['db_server']); |
|
| 360 | + } |
|
| 361 | + } |
|
| 362 | + |
|
| 363 | + $filenameArg = escapeshellarg($filename); |
|
| 364 | + |
|
| 365 | + $process = $webroot->createProcess( |
|
| 366 | + "mysqldump --no-tablespaces --skip-opt --add-drop-table --extended-insert --create-options --quick " . |
|
| 367 | + "--set-charset --default-character-set=utf8 --column-statistics=0 $usernameArg $passwordArg $hostArg " . |
|
| 368 | + "$portArg $databaseArg | gzip -c" |
|
| 369 | + ); |
|
| 370 | + $sspak->writeFileFromProcess($filename, $process); |
|
| 371 | + return true; |
|
| 372 | + } |
|
| 373 | + |
|
| 374 | + public function getdb_PostgreSQLDatabase($webroot, $conf, $sspak, $filename) |
|
| 375 | + { |
|
| 376 | + $usernameArg = escapeshellarg("--username=".$conf['db_username']); |
|
| 377 | + $passwordArg = "PGPASSWORD=".escapeshellarg($conf['db_password']); |
|
| 378 | + $databaseArg = escapeshellarg($conf['db_database']); |
|
| 379 | + $hostArg = escapeshellarg("--host=".$conf['db_server']); |
|
| 380 | + $filenameArg = escapeshellarg($filename); |
|
| 381 | + |
|
| 382 | + $process = $webroot->createProcess( |
|
| 383 | + "$passwordArg pg_dump --clean --no-owner --no-tablespaces $usernameArg $hostArg $databaseArg | gzip -c" |
|
| 384 | + ); |
|
| 385 | + $sspak->writeFileFromProcess($filename, $process); |
|
| 386 | + return true; |
|
| 387 | + } |
|
| 388 | + |
|
| 389 | + public function getassets($webroot, $assetsPath, $sspak, $filename) |
|
| 390 | + { |
|
| 391 | + $assetsParentArg = escapeshellarg(dirname($assetsPath)); |
|
| 392 | + $assetsBaseArg = escapeshellarg(basename($assetsPath)); |
|
| 393 | + |
|
| 394 | + $process = $webroot->createProcess("cd $assetsParentArg && tar cfh - $assetsBaseArg | gzip -c"); |
|
| 395 | + $sspak->writeFileFromProcess($filename, $process); |
|
| 396 | + } |
|
| 397 | + |
|
| 398 | + public function getgitremote($webroot, $sspak, $gitRemoteFile) |
|
| 399 | + { |
|
| 400 | + // Only do anything if we're copying from a git checkout |
|
| 401 | + $gitRepo = $webroot->getPath() .'/.git'; |
|
| 402 | + if ($webroot->exists($gitRepo)) { |
|
| 403 | + // Identify current branch |
|
| 404 | + $output = $webroot->exec(array('git', '--git-dir='.$gitRepo, 'branch')); |
|
| 405 | + if (preg_match("/\* ([^ \n]*)/", $output['output'], $matches) && |
|
| 406 | + strpos("(no branch)", $matches[1])===false |
|
| 407 | + ) { |
|
| 408 | + // If there is a current branch, use that branch's remove |
|
| 409 | + $currentBranch = trim($matches[1]); |
|
| 410 | + $output = $webroot->exec( |
|
| 411 | + array('git', '--git-dir='.$gitRepo, 'config','--get',"branch.$currentBranch.remote") |
|
| 412 | + ); |
|
| 413 | + $remoteName = trim($output['output']); |
|
| 414 | + if (!$remoteName) { |
|
| 415 | + $remoteName = 'origin'; |
|
| 416 | + } |
|
| 417 | + |
|
| 418 | + // Default to origin |
|
| 419 | + } else { |
|
| 420 | + $currentBranch = null; |
|
| 421 | + $remoteName = 'origin'; |
|
| 422 | + } |
|
| 423 | + |
|
| 424 | + // Determine the URL of that remote |
|
| 425 | + $output = $webroot->exec(array('git', '--git-dir='.$gitRepo, 'config','--get',"remote.$remoteName.url")); |
|
| 426 | + $remoteURL = trim($output['output']); |
|
| 427 | + |
|
| 428 | + // Determine the current SHA |
|
| 429 | + $output = $webroot->exec(array('git', '--git-dir='.$gitRepo, 'log','-1','--format=%H')); |
|
| 430 | + $sha = trim($output['output']); |
|
| 431 | + |
|
| 432 | + $content = "remote = $remoteURL\nbranch = $currentBranch\nsha = $sha\n"; |
|
| 433 | + |
|
| 434 | + $sspak->writeFile($gitRemoteFile, $content); |
|
| 435 | + |
|
| 436 | + return true; |
|
| 437 | + } |
|
| 438 | + return false; |
|
| 439 | + } |
|
| 440 | + |
|
| 441 | + /** |
|
| 442 | + * Load an .sspak into an environment. |
|
| 443 | + * Does not backup - be careful! */ |
|
| 444 | + public function load($args) |
|
| 445 | + { |
|
| 446 | + $executor = $this->executor; |
|
| 447 | + |
|
| 448 | + $args->requireUnnamed(array('source sspak file')); |
|
| 449 | + |
|
| 450 | + // Set-up |
|
| 451 | + $file = $args->unnamed(0); |
|
| 452 | + $sspak = new SSPakFile($file, $executor); |
|
| 453 | + $webroot = new Webroot(($args->unnamed(1) ?: '.'), $executor); |
|
| 454 | + $webroot->setSudo($args->sudo('to')); |
|
| 455 | + $pakParts = $args->pakParts(); |
|
| 456 | + |
|
| 457 | + $namedArgs = $args->getNamedArgs(); |
|
| 458 | + if (!empty($namedArgs['identity'])) { |
|
| 459 | + // SSH private key |
|
| 460 | + $webroot->setSSHItentityFile($namedArgs['identity']); |
|
| 461 | + } |
|
| 462 | + |
|
| 463 | + // Validation |
|
| 464 | + if (!$sspak->exists()) { |
|
| 465 | + throw new Exception("File '$file' doesn't exist."); |
|
| 466 | + } |
|
| 467 | + |
|
| 468 | + // Push database, if necessary |
|
| 469 | + $namedArgs = $args->getNamedArgs(); |
|
| 470 | + if ($pakParts['db'] && $sspak->contains('database.sql.gz')) { |
|
| 471 | + $webroot->putdb($sspak, isset($namedArgs['drop-db'])); |
|
| 472 | + } |
|
| 473 | + |
|
| 474 | + // Push assets, if neccessary |
|
| 475 | + if ($pakParts['assets'] && $sspak->contains('assets.tar.gz')) { |
|
| 476 | + $webroot->putassets($sspak); |
|
| 477 | + } |
|
| 478 | + } |
|
| 479 | + |
|
| 480 | + /** |
|
| 481 | + * Install an .sspak into a new environment. |
|
| 482 | + */ |
|
| 483 | + public function install($args) |
|
| 484 | + { |
|
| 485 | + $executor = $this->executor; |
|
| 486 | + |
|
| 487 | + $args->requireUnnamed(array('source sspak file', 'dest new webroot')); |
|
| 488 | + |
|
| 489 | + // Set-up |
|
| 490 | + $file = $args->unnamed(0); |
|
| 491 | + $webrootDir = $args->unnamed(1); |
|
| 492 | + $sspak = new SSPakFile($file, $executor); |
|
| 493 | + $webroot = new Webroot($webrootDir, $executor); |
|
| 494 | + $webroot->setSudo($args->sudo('to')); |
|
| 495 | + $pakParts = $args->pakParts(); |
|
| 496 | + |
|
| 497 | + // Validation |
|
| 498 | + if ($webroot->exists($webroot->getPath())) { |
|
| 499 | + throw new Exception("Webroot '$webrootDir' already exists."); |
|
| 500 | + } |
|
| 501 | + if (!$sspak->exists()) { |
|
| 502 | + throw new Exception("File '$file' doesn't exist."); |
|
| 503 | + } |
|
| 504 | + |
|
| 505 | + // Create new dir |
|
| 506 | + $webroot->exec(array('mkdir', $webroot->getPath())); |
|
| 507 | + |
|
| 508 | + if ($sspak->contains('git-remote')) { |
|
| 509 | + $details = $sspak->gitRemoteDetails(); |
|
| 510 | + $webroot->putgit($details); |
|
| 511 | + } |
|
| 512 | + |
|
| 513 | + // TODO: composer install needed. |
|
| 514 | + |
|
| 515 | + // Push database, if necessary |
|
| 516 | + $namedArgs = $args->getNamedArgs(); |
|
| 517 | + if ($pakParts['db'] && $sspak->contains('database.sql.gz')) { |
|
| 518 | + $webroot->putdb($sspak, isset($namedArgs['drop-db'])); |
|
| 519 | + } |
|
| 520 | + |
|
| 521 | + // Push assets, if neccessary |
|
| 522 | + if ($pakParts['assets'] && $sspak->contains('assets.tar.gz')) { |
|
| 523 | + $webroot->putassets($sspak); |
|
| 524 | + } |
|
| 525 | + } |
|
| 526 | + |
|
| 527 | + /** |
|
| 528 | + * Bundle a .sspak into a self-extracting executable installer. |
|
| 529 | + */ |
|
| 530 | + public function bundle($args) |
|
| 531 | + { |
|
| 532 | + // TODO: throws require_once errors, fix before re-enabling. |
|
| 533 | + |
|
| 534 | + $executor = $this->executor; |
|
| 535 | + |
|
| 536 | + $args->requireUnnamed(array('source sspak file', 'dest executable file')); |
|
| 537 | + |
|
| 538 | + // Set-up |
|
| 539 | + $sourceFile = $args->unnamed(0); |
|
| 540 | + $destFile = $args->unnamed(1); |
|
| 541 | + |
|
| 542 | + $sspakScript = file_get_contents($_SERVER['argv'][0]); |
|
| 543 | + // Broken up to not get detected by our sed command |
|
| 544 | + $sspakScript .= "\n__halt_compiler();\n"."//"." TAR START?>\n"; |
|
| 545 | + |
|
| 546 | + // Mark as self-extracting |
|
| 547 | + $sspakScript = str_replace('$isSelfExtracting = false;', '$isSelfExtracting = true;', $sspakScript); |
|
| 548 | + |
|
| 549 | + // Load the sniffer file |
|
| 550 | + $snifferFile = dirname(__FILE__) . '/sspak-sniffer.php'; |
|
| 551 | + $sspakScript = str_replace( |
|
| 552 | + "\$snifferFileContent = '';\n", |
|
| 553 | + "\$snifferFileContent = '" |
|
| 554 | + . str_replace(array("\\","'"), array("\\\\", "\\'"), file_get_contents($snifferFile)) . "';\n", |
|
| 555 | + $sspakScript |
|
| 556 | + ); |
|
| 557 | + |
|
| 558 | + file_put_contents($destFile, $sspakScript); |
|
| 559 | + chmod($destFile, 0775); |
|
| 560 | + |
|
| 561 | + $executor->execLocal(array('cat', $sourceFile), array( |
|
| 562 | + 'outputFile' => $destFile, |
|
| 563 | + 'outputFileAppend' => true |
|
| 564 | + )); |
|
| 565 | + } |
|
| 566 | + |
|
| 567 | + /** |
|
| 568 | + * Transfer between environments without creating an sspak file |
|
| 569 | + */ |
|
| 570 | + public function transfer($args) |
|
| 571 | + { |
|
| 572 | + echo "Not implemented yet.\n"; |
|
| 573 | + } |
|
| 574 | 574 | } |
@@ -45,14 +45,14 @@ discard block |
||
| 45 | 45 | "method" => "load", |
| 46 | 46 | ), |
| 47 | 47 | "saveexisting" => array( |
| 48 | - "description" => "Create an .sspak file from database SQL dump and/or assets. " . |
|
| 48 | + "description" => "Create an .sspak file from database SQL dump and/or assets. ". |
|
| 49 | 49 | "Does not require a SilverStripe site.", |
| 50 | 50 | "unnamedArgs" => array("sspak file"), |
| 51 | 51 | "namedArgs" => array("db", "assets"), |
| 52 | 52 | "method" => "saveexisting" |
| 53 | 53 | ), |
| 54 | 54 | "extract" => array( |
| 55 | - "description" => "Extract an .sspak file into the current working directory. Does not require a " . |
|
| 55 | + "description" => "Extract an .sspak file into the current working directory. Does not require a ". |
|
| 56 | 56 | "SilverStripe site.", |
| 57 | 57 | "unnamedArgs" => array("sspak file", "destination path"), |
| 58 | 58 | "method" => "extract" |
@@ -173,7 +173,7 @@ discard block |
||
| 173 | 173 | // from other formats. |
| 174 | 174 | // There is no cross-platform way of checking the assets.tar.gz size without unpacking, so we assume the size |
| 175 | 175 | // of database is negligible which lets us approximate the size of assets. |
| 176 | - if (filesize($file) > 8*1024*1024*1024) { |
|
| 176 | + if (filesize($file) > 8 * 1024 * 1024 * 1024) { |
|
| 177 | 177 | $msg = <<<EOM |
| 178 | 178 | |
| 179 | 179 | ERROR: SSPak is unable to extract archives over 8 GB. |
@@ -230,8 +230,8 @@ discard block |
||
| 230 | 230 | $db = new DatabaseConnector($webroot); |
| 231 | 231 | |
| 232 | 232 | foreach ($db->getTables() as $table) { |
| 233 | - $filename = $destPath . '/' . $table . '.csv'; |
|
| 234 | - echo $filename . "...\n"; |
|
| 233 | + $filename = $destPath.'/'.$table.'.csv'; |
|
| 234 | + echo $filename."...\n"; |
|
| 235 | 235 | touch($filename); |
| 236 | 236 | $writer = new CsvTableWriter($filename); |
| 237 | 237 | $db->saveTable($table, $writer); |
@@ -254,9 +254,9 @@ discard block |
||
| 254 | 254 | $db = new DatabaseConnector($webroot); |
| 255 | 255 | |
| 256 | 256 | foreach ($db->getTables() as $table) { |
| 257 | - $filename = $srcPath . '/' . $table . '.csv'; |
|
| 257 | + $filename = $srcPath.'/'.$table.'.csv'; |
|
| 258 | 258 | if (file_exists($filename)) { |
| 259 | - echo $filename . "...\n"; |
|
| 259 | + echo $filename."...\n"; |
|
| 260 | 260 | $reader = new CsvTableReader($filename); |
| 261 | 261 | $db->loadTable($table, $reader); |
| 262 | 262 | } else { |
@@ -317,7 +317,7 @@ discard block |
||
| 317 | 317 | // Check the database type |
| 318 | 318 | $dbFunction = 'getdb_'.$details['db_type']; |
| 319 | 319 | if (!method_exists($this, $dbFunction)) { |
| 320 | - throw new Exception("Can't process database type '" . $details['db_type'] . "'"); |
|
| 320 | + throw new Exception("Can't process database type '".$details['db_type']."'"); |
|
| 321 | 321 | } |
| 322 | 322 | $this->$dbFunction($webroot, $details, $sspak, basename($dbFile)); |
| 323 | 323 | } |
@@ -350,7 +350,7 @@ discard block |
||
| 350 | 350 | $hostArg = ''; |
| 351 | 351 | $portArg = ''; |
| 352 | 352 | if (!empty($conf['db_server']) && $conf['db_server'] != 'localhost') { |
| 353 | - if (strpos($conf['db_server'], ':')!==false) { |
|
| 353 | + if (strpos($conf['db_server'], ':') !== false) { |
|
| 354 | 354 | // Handle "server:port" format. |
| 355 | 355 | $server = explode(':', $conf['db_server'], 2); |
| 356 | 356 | $hostArg = escapeshellarg("--host=".$server[0]); |
@@ -363,8 +363,8 @@ discard block |
||
| 363 | 363 | $filenameArg = escapeshellarg($filename); |
| 364 | 364 | |
| 365 | 365 | $process = $webroot->createProcess( |
| 366 | - "mysqldump --no-tablespaces --skip-opt --add-drop-table --extended-insert --create-options --quick " . |
|
| 367 | - "--set-charset --default-character-set=utf8 --column-statistics=0 $usernameArg $passwordArg $hostArg " . |
|
| 366 | + "mysqldump --no-tablespaces --skip-opt --add-drop-table --extended-insert --create-options --quick ". |
|
| 367 | + "--set-charset --default-character-set=utf8 --column-statistics=0 $usernameArg $passwordArg $hostArg ". |
|
| 368 | 368 | "$portArg $databaseArg | gzip -c" |
| 369 | 369 | ); |
| 370 | 370 | $sspak->writeFileFromProcess($filename, $process); |
@@ -398,17 +398,17 @@ discard block |
||
| 398 | 398 | public function getgitremote($webroot, $sspak, $gitRemoteFile) |
| 399 | 399 | { |
| 400 | 400 | // Only do anything if we're copying from a git checkout |
| 401 | - $gitRepo = $webroot->getPath() .'/.git'; |
|
| 401 | + $gitRepo = $webroot->getPath().'/.git'; |
|
| 402 | 402 | if ($webroot->exists($gitRepo)) { |
| 403 | 403 | // Identify current branch |
| 404 | 404 | $output = $webroot->exec(array('git', '--git-dir='.$gitRepo, 'branch')); |
| 405 | 405 | if (preg_match("/\* ([^ \n]*)/", $output['output'], $matches) && |
| 406 | - strpos("(no branch)", $matches[1])===false |
|
| 406 | + strpos("(no branch)", $matches[1]) === false |
|
| 407 | 407 | ) { |
| 408 | 408 | // If there is a current branch, use that branch's remove |
| 409 | 409 | $currentBranch = trim($matches[1]); |
| 410 | 410 | $output = $webroot->exec( |
| 411 | - array('git', '--git-dir='.$gitRepo, 'config','--get',"branch.$currentBranch.remote") |
|
| 411 | + array('git', '--git-dir='.$gitRepo, 'config', '--get', "branch.$currentBranch.remote") |
|
| 412 | 412 | ); |
| 413 | 413 | $remoteName = trim($output['output']); |
| 414 | 414 | if (!$remoteName) { |
@@ -422,11 +422,11 @@ discard block |
||
| 422 | 422 | } |
| 423 | 423 | |
| 424 | 424 | // Determine the URL of that remote |
| 425 | - $output = $webroot->exec(array('git', '--git-dir='.$gitRepo, 'config','--get',"remote.$remoteName.url")); |
|
| 425 | + $output = $webroot->exec(array('git', '--git-dir='.$gitRepo, 'config', '--get', "remote.$remoteName.url")); |
|
| 426 | 426 | $remoteURL = trim($output['output']); |
| 427 | 427 | |
| 428 | 428 | // Determine the current SHA |
| 429 | - $output = $webroot->exec(array('git', '--git-dir='.$gitRepo, 'log','-1','--format=%H')); |
|
| 429 | + $output = $webroot->exec(array('git', '--git-dir='.$gitRepo, 'log', '-1', '--format=%H')); |
|
| 430 | 430 | $sha = trim($output['output']); |
| 431 | 431 | |
| 432 | 432 | $content = "remote = $remoteURL\nbranch = $currentBranch\nsha = $sha\n"; |
@@ -547,11 +547,11 @@ discard block |
||
| 547 | 547 | $sspakScript = str_replace('$isSelfExtracting = false;', '$isSelfExtracting = true;', $sspakScript); |
| 548 | 548 | |
| 549 | 549 | // Load the sniffer file |
| 550 | - $snifferFile = dirname(__FILE__) . '/sspak-sniffer.php'; |
|
| 550 | + $snifferFile = dirname(__FILE__).'/sspak-sniffer.php'; |
|
| 551 | 551 | $sspakScript = str_replace( |
| 552 | 552 | "\$snifferFileContent = '';\n", |
| 553 | 553 | "\$snifferFileContent = '" |
| 554 | - . str_replace(array("\\","'"), array("\\\\", "\\'"), file_get_contents($snifferFile)) . "';\n", |
|
| 554 | + . str_replace(array("\\", "'"), array("\\\\", "\\'"), file_get_contents($snifferFile))."';\n", |
|
| 555 | 555 | $sspakScript |
| 556 | 556 | ); |
| 557 | 557 | |
@@ -12,84 +12,84 @@ discard block |
||
| 12 | 12 | |
| 13 | 13 | class SSPakFile extends FilesystemEntity |
| 14 | 14 | { |
| 15 | - protected $phar; |
|
| 16 | - protected $pharAlias; |
|
| 17 | - protected $pharPath; |
|
| 18 | - |
|
| 19 | - public function __construct($path, $executor, $pharAlias = 'sspak.phar') |
|
| 20 | - { |
|
| 21 | - parent::__construct($path, $executor); |
|
| 22 | - if (!$this->isLocal()) { |
|
| 23 | - throw new LogicException("Can't manipulate remote .sspak.phar files, only remote webroots."); |
|
| 24 | - } |
|
| 25 | - |
|
| 26 | - $this->pharAlias = $pharAlias; |
|
| 27 | - $this->pharPath = $path; |
|
| 28 | - |
|
| 29 | - // Executable Phar version |
|
| 30 | - if (substr($path, -5) === '.phar') { |
|
| 31 | - $this->phar = new Phar( |
|
| 32 | - $path, |
|
| 33 | - FilesystemIterator::CURRENT_AS_FILEINFO | FilesystemIterator::KEY_AS_FILENAME, |
|
| 34 | - $this->pharAlias |
|
| 35 | - ); |
|
| 36 | - if (!file_exists($this->path)) { |
|
| 37 | - $this->makeExecutable(); |
|
| 38 | - } |
|
| 39 | - |
|
| 40 | - // Non-executable Tar version |
|
| 41 | - } else { |
|
| 42 | - $this->phar = new PharData( |
|
| 43 | - $path, |
|
| 44 | - FilesystemIterator::CURRENT_AS_FILEINFO | FilesystemIterator::KEY_AS_FILENAME, |
|
| 45 | - $this->pharAlias |
|
| 46 | - ); |
|
| 47 | - } |
|
| 48 | - } |
|
| 49 | - |
|
| 50 | - public function getPhar() |
|
| 51 | - { |
|
| 52 | - return $this->phar; |
|
| 53 | - } |
|
| 54 | - |
|
| 55 | - /** |
|
| 56 | - * Add the SSPak executable information into this SSPak file |
|
| 57 | - */ |
|
| 58 | - public function makeExecutable() |
|
| 59 | - { |
|
| 60 | - if (ini_get('phar.readonly')) { |
|
| 61 | - throw new Exception("Please set phar.readonly to false in your php.ini."); |
|
| 62 | - } |
|
| 63 | - |
|
| 64 | - passthru("composer install -d " . escapeshellarg(PACKAGE_ROOT) . " --no-dev"); |
|
| 65 | - |
|
| 66 | - $root = PACKAGE_ROOT; |
|
| 67 | - $srcRoots = [ |
|
| 68 | - 'src/', |
|
| 69 | - 'vendor/', |
|
| 70 | - ]; |
|
| 71 | - |
|
| 72 | - // Add the bin file, but strip of the #! exec header. |
|
| 73 | - $this->phar['bin/sspak'] = preg_replace( |
|
| 74 | - "/^#!\/usr\/bin\/env php\n/", |
|
| 75 | - '', |
|
| 76 | - file_get_contents($root . "bin/sspak") |
|
| 77 | - ); |
|
| 78 | - |
|
| 79 | - foreach ($srcRoots as $srcRoot) { |
|
| 80 | - foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($root . $srcRoot)) as $fileObj) { |
|
| 81 | - if ($fileObj->isFile()) { |
|
| 82 | - $file = $fileObj->getRealPath(); |
|
| 83 | - |
|
| 84 | - $relativeFile = str_replace($root, '', $file); |
|
| 85 | - |
|
| 86 | - echo "Adding $relativeFile\n"; |
|
| 87 | - $this->phar[$relativeFile] = file_get_contents($file); |
|
| 88 | - } |
|
| 89 | - } |
|
| 90 | - } |
|
| 91 | - |
|
| 92 | - $stub = <<<STUB |
|
| 15 | + protected $phar; |
|
| 16 | + protected $pharAlias; |
|
| 17 | + protected $pharPath; |
|
| 18 | + |
|
| 19 | + public function __construct($path, $executor, $pharAlias = 'sspak.phar') |
|
| 20 | + { |
|
| 21 | + parent::__construct($path, $executor); |
|
| 22 | + if (!$this->isLocal()) { |
|
| 23 | + throw new LogicException("Can't manipulate remote .sspak.phar files, only remote webroots."); |
|
| 24 | + } |
|
| 25 | + |
|
| 26 | + $this->pharAlias = $pharAlias; |
|
| 27 | + $this->pharPath = $path; |
|
| 28 | + |
|
| 29 | + // Executable Phar version |
|
| 30 | + if (substr($path, -5) === '.phar') { |
|
| 31 | + $this->phar = new Phar( |
|
| 32 | + $path, |
|
| 33 | + FilesystemIterator::CURRENT_AS_FILEINFO | FilesystemIterator::KEY_AS_FILENAME, |
|
| 34 | + $this->pharAlias |
|
| 35 | + ); |
|
| 36 | + if (!file_exists($this->path)) { |
|
| 37 | + $this->makeExecutable(); |
|
| 38 | + } |
|
| 39 | + |
|
| 40 | + // Non-executable Tar version |
|
| 41 | + } else { |
|
| 42 | + $this->phar = new PharData( |
|
| 43 | + $path, |
|
| 44 | + FilesystemIterator::CURRENT_AS_FILEINFO | FilesystemIterator::KEY_AS_FILENAME, |
|
| 45 | + $this->pharAlias |
|
| 46 | + ); |
|
| 47 | + } |
|
| 48 | + } |
|
| 49 | + |
|
| 50 | + public function getPhar() |
|
| 51 | + { |
|
| 52 | + return $this->phar; |
|
| 53 | + } |
|
| 54 | + |
|
| 55 | + /** |
|
| 56 | + * Add the SSPak executable information into this SSPak file |
|
| 57 | + */ |
|
| 58 | + public function makeExecutable() |
|
| 59 | + { |
|
| 60 | + if (ini_get('phar.readonly')) { |
|
| 61 | + throw new Exception("Please set phar.readonly to false in your php.ini."); |
|
| 62 | + } |
|
| 63 | + |
|
| 64 | + passthru("composer install -d " . escapeshellarg(PACKAGE_ROOT) . " --no-dev"); |
|
| 65 | + |
|
| 66 | + $root = PACKAGE_ROOT; |
|
| 67 | + $srcRoots = [ |
|
| 68 | + 'src/', |
|
| 69 | + 'vendor/', |
|
| 70 | + ]; |
|
| 71 | + |
|
| 72 | + // Add the bin file, but strip of the #! exec header. |
|
| 73 | + $this->phar['bin/sspak'] = preg_replace( |
|
| 74 | + "/^#!\/usr\/bin\/env php\n/", |
|
| 75 | + '', |
|
| 76 | + file_get_contents($root . "bin/sspak") |
|
| 77 | + ); |
|
| 78 | + |
|
| 79 | + foreach ($srcRoots as $srcRoot) { |
|
| 80 | + foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($root . $srcRoot)) as $fileObj) { |
|
| 81 | + if ($fileObj->isFile()) { |
|
| 82 | + $file = $fileObj->getRealPath(); |
|
| 83 | + |
|
| 84 | + $relativeFile = str_replace($root, '', $file); |
|
| 85 | + |
|
| 86 | + echo "Adding $relativeFile\n"; |
|
| 87 | + $this->phar[$relativeFile] = file_get_contents($file); |
|
| 88 | + } |
|
| 89 | + } |
|
| 90 | + } |
|
| 91 | + |
|
| 92 | + $stub = <<<STUB |
|
| 93 | 93 | #!/usr/bin/env php |
| 94 | 94 | <?php |
| 95 | 95 | define('PACKAGE_ROOT', 'phar://$this->pharAlias/'); |
@@ -98,106 +98,106 @@ discard block |
||
| 98 | 98 | __HALT_COMPILER(); |
| 99 | 99 | STUB; |
| 100 | 100 | |
| 101 | - $this->phar->setStub($stub); |
|
| 102 | - chmod($this->path, 0775); |
|
| 103 | - |
|
| 104 | - passthru("composer install -d " . escapeshellarg(PACKAGE_ROOT)); |
|
| 105 | - } |
|
| 106 | - |
|
| 107 | - /** |
|
| 108 | - * Returns true if this sspak file contains the given file. |
|
| 109 | - * @param string $file The filename to look for |
|
| 110 | - * @return boolean |
|
| 111 | - */ |
|
| 112 | - public function contains($file) |
|
| 113 | - { |
|
| 114 | - return $this->phar->offsetExists($file); |
|
| 115 | - } |
|
| 116 | - |
|
| 117 | - /** |
|
| 118 | - * Returns the content of a file from this sspak |
|
| 119 | - */ |
|
| 120 | - public function content($file) |
|
| 121 | - { |
|
| 122 | - return file_get_contents($this->phar[$file]); |
|
| 123 | - } |
|
| 124 | - |
|
| 125 | - /** |
|
| 126 | - * Pipe the output of the given process into a file within this SSPak |
|
| 127 | - * @param string $filename The file to create within the SSPak |
|
| 128 | - * @param Process $process The process to execute and take the output from |
|
| 129 | - * @return null |
|
| 130 | - */ |
|
| 131 | - public function writeFileFromProcess($filename, Process $process) |
|
| 132 | - { |
|
| 133 | - // Non-executable Phars can't have content streamed into them |
|
| 134 | - // This means that we need to create a temp file, which is a pain, if that file happens to be a 3GB |
|
| 135 | - // asset dump. :-/ |
|
| 136 | - if ($this->phar instanceof PharData) { |
|
| 137 | - $tmpFile = '/tmp/sspak-content-' .rand(100000, 999999); |
|
| 138 | - $process->exec(array('outputFile' => $tmpFile)); |
|
| 139 | - $this->phar->addFile($tmpFile, $filename); |
|
| 140 | - unlink($tmpFile); |
|
| 141 | - |
|
| 142 | - // So, where we *can* use write streams, we do so. |
|
| 143 | - } else { |
|
| 144 | - $stream = $this->writeStreamForFile($filename); |
|
| 145 | - $process->exec(array('outputStream' => $stream)); |
|
| 146 | - fclose($stream); |
|
| 147 | - } |
|
| 148 | - } |
|
| 149 | - |
|
| 150 | - /** |
|
| 151 | - * Return a writeable stream corresponding to the given file within the .sspak |
|
| 152 | - * @param string $filename The name of the file within the .sspak |
|
| 153 | - * @return Stream context |
|
| 154 | - */ |
|
| 155 | - public function writeStreamForFile($filename) |
|
| 156 | - { |
|
| 157 | - return fopen('phar://' . $this->pharAlias . '/' . $filename, 'w'); |
|
| 158 | - } |
|
| 159 | - |
|
| 160 | - /** |
|
| 161 | - * Return a readable stream corresponding to the given file within the .sspak |
|
| 162 | - * @param string $filename The name of the file within the .sspak |
|
| 163 | - * @return Stream context |
|
| 164 | - */ |
|
| 165 | - public function readStreamForFile($filename) |
|
| 166 | - { |
|
| 167 | - // Note: using pharAlias here doesn't work on Debian Wheezy (nor on Windows for that matter). |
|
| 168 | - //return fopen('phar://' . $this->pharAlias . '/' . $filename, 'r'); |
|
| 169 | - return fopen('phar://' . $this->pharPath . '/' . $filename, 'r'); |
|
| 170 | - } |
|
| 171 | - |
|
| 172 | - /** |
|
| 173 | - * Create a file in the .sspak with the given content |
|
| 174 | - * @param string $filename The name of the file within the .sspak |
|
| 175 | - * @param string $content The content of the file |
|
| 176 | - * @return null |
|
| 177 | - */ |
|
| 178 | - public function writeFile($filename, $content) |
|
| 179 | - { |
|
| 180 | - $this->phar[$filename] = $content; |
|
| 181 | - } |
|
| 182 | - |
|
| 183 | - /** |
|
| 184 | - * Extracts the git remote details and reutrns them as a map |
|
| 185 | - */ |
|
| 186 | - public function gitRemoteDetails() |
|
| 187 | - { |
|
| 188 | - $content = $this->content('git-remote'); |
|
| 189 | - $details = array(); |
|
| 190 | - foreach (explode("\n", trim($content)) as $line) { |
|
| 191 | - if (!$line) { |
|
| 192 | - continue; |
|
| 193 | - } |
|
| 194 | - |
|
| 195 | - if (preg_match('/^([^ ]+) *= *(.*)$/', $line, $matches)) { |
|
| 196 | - $details[$matches[1]] = $matches[2]; |
|
| 197 | - } else { |
|
| 198 | - throw new Exception("Bad line '$line'"); |
|
| 199 | - } |
|
| 200 | - } |
|
| 201 | - return $details; |
|
| 202 | - } |
|
| 101 | + $this->phar->setStub($stub); |
|
| 102 | + chmod($this->path, 0775); |
|
| 103 | + |
|
| 104 | + passthru("composer install -d " . escapeshellarg(PACKAGE_ROOT)); |
|
| 105 | + } |
|
| 106 | + |
|
| 107 | + /** |
|
| 108 | + * Returns true if this sspak file contains the given file. |
|
| 109 | + * @param string $file The filename to look for |
|
| 110 | + * @return boolean |
|
| 111 | + */ |
|
| 112 | + public function contains($file) |
|
| 113 | + { |
|
| 114 | + return $this->phar->offsetExists($file); |
|
| 115 | + } |
|
| 116 | + |
|
| 117 | + /** |
|
| 118 | + * Returns the content of a file from this sspak |
|
| 119 | + */ |
|
| 120 | + public function content($file) |
|
| 121 | + { |
|
| 122 | + return file_get_contents($this->phar[$file]); |
|
| 123 | + } |
|
| 124 | + |
|
| 125 | + /** |
|
| 126 | + * Pipe the output of the given process into a file within this SSPak |
|
| 127 | + * @param string $filename The file to create within the SSPak |
|
| 128 | + * @param Process $process The process to execute and take the output from |
|
| 129 | + * @return null |
|
| 130 | + */ |
|
| 131 | + public function writeFileFromProcess($filename, Process $process) |
|
| 132 | + { |
|
| 133 | + // Non-executable Phars can't have content streamed into them |
|
| 134 | + // This means that we need to create a temp file, which is a pain, if that file happens to be a 3GB |
|
| 135 | + // asset dump. :-/ |
|
| 136 | + if ($this->phar instanceof PharData) { |
|
| 137 | + $tmpFile = '/tmp/sspak-content-' .rand(100000, 999999); |
|
| 138 | + $process->exec(array('outputFile' => $tmpFile)); |
|
| 139 | + $this->phar->addFile($tmpFile, $filename); |
|
| 140 | + unlink($tmpFile); |
|
| 141 | + |
|
| 142 | + // So, where we *can* use write streams, we do so. |
|
| 143 | + } else { |
|
| 144 | + $stream = $this->writeStreamForFile($filename); |
|
| 145 | + $process->exec(array('outputStream' => $stream)); |
|
| 146 | + fclose($stream); |
|
| 147 | + } |
|
| 148 | + } |
|
| 149 | + |
|
| 150 | + /** |
|
| 151 | + * Return a writeable stream corresponding to the given file within the .sspak |
|
| 152 | + * @param string $filename The name of the file within the .sspak |
|
| 153 | + * @return Stream context |
|
| 154 | + */ |
|
| 155 | + public function writeStreamForFile($filename) |
|
| 156 | + { |
|
| 157 | + return fopen('phar://' . $this->pharAlias . '/' . $filename, 'w'); |
|
| 158 | + } |
|
| 159 | + |
|
| 160 | + /** |
|
| 161 | + * Return a readable stream corresponding to the given file within the .sspak |
|
| 162 | + * @param string $filename The name of the file within the .sspak |
|
| 163 | + * @return Stream context |
|
| 164 | + */ |
|
| 165 | + public function readStreamForFile($filename) |
|
| 166 | + { |
|
| 167 | + // Note: using pharAlias here doesn't work on Debian Wheezy (nor on Windows for that matter). |
|
| 168 | + //return fopen('phar://' . $this->pharAlias . '/' . $filename, 'r'); |
|
| 169 | + return fopen('phar://' . $this->pharPath . '/' . $filename, 'r'); |
|
| 170 | + } |
|
| 171 | + |
|
| 172 | + /** |
|
| 173 | + * Create a file in the .sspak with the given content |
|
| 174 | + * @param string $filename The name of the file within the .sspak |
|
| 175 | + * @param string $content The content of the file |
|
| 176 | + * @return null |
|
| 177 | + */ |
|
| 178 | + public function writeFile($filename, $content) |
|
| 179 | + { |
|
| 180 | + $this->phar[$filename] = $content; |
|
| 181 | + } |
|
| 182 | + |
|
| 183 | + /** |
|
| 184 | + * Extracts the git remote details and reutrns them as a map |
|
| 185 | + */ |
|
| 186 | + public function gitRemoteDetails() |
|
| 187 | + { |
|
| 188 | + $content = $this->content('git-remote'); |
|
| 189 | + $details = array(); |
|
| 190 | + foreach (explode("\n", trim($content)) as $line) { |
|
| 191 | + if (!$line) { |
|
| 192 | + continue; |
|
| 193 | + } |
|
| 194 | + |
|
| 195 | + if (preg_match('/^([^ ]+) *= *(.*)$/', $line, $matches)) { |
|
| 196 | + $details[$matches[1]] = $matches[2]; |
|
| 197 | + } else { |
|
| 198 | + throw new Exception("Bad line '$line'"); |
|
| 199 | + } |
|
| 200 | + } |
|
| 201 | + return $details; |
|
| 202 | + } |
|
| 203 | 203 | } |
@@ -61,7 +61,7 @@ discard block |
||
| 61 | 61 | throw new Exception("Please set phar.readonly to false in your php.ini."); |
| 62 | 62 | } |
| 63 | 63 | |
| 64 | - passthru("composer install -d " . escapeshellarg(PACKAGE_ROOT) . " --no-dev"); |
|
| 64 | + passthru("composer install -d ".escapeshellarg(PACKAGE_ROOT)." --no-dev"); |
|
| 65 | 65 | |
| 66 | 66 | $root = PACKAGE_ROOT; |
| 67 | 67 | $srcRoots = [ |
@@ -73,11 +73,11 @@ discard block |
||
| 73 | 73 | $this->phar['bin/sspak'] = preg_replace( |
| 74 | 74 | "/^#!\/usr\/bin\/env php\n/", |
| 75 | 75 | '', |
| 76 | - file_get_contents($root . "bin/sspak") |
|
| 76 | + file_get_contents($root."bin/sspak") |
|
| 77 | 77 | ); |
| 78 | 78 | |
| 79 | 79 | foreach ($srcRoots as $srcRoot) { |
| 80 | - foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($root . $srcRoot)) as $fileObj) { |
|
| 80 | + foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($root.$srcRoot)) as $fileObj) { |
|
| 81 | 81 | if ($fileObj->isFile()) { |
| 82 | 82 | $file = $fileObj->getRealPath(); |
| 83 | 83 | |
@@ -101,7 +101,7 @@ discard block |
||
| 101 | 101 | $this->phar->setStub($stub); |
| 102 | 102 | chmod($this->path, 0775); |
| 103 | 103 | |
| 104 | - passthru("composer install -d " . escapeshellarg(PACKAGE_ROOT)); |
|
| 104 | + passthru("composer install -d ".escapeshellarg(PACKAGE_ROOT)); |
|
| 105 | 105 | } |
| 106 | 106 | |
| 107 | 107 | /** |
@@ -134,7 +134,7 @@ discard block |
||
| 134 | 134 | // This means that we need to create a temp file, which is a pain, if that file happens to be a 3GB |
| 135 | 135 | // asset dump. :-/ |
| 136 | 136 | if ($this->phar instanceof PharData) { |
| 137 | - $tmpFile = '/tmp/sspak-content-' .rand(100000, 999999); |
|
| 137 | + $tmpFile = '/tmp/sspak-content-'.rand(100000, 999999); |
|
| 138 | 138 | $process->exec(array('outputFile' => $tmpFile)); |
| 139 | 139 | $this->phar->addFile($tmpFile, $filename); |
| 140 | 140 | unlink($tmpFile); |
@@ -154,7 +154,7 @@ discard block |
||
| 154 | 154 | */ |
| 155 | 155 | public function writeStreamForFile($filename) |
| 156 | 156 | { |
| 157 | - return fopen('phar://' . $this->pharAlias . '/' . $filename, 'w'); |
|
| 157 | + return fopen('phar://'.$this->pharAlias.'/'.$filename, 'w'); |
|
| 158 | 158 | } |
| 159 | 159 | |
| 160 | 160 | /** |
@@ -166,7 +166,7 @@ discard block |
||
| 166 | 166 | { |
| 167 | 167 | // Note: using pharAlias here doesn't work on Debian Wheezy (nor on Windows for that matter). |
| 168 | 168 | //return fopen('phar://' . $this->pharAlias . '/' . $filename, 'r'); |
| 169 | - return fopen('phar://' . $this->pharPath . '/' . $filename, 'r'); |
|
| 169 | + return fopen('phar://'.$this->pharPath.'/'.$filename, 'r'); |
|
| 170 | 170 | } |
| 171 | 171 | |
| 172 | 172 | /** |
@@ -9,63 +9,63 @@ |
||
| 9 | 9 | */ |
| 10 | 10 | class Executor |
| 11 | 11 | { |
| 12 | - protected $defaultOptions = array( |
|
| 13 | - 'throwException' => true, |
|
| 14 | - 'inputContent' => null, |
|
| 15 | - 'inputFile' => null, |
|
| 16 | - 'inputStream' => null, |
|
| 17 | - 'outputFile' => null, |
|
| 18 | - 'outputFileAppend' => false, |
|
| 19 | - 'outputStream' => null, |
|
| 20 | - ); |
|
| 12 | + protected $defaultOptions = array( |
|
| 13 | + 'throwException' => true, |
|
| 14 | + 'inputContent' => null, |
|
| 15 | + 'inputFile' => null, |
|
| 16 | + 'inputStream' => null, |
|
| 17 | + 'outputFile' => null, |
|
| 18 | + 'outputFileAppend' => false, |
|
| 19 | + 'outputStream' => null, |
|
| 20 | + ); |
|
| 21 | 21 | |
| 22 | - /** |
|
| 23 | - * @param string $command The command |
|
| 24 | - * @param boolean $throwException If true, an Exception will be thrown on a nonzero error code |
|
| 25 | - * @param boolean $returnOutput If true, output will be captured |
|
| 26 | - * @param boolean $inputContent Content for STDIN. Otherwise the parent script's STDIN is used |
|
| 27 | - * @return A map containing 'return', 'output', and 'error' |
|
| 28 | - */ |
|
| 29 | - public function execLocal($command, $options = array()) |
|
| 30 | - { |
|
| 31 | - $process = $this->createLocal($command, $options); |
|
| 32 | - return $process->exec(); |
|
| 33 | - } |
|
| 22 | + /** |
|
| 23 | + * @param string $command The command |
|
| 24 | + * @param boolean $throwException If true, an Exception will be thrown on a nonzero error code |
|
| 25 | + * @param boolean $returnOutput If true, output will be captured |
|
| 26 | + * @param boolean $inputContent Content for STDIN. Otherwise the parent script's STDIN is used |
|
| 27 | + * @return A map containing 'return', 'output', and 'error' |
|
| 28 | + */ |
|
| 29 | + public function execLocal($command, $options = array()) |
|
| 30 | + { |
|
| 31 | + $process = $this->createLocal($command, $options); |
|
| 32 | + return $process->exec(); |
|
| 33 | + } |
|
| 34 | 34 | |
| 35 | - public function execRemote($command, $options = array()) |
|
| 36 | - { |
|
| 37 | - $process = $this->createRemote($command, $options); |
|
| 38 | - return $process->exec(); |
|
| 39 | - } |
|
| 35 | + public function execRemote($command, $options = array()) |
|
| 36 | + { |
|
| 37 | + $process = $this->createRemote($command, $options); |
|
| 38 | + return $process->exec(); |
|
| 39 | + } |
|
| 40 | 40 | |
| 41 | - public function createLocal($command, $options) |
|
| 42 | - { |
|
| 43 | - $options = array_merge($this->defaultOptions, $options); |
|
| 44 | - if (is_array($command)) { |
|
| 45 | - $command = $this->commandArrayToString($command); |
|
| 46 | - } |
|
| 41 | + public function createLocal($command, $options) |
|
| 42 | + { |
|
| 43 | + $options = array_merge($this->defaultOptions, $options); |
|
| 44 | + if (is_array($command)) { |
|
| 45 | + $command = $this->commandArrayToString($command); |
|
| 46 | + } |
|
| 47 | 47 | |
| 48 | - return new Process($command, $options); |
|
| 49 | - } |
|
| 48 | + return new Process($command, $options); |
|
| 49 | + } |
|
| 50 | 50 | |
| 51 | - public function createRemote($server, $command, $options = array()) |
|
| 52 | - { |
|
| 53 | - $process = $this->createLocal($command, $options); |
|
| 54 | - $process->setRemoteServer($server); |
|
| 55 | - return $process; |
|
| 56 | - } |
|
| 51 | + public function createRemote($server, $command, $options = array()) |
|
| 52 | + { |
|
| 53 | + $process = $this->createLocal($command, $options); |
|
| 54 | + $process->setRemoteServer($server); |
|
| 55 | + return $process; |
|
| 56 | + } |
|
| 57 | 57 | |
| 58 | - /** |
|
| 59 | - * Turn an array command in a string, escaping and concatenating each item |
|
| 60 | - * @param array $command Command array. First element is the command and all remaining are the arguments. |
|
| 61 | - * @return string String command |
|
| 62 | - */ |
|
| 63 | - public function commandArrayToString($command) |
|
| 64 | - { |
|
| 65 | - $string = escapeshellcmd(array_shift($command)); |
|
| 66 | - foreach ($command as $arg) { |
|
| 67 | - $string .= ' ' . escapeshellarg($arg); |
|
| 68 | - } |
|
| 69 | - return $string; |
|
| 70 | - } |
|
| 58 | + /** |
|
| 59 | + * Turn an array command in a string, escaping and concatenating each item |
|
| 60 | + * @param array $command Command array. First element is the command and all remaining are the arguments. |
|
| 61 | + * @return string String command |
|
| 62 | + */ |
|
| 63 | + public function commandArrayToString($command) |
|
| 64 | + { |
|
| 65 | + $string = escapeshellcmd(array_shift($command)); |
|
| 66 | + foreach ($command as $arg) { |
|
| 67 | + $string .= ' ' . escapeshellarg($arg); |
|
| 68 | + } |
|
| 69 | + return $string; |
|
| 70 | + } |
|
| 71 | 71 | } |
@@ -64,7 +64,7 @@ |
||
| 64 | 64 | { |
| 65 | 65 | $string = escapeshellcmd(array_shift($command)); |
| 66 | 66 | foreach ($command as $arg) { |
| 67 | - $string .= ' ' . escapeshellarg($arg); |
|
| 67 | + $string .= ' '.escapeshellarg($arg); |
|
| 68 | 68 | } |
| 69 | 69 | return $string; |
| 70 | 70 | } |
@@ -8,48 +8,48 @@ |
||
| 8 | 8 | |
| 9 | 9 | // Argument parsing |
| 10 | 10 | if (empty($_SERVER['argv'][1])) { |
| 11 | - echo "Usage: {$_SERVER['argv'][0]} (site-docroot)\n"; |
|
| 12 | - exit(1); |
|
| 11 | + echo "Usage: {$_SERVER['argv'][0]} (site-docroot)\n"; |
|
| 12 | + exit(1); |
|
| 13 | 13 | } |
| 14 | 14 | |
| 15 | 15 | $basePath = $_SERVER['argv'][1]; |
| 16 | 16 | if ($basePath[0] != '/') { |
| 17 | - $basePath = getcwd() . '/' . $basePath; |
|
| 17 | + $basePath = getcwd() . '/' . $basePath; |
|
| 18 | 18 | } |
| 19 | 19 | |
| 20 | 20 | // SilverStripe bootstrap |
| 21 | 21 | define('BASE_PATH', realpath($basePath)); |
| 22 | 22 | if (!defined('BASE_URL')) { |
| 23 | - define('BASE_URL', '/'); |
|
| 23 | + define('BASE_URL', '/'); |
|
| 24 | 24 | } |
| 25 | 25 | $_SERVER['HTTP_HOST'] = 'localhost'; |
| 26 | 26 | chdir(BASE_PATH); |
| 27 | 27 | |
| 28 | 28 | if (file_exists(BASE_PATH.'/sapphire/core/Core.php')) { |
| 29 | - //SS 2.x |
|
| 30 | - require_once(BASE_PATH . '/sapphire/core/Core.php'); |
|
| 29 | + //SS 2.x |
|
| 30 | + require_once(BASE_PATH . '/sapphire/core/Core.php'); |
|
| 31 | 31 | } elseif (file_exists(BASE_PATH.'/framework/core/Core.php')) { |
| 32 | - //SS 3.x |
|
| 33 | - require_once(BASE_PATH. '/framework/core/Core.php'); |
|
| 32 | + //SS 3.x |
|
| 33 | + require_once(BASE_PATH. '/framework/core/Core.php'); |
|
| 34 | 34 | } elseif (file_exists(BASE_PATH.'/vendor/silverstripe/framework')) { |
| 35 | - //SS 4.x |
|
| 36 | - require_once(BASE_PATH. '/vendor/autoload.php'); |
|
| 37 | - $kernel = new SilverStripe\Core\CoreKernel(BASE_PATH); |
|
| 38 | - //boot the parts of the kernel to populate the DB config |
|
| 39 | - foreach (array('bootDatabaseEnvVars', 'bootDatabaseGlobals') as $bootMethod) { |
|
| 40 | - $reflectedBootMethod = new ReflectionMethod($kernel, $bootMethod); |
|
| 41 | - $reflectedBootMethod->setAccessible(true); |
|
| 42 | - $reflectedBootMethod->invoke($kernel); |
|
| 43 | - } |
|
| 44 | - $databaseConfig = SilverStripe\ORM\DB::getConfig(); |
|
| 35 | + //SS 4.x |
|
| 36 | + require_once(BASE_PATH. '/vendor/autoload.php'); |
|
| 37 | + $kernel = new SilverStripe\Core\CoreKernel(BASE_PATH); |
|
| 38 | + //boot the parts of the kernel to populate the DB config |
|
| 39 | + foreach (array('bootDatabaseEnvVars', 'bootDatabaseGlobals') as $bootMethod) { |
|
| 40 | + $reflectedBootMethod = new ReflectionMethod($kernel, $bootMethod); |
|
| 41 | + $reflectedBootMethod->setAccessible(true); |
|
| 42 | + $reflectedBootMethod->invoke($kernel); |
|
| 43 | + } |
|
| 44 | + $databaseConfig = SilverStripe\ORM\DB::getConfig(); |
|
| 45 | 45 | } else { |
| 46 | - echo "Couldn't locate framework's Core.php. Perhaps " . BASE_PATH . " is not a SilverStripe project?\n"; |
|
| 47 | - exit(2); |
|
| 46 | + echo "Couldn't locate framework's Core.php. Perhaps " . BASE_PATH . " is not a SilverStripe project?\n"; |
|
| 47 | + exit(2); |
|
| 48 | 48 | } |
| 49 | 49 | |
| 50 | 50 | $output = array(); |
| 51 | 51 | foreach ($databaseConfig as $k => $v) { |
| 52 | - $output['db_' . $k] = $v; |
|
| 52 | + $output['db_' . $k] = $v; |
|
| 53 | 53 | } |
| 54 | 54 | $output['assets_path'] = ASSETS_PATH; |
| 55 | 55 | |
@@ -14,7 +14,7 @@ discard block |
||
| 14 | 14 | |
| 15 | 15 | $basePath = $_SERVER['argv'][1]; |
| 16 | 16 | if ($basePath[0] != '/') { |
| 17 | - $basePath = getcwd() . '/' . $basePath; |
|
| 17 | + $basePath = getcwd().'/'.$basePath; |
|
| 18 | 18 | } |
| 19 | 19 | |
| 20 | 20 | // SilverStripe bootstrap |
@@ -27,13 +27,13 @@ discard block |
||
| 27 | 27 | |
| 28 | 28 | if (file_exists(BASE_PATH.'/sapphire/core/Core.php')) { |
| 29 | 29 | //SS 2.x |
| 30 | - require_once(BASE_PATH . '/sapphire/core/Core.php'); |
|
| 30 | + require_once(BASE_PATH.'/sapphire/core/Core.php'); |
|
| 31 | 31 | } elseif (file_exists(BASE_PATH.'/framework/core/Core.php')) { |
| 32 | 32 | //SS 3.x |
| 33 | - require_once(BASE_PATH. '/framework/core/Core.php'); |
|
| 33 | + require_once(BASE_PATH.'/framework/core/Core.php'); |
|
| 34 | 34 | } elseif (file_exists(BASE_PATH.'/vendor/silverstripe/framework')) { |
| 35 | 35 | //SS 4.x |
| 36 | - require_once(BASE_PATH. '/vendor/autoload.php'); |
|
| 36 | + require_once(BASE_PATH.'/vendor/autoload.php'); |
|
| 37 | 37 | $kernel = new SilverStripe\Core\CoreKernel(BASE_PATH); |
| 38 | 38 | //boot the parts of the kernel to populate the DB config |
| 39 | 39 | foreach (array('bootDatabaseEnvVars', 'bootDatabaseGlobals') as $bootMethod) { |
@@ -43,13 +43,13 @@ discard block |
||
| 43 | 43 | } |
| 44 | 44 | $databaseConfig = SilverStripe\ORM\DB::getConfig(); |
| 45 | 45 | } else { |
| 46 | - echo "Couldn't locate framework's Core.php. Perhaps " . BASE_PATH . " is not a SilverStripe project?\n"; |
|
| 46 | + echo "Couldn't locate framework's Core.php. Perhaps ".BASE_PATH." is not a SilverStripe project?\n"; |
|
| 47 | 47 | exit(2); |
| 48 | 48 | } |
| 49 | 49 | |
| 50 | 50 | $output = array(); |
| 51 | 51 | foreach ($databaseConfig as $k => $v) { |
| 52 | - $output['db_' . $k] = $v; |
|
| 52 | + $output['db_'.$k] = $v; |
|
| 53 | 53 | } |
| 54 | 54 | $output['assets_path'] = ASSETS_PATH; |
| 55 | 55 | |