Completed
Branch bootstrap-refactoring (b06695)
by Adam
03:28
created

Bootstrap::resolveBootstrap()   B

Complexity

Conditions 5
Paths 4

Size

Total Lines 17
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 13
CRAP Score 5.009

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 17
ccs 13
cts 14
cp 0.9286
rs 8.8571
cc 5
eloc 13
nc 4
nop 0
crap 5.009
1
<?php
2
3
4
namespace Genesis;
5
6
7
use Genesis\Config\Container;
8
use Genesis\Config\ContainerFactory;
9
10
/**
11
 * @author Adam Bisek <[email protected]>
12
 */
13
class Bootstrap
14
{
15
16
	const DEFAULT_CONFIG_FILE = 'config.neon';
17
18
	/** @var BuildFactory */
19
	private $buildFactory;
20
21
	/** @var string */
22
	private $workingDir;
23
24
25
	/**
26
	 * @return BuildFactory
27
	 */
28
	public function getBuildFactory()
29
	{
30
		return $this->buildFactory;
31
	}
32
33
34
	/**
35
	 * @param BuildFactory $buildFactory
36
	 */
37 14
	public function setBuildFactory($buildFactory)
38
	{
39 14
		$this->buildFactory = $buildFactory;
40 14
	}
41
42
43
	/**
44
	 * @param InputArgs $inputArgs
45
	 * @throws TerminateException
46
	 */
47 14
	public function run(InputArgs $inputArgs)
48
	{
49 14
		$this->startup($inputArgs);
50 13
		$arguments = $inputArgs->getArguments();
51 13
		if (isset($arguments[0]) && $arguments[0] === 'self-init') {
52 1
			$directoryName = isset($arguments[1]) ? $arguments[1] : 'build';
53 1
			$selfInit = new Commands\SelfInit();
54 1
			$selfInit->setDistDirectory(__DIR__ . '/build-dist');
55 1
			$selfInit->setWorkingDirectory($this->workingDir);
56 1
			$selfInit->setDirname($directoryName);
57 1
			$selfInit->execute();
58 1
			$this->terminate(0);
59
		}
60 12
		$container = $this->resolveBootstrap();
61 11
		$configFile = $inputArgs->getOption('config') ? $inputArgs->getOption('config') : self::DEFAULT_CONFIG_FILE;
62
		try {
63 11
			$container = $this->createContainer($configFile, $container);
64 11
			$build = $this->createBuild($container, $arguments);
65 11
		} catch (\Throwable $e) { // fault barrier -> catch all
66
			$this->handleException($e);
67 2
		} catch (\Exception $e) { // fault barrier -> catch all, PHP 5.x compatibility
68 2
			$this->handleException($e);
69
		}
70 9
		if (count($arguments) < 1) {
71 2
			$this->log("Running default", 'green');
72 2
			$build->runDefault();
73 2
			$this->terminate(0);
74
		}
75
76 7
		$method = 'run' . str_replace('-', '', ucfirst($arguments[0]));
77 7
		if (!method_exists($build, $method)) {
78 1
			$this->log("Task '$arguments[0]' does not exists.", 'red');
79 1
			$this->terminate(255);
80
		}
81 6
		$this->log("Running [$arguments[0]]", 'green');
82
		try {
83 6
			$build->$method();
84 7
		} catch (\Throwable $e) { // fault barrier -> catch all
85 1
			$this->handleException($e);
86 1
		} catch (\Exception $e) { // fault barrier -> catch all, PHP 5.x compatibility
87 1
			$this->handleException($e);
88
		}
89 5
		$this->log("Exited with SUCCESS", 'black', 'green');
90 5
		echo PHP_EOL;
91 5
		$this->terminate(0);
92
	}
93
94
95 14
	private function terminate($code)
96
	{
97 14
		throw new TerminateException(NULL, $code);
98 1
	}
99
100
101 14
	private function startup(InputArgs $inputArgs)
102
	{
103 14
		$this->workingDir = getcwd();
104 14
		if ($inputArgs->getOption('colors') !== NULL && !$inputArgs->getOption('colors')) {
105 14
			Cli::$enableColors = FALSE;
106 14
		}
107 14
		if ($inputArgs->getOption('working-dir')) {
108 14
			$this->workingDir = realpath($inputArgs->getOption('working-dir'));
109 14
			if (!$this->workingDir) {
110 1
				$this->log(sprintf("Working dir '%s' does not exists.", $inputArgs->getOption('working-dir')), 'red');
111 1
				$this->terminate(255);
112
			}
113 14
		}
114 14
		if ($this->workingDir === __DIR__) {
115 1
			$this->log(sprintf("Working dir '%s' is directory with Genesis. You have to choose directory with build.", $this->workingDir), 'red');
116 1
			$this->terminate(255);
117
		}
118 13
	}
119
120
121
	/**
122
	 * @return Container|NULL
123
	 */
124 12
	private function resolveBootstrap()
125
	{
126 12
		$bootstrapFile = $this->workingDir . DIRECTORY_SEPARATOR . 'bootstrap.php';
127 12
		if (!is_file($bootstrapFile)) {
128 1
			$this->log("Info: bootstrap.php was not found in working directory.", 'dark_gray');
129 1
			return NULL;
130
		}
131 11
		$this->log("Info: Found bootstrap.php in working directory.", 'dark_gray');
132 11
		$container = require_once $bootstrapFile;
133 11
		if ($container === 1 || $container === TRUE) { // 1 = success, TRUE = already required
134 2
			return NULL;
135 11
		} elseif ($container instanceof Container) {
136 10
			return $container;
137
		}
138 1
		$this->log("Returned value from bootstrap.php must be instance of 'Genesis\\Container\\Container' or nothing (NULL).", 'red');
139 1
		$this->terminate(255);
140
	}
141
142
143
	/**
144
	 * @param $configFile
145
	 * @param Container|NULL $bootstrapContainer
146
	 * @return Container
147
	 */
148 11
	private function createContainer($configFile, Container $bootstrapContainer = NULL)
149
	{
150 11
		$factory = new ContainerFactory();
151 11
		$factory->addConfig($this->workingDir . '/' . $configFile);
152 11
		if (is_file($this->workingDir . '/config.local.neon')) {
153
			$factory->addConfig($this->workingDir . '/config.local.neon');
154
		}
155 11
		$factory->setWorkingDirectory($this->workingDir);
156 11
		if ($bootstrapContainer !== NULL) {
157 10
			$factory->addContainerToMerge($bootstrapContainer);
158 10
		}
159 11
		return $factory->create();
160
	}
161
162
163
	/**
164
	 * @param Container $container
165
	 * @return Build
166
	 */
167 11
	private function createBuild(Container $container, array $arguments = NULL)
168
	{
169 11
		if ($this->buildFactory === NULL) {
170
			throw new InvalidStateException("Build factory was not setted.");
171
		}
172 11
		return $this->buildFactory->create($container, $arguments);
173
	}
174
175
176
	/**
177
	 * @param \Exception|\Throwable $e
178
	 * @throws TerminateException
179
	 */
180 3
	private function handleException($e)
181
	{
182 3
		$this->log("Exited with ERROR:", 'red');
183 3
		$this->log($e->getMessage(), 'red');
184 3
		echo $e->getTraceAsString() . PHP_EOL;
185 3
		$this->terminate(255);
186
	}
187
188
189
	/**
190
	 * @param string $message
191
	 * @param string|null $color
192
	 * @param string|null $backgroundColor
193
	 */
194 13
	private function log($message, $color = NULL, $backgroundColor = NULL)
195
	{
196 13
		echo Cli::getColoredString($message . PHP_EOL, $color, $backgroundColor);
197 13
	}
198
199
}