@@ -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 |