Completed
Branch bootstrap-refactoring (53fe8d)
by Adam
03:39
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
0 ignored issues
show
Bug introduced by
The class Throwable does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
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
0 ignored issues
show
Bug introduced by
The class Throwable does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
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
}