Completed
Branch bootstrap-refactoring (533d01)
by Adam
03:58
created

Bootstrap::startup()   B

Complexity

Conditions 6
Paths 12

Size

Total Lines 18
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 15
CRAP Score 6.0585

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 18
ccs 15
cts 17
cp 0.8824
rs 8.8571
cc 6
eloc 12
nc 12
nop 1
crap 6.0585
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
	/** @var BuildFactory */
21
	private $buildFactory;
22
23
	/** @var string */
24
	private $workingDir;
25
26
27
	/**
28
	 * @return BuildFactory
29
	 */
30
	public function getBuildFactory()
31
	{
32
		return $this->buildFactory;
33
	}
34
35
36
	/**
37
	 * @param BuildFactory $buildFactory
38
	 */
39 14
	public function setBuildFactory($buildFactory)
40
	{
41 14
		$this->buildFactory = $buildFactory;
42 14
	}
43
44
45 14
	public function run(InputArgs $inputArgs)
46
	{
47 14
		$this->startup($inputArgs);
48 13
		$arguments = $inputArgs->getArguments();
49 13
		if (isset($arguments[0]) && $arguments[0] === 'self-init') {
50 1
			$directoryName = isset($arguments[1]) ? $arguments[1] : 'build';
51 1
			$selfInit = new Commands\SelfInit();
52 1
			$selfInit->setDistDirectory(__DIR__ . '/build-dist');
53 1
			$selfInit->setWorkingDirectory($this->workingDir);
54 1
			$selfInit->setDirname($directoryName);
55 1
			$selfInit->execute();
56 1
			$this->terminate(0);
57
		}
58 12
		$container = $this->resolveBootstrap();
59 11
		$configFile = $inputArgs->getOption('config') ? $inputArgs->getOption('config') : self::DEFAULT_CONFIG_FILE;
60
		try {
61 11
			$container = $this->createContainer($configFile, $container);
62 11
			$build = $this->createBuild($container, $arguments);
63 11
		} catch (Exception $e) {
64 2
			$this->log("Exited with ERROR:", 'red');
65 2
			$this->log($e->getMessage(), 'red');
66 2
			echo $e->getTraceAsString() . PHP_EOL;
67 2
			$this->terminate(255);
68
		}
69 9
		if (count($arguments) < 1) {
70 2
			$this->log("Running default", 'green');
71 2
			$build->runDefault();
0 ignored issues
show
Bug introduced by
The variable $build does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
72 2
			$this->terminate(0);
73
		}
74
75 7
		$method = 'run' . str_replace('-', '', ucfirst($arguments[0]));
76 7
		if (!method_exists($build, $method)) {
77 1
			$this->log("Task '$arguments[0]' does not exists.", 'red');
78 1
			$this->terminate(255);
79
		}
80 6
		$this->log("Running [$arguments[0]]", 'green');
81
		try {
82 6
			$build->$method();
83 6
		} catch (\Exception $e) { // fault barrier -> catch all
84 2
			$this->log("Exited with ERROR:", 'red');
85 2
			$this->log($e->getMessage(), 'red');
86 1
			echo $e->getTraceAsString() . PHP_EOL;
87 1
			$this->terminate(255);
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
		$container = NULL;
0 ignored issues
show
Unused Code introduced by
$container is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
128 12
		if (!is_file($bootstrapFile)) {
129 1
			$this->log("Info: bootstrap.php was not found in working directory.", 'dark_gray');
130 1
			return NULL;
131
		}
132 11
		$this->log("Info: Found bootstrap.php in working directory.", 'dark_gray');
133 11
		$container = require_once $bootstrapFile;
134 11
		if ($container === 1 || $container === TRUE) { // 1 = success, TRUE = already required
135 2
			return NULL;
136 11
		}elseif ($container instanceof Container) {
137 10
			return $container;
138
		}
139 1
		$this->log("Returned value from bootstrap.php must be instance of 'Genesis\\Container\\Container' or nothing (NULL).", 'red');
140 1
		$this->terminate(255);
141
	}
142
143
144
	/**
145
	 * @return Container
146
	 */
147 11
	private function createContainer($configFile, Container $bootstrapContainer = NULL)
148
	{
149 11
		$factory = new ContainerFactory();
150 11
		$factory->addConfig($this->workingDir . '/' . $configFile);
151 11
		if (is_file($this->workingDir . '/config.local.neon')) {
152
			$factory->addConfig($this->workingDir . '/config.local.neon');
153
		}
154 11
		$factory->setWorkingDirectory($this->workingDir);
155 11
		if ($bootstrapContainer !== NULL) {
156 10
			$factory->addContainerToMerge($bootstrapContainer);
157 10
		}
158 11
		return $factory->create();
159
	}
160
161
162
	/**
163
	 * @param Container $container
164
	 * @return Build
165
	 */
166 11
	private function createBuild(Container $container, array $arguments = NULL)
167
	{
168 11
		if ($this->buildFactory === NULL){
169
			throw new InvalidStateException("Build factory was not setted.");
170
		}
171 11
		return $this->buildFactory->create($container, $arguments);
172
	}
173
174
175 13
	private function log($message, $color = NULL, $backgroundColor = NULL)
176
	{
177 13
		echo Cli::getColoredString($message . PHP_EOL, $color, $backgroundColor);
178 13
	}
179
180
}