Completed
Push — master ( 63676d...3faef6 )
by Lukas
28:10 queued 12:28
created

GenerateCommand::generateMigration()   B

Complexity

Conditions 3
Paths 4

Size

Total Lines 28
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 18
nc 4
nop 3
dl 0
loc 28
rs 8.8571
c 0
b 0
f 0
1
<?php
2
/**
3
 * @author Joas Schilling <[email protected]>
4
 * @author Thomas Müller <[email protected]>
5
 *
6
 * @copyright Copyright (c) 2017 Joas Schilling <[email protected]>
7
 * @copyright Copyright (c) 2017, ownCloud GmbH
8
 *
9
 * @license AGPL-3.0
10
 *
11
 * This code is free software: you can redistribute it and/or modify
12
 * it under the terms of the GNU Affero General Public License, version 3,
13
 * as published by the Free Software Foundation.
14
 *
15
 * This program is distributed in the hope that it will be useful,
16
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18
 * GNU Affero General Public License for more details.
19
 *
20
 * You should have received a copy of the GNU Affero General Public License, version 3,
21
 * along with this program.  If not, see <http://www.gnu.org/licenses/>
22
 *
23
 */
24
25
namespace OC\Core\Command\Db\Migrations;
26
27
28
use OC\DB\MigrationService;
29
use OC\Migration\ConsoleOutput;
30
use OCP\IDBConnection;
31
use Symfony\Component\Console\Command\Command;
32
use Symfony\Component\Console\Exception\RuntimeException;
33
use Symfony\Component\Console\Input\InputArgument;
34
use Symfony\Component\Console\Input\InputInterface;
35
use Symfony\Component\Console\Output\OutputInterface;
36
37
class GenerateCommand extends Command {
38
39
	protected static $_templateSimple =
40
		'<?php
41
namespace {{<namespace}};
42
43
use Doctrine\DBAL\Schema\Schema;
44
use OCP\Migration\SimpleMigrationStep;
45
use OCP\Migration\IOutput;
46
47
/**
48
 * Auto-generated migration step: Please modify to your needs!
49
 */
50
class {{classname}} extends SimpleMigrationStep {
51
52
	/**
53
	 * @param IOutput $output
54
	 * @param \Closure $schemaClosure The `\Closure` returns a `Schema`
55
	 * @param array $options
56
	 * @since 13.0.0
57
	 */
58
	public function preSchemaChange(IOutput $output, \Closure $schemaClosure, array $options) {
59
	}
60
61
	/**
62
	 * @param IOutput $output
63
	 * @param \Closure $schemaClosure The `\Closure` returns a `Schema`
64
	 * @param array $options
65
	 * @return null|Schema
66
	 * @since 13.0.0
67
	 */
68
	public function changeSchema(IOutput $output, \Closure $schemaClosure, array $options) {
69
{{schemabody}}
70
	}
71
72
	/**
73
	 * @param IOutput $output
74
	 * @param \Closure $schemaClosure The `\Closure` returns a `Schema`
75
	 * @param array $options
76
	 * @since 13.0.0
77
	 */
78
	public function postSchemaChange(IOutput $output, \Closure $schemaClosure, array $options) {
79
	}
80
}
81
';
82
83
	/** @var IDBConnection */
84
	protected $connection;
85
86
	/**
87
	 * @param IDBConnection $connection
88
	 */
89
	public function __construct(IDBConnection $connection) {
90
		$this->connection = $connection;
91
92
		parent::__construct();
93
	}
94
95
	protected function configure() {
96
		$this
97
			->setName('migrations:generate')
98
			->addArgument('app', InputArgument::REQUIRED, 'Name of the app this migration command shall work on')
99
			->addArgument('version', InputArgument::REQUIRED, 'Major version of this app, to allow versions on parallel development branches')
100
		;
101
102
		parent::configure();
103
	}
104
105
	public function execute(InputInterface $input, OutputInterface $output) {
106
		$appName = $input->getArgument('app');
107
		$version = $input->getArgument('version');
108
109
		if (!preg_match('/^\d{1,16}$/',$version)) {
110
			$output->writeln('<error>The given version is invalid. Only 0-9 are allowed (max. 16 digits)</error>');
111
			return 1;
112
		}
113
114
		$ms = new MigrationService($appName, $this->connection, new ConsoleOutput($output));
115
116
		$date = date('YmdHis');
117
		$path = $this->generateMigration($ms, 'Version' . $version . 'Date' . $date);
118
119
		$output->writeln("New migration class has been generated to <info>$path</info>");
120
		return 0;
121
	}
122
123
	/**
124
	 * @param MigrationService $ms
125
	 * @param string $className
126
	 * @param string $schemaBody
127
	 * @return string
128
	 */
129
	protected function generateMigration(MigrationService $ms, $className, $schemaBody = '') {
130
		if ($schemaBody === '') {
131
			$schemaBody = "\t\t" . 'return null;';
132
		}
133
134
135
		$placeHolders = [
136
			'{{namespace}}',
137
			'{{classname}}',
138
			'{{schemabody}}',
139
		];
140
		$replacements = [
141
			$ms->getMigrationsNamespace(),
142
			$className,
143
			$schemaBody,
144
		];
145
		$code = str_replace($placeHolders, $replacements, self::$_templateSimple);
146
		$dir = $ms->getMigrationsDirectory();
147
148
		$this->ensureMigrationDirExists($dir);
149
		$path = $dir . '/' . $className . '.php';
150
151
		if (file_put_contents($path, $code) === false) {
152
			throw new RuntimeException('Failed to generate new migration step.');
153
		}
154
155
		return $path;
156
	}
157
158
	protected function ensureMigrationDirExists($directory) {
159
		if (file_exists($directory) && is_dir($directory)) {
160
			return;
161
		}
162
163
		if (file_exists($directory)) {
164
			throw new \RuntimeException("Could not create folder \"$directory\"");
165
		}
166
167
		$this->ensureMigrationDirExists(dirname($directory));
168
169
		if (!@mkdir($directory) && !is_dir($directory)) {
170
			throw new \RuntimeException("Could not create folder \"$directory\"");
171
		}
172
	}
173
}
174