Completed
Branch bootstrap-refactoring (b38e68)
by Adam
04:20
created

Bootstrap.php (1 issue)

Labels
Severity

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
	/** @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
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;
128 12
		if (is_file($bootstrapFile)) {
129 11
			$this->log("Info: Found bootstrap.php in working directory.", 'dark_gray');
130 11
			$container = require_once $bootstrapFile;
131 11
			if ($container === 1 || $container === TRUE) { // 1 = success, TRUE = already required
132 2
				$container = NULL;
133 11
			}elseif (!($container instanceof Container)) {
134 1
				$this->log("Returned value from bootstrap.php must be instance of 'Genesis\\Container\\Container' or nothing (NULL).", 'red');
135 1
				$this->terminate(255);
136
			}
137 10
		} else {
138 1
			$this->log("Info: bootstrap.php was not found in working directory.", 'dark_gray');
139
		}
140 11
		return $container;
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
}