Completed
Push — master ( 45b1bb...11e0c2 )
by Adam
03:27
created

Bootstrap.php (10 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

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
 * Bootstrap
14
 */
15
class Bootstrap
16
{
17
18
	const DEFAULT_CONFIG_FILE = 'config.neon';
19
20
21
	public function run(InputArgs $inputArgs)
22
	{
23
		$workingDir = getcwd();
24
		if ($inputArgs->getOption('colors') !== NULL && !$inputArgs->getOption('colors')) {
25
			Cli::$enableColors = FALSE;
26
		}
27
		if ($inputArgs->getOption('working-dir')) {
28
			$workingDir = realpath($inputArgs->getOption('working-dir'));
29
			if (!$workingDir) {
30
				$this->log(sprintf("Working dir '%s' does not exists.", $inputArgs->getOption('working-dir')), 'red');
31
				exit(255);
1 ignored issue
show
Coding Style Compatibility introduced by
The method run() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
32
			}
33
		}
34
		if ($workingDir === __DIR__) {
35
			$this->log(sprintf("Working dir '%s' is directory with Genesis. You have to choose directory with build.", $workingDir), 'red');
36
			exit(255);
1 ignored issue
show
Coding Style Compatibility introduced by
The method run() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
37
		}
38
39
		$arguments = $inputArgs->getArguments();
40
		if(isset($arguments[0]) && $arguments[0] === 'self-init'){
41
			$directoryName = isset($arguments[1]) ? $arguments[1] : 'build';
42
			$selfInit = new Commands\SelfInit();
43
			$selfInit->setDistDirectory(__DIR__ . '/build-dist');
44
			$selfInit->setWorkingDirectory($workingDir);
45
			$selfInit->setDirname($directoryName);
46
			$selfInit->execute();
47
			exit(0);
1 ignored issue
show
Coding Style Compatibility introduced by
The method run() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
48
		}
49
50
		$bootstrapFile = $this->detectBootstrapFilename($workingDir);
51
		$container = NULL;
52
		if (is_file($bootstrapFile)) {
53
			$this->log("Info: Found bootstrap.php in working directory.", 'dark_gray');
54
			$container = require_once $bootstrapFile;
55
			if($container === 1 || $container === TRUE){ // 1 = success, TRUE = already required
56
				$container = NULL;
57
			}elseif(!($container instanceof Container)){
58
				$this->log("Returned value from bootstrap.php must be instance of 'Genesis\\Container\\Container' or nothing (NULL).", 'red');
59
				exit(255);
1 ignored issue
show
Coding Style Compatibility introduced by
The method run() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
60
			}
61
		} else {
62
			$this->log("Info: bootstrap.php was not found in working directory.", 'dark_gray');
63
		}
64
65
		$arguments = $inputArgs->getArguments();
66
		$configFile = $inputArgs->getOption('config') ? $inputArgs->getOption('config') : self::DEFAULT_CONFIG_FILE;
67
		try {
68
			$container = $this->createContainer($workingDir, $configFile, $container);
69
			$build = $this->createBuild($container, $arguments);
70
		} catch (\Exception $e) {
71
			$this->log("Exited with ERROR:", 'red');
72
			$this->log($e->getMessage(), 'red');
73
			echo $e->getTraceAsString() . PHP_EOL;
74
			exit(255);
1 ignored issue
show
Coding Style Compatibility introduced by
The method run() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
75
		}
76
		if (count($arguments) < 1) {
77
			$this->log("Running default", 'green');
78
			$build->runDefault();
79
			exit(0);
1 ignored issue
show
Coding Style Compatibility introduced by
The method run() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
80
		}
81
82
		$method = 'run' . str_replace('-', '', ucfirst($arguments[0]));
83
		if (!method_exists($build, $method)) {
84
			$this->log("Task '$arguments[0]' does not exists.", 'red');
85
			exit(255);
1 ignored issue
show
Coding Style Compatibility introduced by
The method run() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
86
		}
87
		$this->log("Running [$arguments[0]]", 'green');
88
		try {
89
			$build->$method();
90
		} catch (\Exception $e) {
91
			$this->log("Exited with ERROR:", 'red');
92
			$this->log($e->getMessage(), 'red');
93
			echo $e->getTraceAsString() . PHP_EOL;
94
			exit(255);
1 ignored issue
show
Coding Style Compatibility introduced by
The method run() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
95
		}
96
		$this->log("Exited with SUCCESS", 'black', 'green');
97
		echo PHP_EOL;
98
		exit(0);
1 ignored issue
show
Coding Style Compatibility introduced by
The method run() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
99
	}
100
101
102
	protected function detectBootstrapFilename($workingDir)
103
	{
104
		return $workingDir . DIRECTORY_SEPARATOR . 'bootstrap.php';
105
	}
106
107
108
	/**
109
	 * @return Container
110
	 */
111
	protected function createContainer($workingDir, $configFile, Container $bootstrapContainer = NULL)
112
	{
113
		$factory = new ContainerFactory();
114
		$factory->addConfig($workingDir . '/' . $configFile);
115
		if(is_file($workingDir . '/config.local.neon')){
116
			$factory->addConfig($workingDir . '/config.local.neon');
117
		}
118
		$factory->setWorkingDirectory($workingDir);
119
		if($bootstrapContainer !== NULL){
120
			$factory->addContainerToMerge($bootstrapContainer);
121
		}
122
		return $factory->create();
123
	}
124
125
126
	/**
127
	 * @param Container $container
128
	 * @return Build
129
	 */
130
	protected function createBuild(Container $container, array $arguments = NULL)
131
	{
132
		$class = $container->getClass();
133
		if (!class_exists($class, TRUE)) {
134
			$this->log(sprintf(
135
				"Build class '%s' was not found." . PHP_EOL .
136
				"Are you in correct working directory?" . PHP_EOL .
137
				"Did you forget add bootstrap.php with class loading into working directory?" . PHP_EOL .
138
				"Did you forget to load class %s?", $class, $class), 'red');
139
			exit(255);
1 ignored issue
show
Coding Style Compatibility introduced by
The method createBuild() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
140
		}
141
		$build = new $class($container, $arguments);
142
		if (!($build instanceof IBuild)) {
143
			throw new \RuntimeException("Instance of build does not implements interface IBuild.");
144
		}
145
		$this->autowire($build, $container);
146
		$build->setup();
147
		return $build;
148
	}
149
150
151
	protected function autowire(IBuild $build, Container $container)
152
	{
153
		foreach ($this->getAutowiredProperties($build) as $property => $service) {
154
			if(!$container->hasService($service)){
155
				throw new \RuntimeException("Cannot found service '$service' to inject into " . get_class($build) . "::$property.");
156
			}
157
			$build->$property = $container->getService($service);
158
		}
159
	}
160
161
162
	protected function getAutowiredProperties($class)
163
	{
164
		$return = [];
165
		$reflectionClass = new \ReflectionClass($class);
166
		foreach($reflectionClass->getProperties(\ReflectionProperty::IS_PUBLIC) as $property){
167
			$reflectionProp = new \ReflectionProperty($class, $property->getName());
168
			$doc = $reflectionProp->getDocComment();
169
			if(preg_match('#@inject ?([^\s]*)\s#s', $doc, $matches)){
170
				$return[$property->getName()] = trim($matches[1]) !== '' ? $matches[1] : $property->getName();
171
			}
172
		}
173
		return $return;
174
	}
175
176
177
	protected function log($message, $color = NULL, $backgroundColor = NULL)
178
	{
179
		echo Cli::getColoredString($message . PHP_EOL, $color, $backgroundColor);
180
	}
181
182
}