Completed
Push — master ( 31785d...5192f1 )
by Richard
06:45
created

App::run()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 21
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 11
CRAP Score 2.0145

Importance

Changes 0
Metric Value
dl 0
loc 21
ccs 11
cts 13
cp 0.8462
rs 9.3142
c 0
b 0
f 0
cc 2
eloc 12
nc 2
nop 1
crap 2.0145
1
<?php
2
/******************************************************************************
3
 * An implementation of dicto (scg.unibe.ch/dicto) in and for PHP.
4
 * 
5
 * Copyright (c) 2016 Richard Klees <[email protected]>
6
 *
7
 * This software is licensed under The MIT License. You should have received 
8
 * a copy of the license along with the code.
9
 */
10
11
namespace Lechimp\Dicto\App;
12
13
use Lechimp\Dicto\App\RuleLoader;
14
use Lechimp\Dicto\Definition\RuleParser;
15
use Lechimp\Dicto\Rules\Ruleset;
16
use Lechimp\Dicto\Rules as R;
17
use Lechimp\Dicto\Variables as V;
18
use Symfony\Component\Yaml\Yaml;
19
use Pimple\Container;
20
use PhpParser\ParserFactory;
21
22
/**
23
 * The App to be run from a script.
24
 */
25
class App {
26 12
    public function __construct() {
27 12
        ini_set('xdebug.max_nesting_level', 200);
28 12
    }
29
30
    /**
31
     * Run the app.
32
     *
33
     * @param   array   $params     from commandline
34
     * @return  null
35
     */
36 2
    public function run(array $params) {
37 1
        if (count($params) < 2) {
38
            throw new \RuntimeException(
39
                "Expected path to config-file as first parameter.");
40
        }
41
42
        // drop program name
43 2
        array_shift($params);
44
45
        // the rest of the params are paths to configs
46 1
        list($config_file_path, $configs) = $this->load_configs($params);
47 1
        $t = explode("/", $config_file_path);
48 1
        array_pop($t);
49 1
        $config_file_path = implode("/", $t);
50
51 1
        $dic = $this->create_dic($config_file_path, $configs);
52
53 1
        $this->configure_runtime($dic["config"]);
54
55 1
        $dic["engine"]->run();
56 1
    }
57
58
    /**
59
     * Create and initialize the DI-container.
60
     *
61
     * @param   string      $config_file_path
62
     * @param   array       &$configs
63
     * @return  Container
64
     */
65 6
    protected function create_dic($config_file_path, array &$configs) {
66 6
        array('is_string($rule_file_path)');
67
68 6
        $container = new Container();
69
70
        $container["config"] = function () use ($config_file_path, &$configs) {
71 5
            return new Config($config_file_path, $configs);
72
        };
73
74
        $container["ruleset"] = function($c) {
75 1
            $rule_file_path = $c["config"]->project_rules();
76 1
            if (!file_exists($rule_file_path)) {
77
                throw new \RuntimeException("Unknown rule-file '$rule_file_path'");
78
            }
79 1
            $ruleset = $c["rule_loader"]->load_rules_from($rule_file_path);
80 1
            return $ruleset;
81
        };
82
83
        $container["rule_loader"] = function($c) {
84 1
            return new RuleLoader($c["rule_parser"]);
85
        };
86
87
        $container["rule_parser"] = function($c) {
88
            return new RuleParser
89 1
                ( $c["variables"]
90 1
                , $c["schemas"]
91 1
                , $c["properties"]
92 1
                );
93
        };
94
95
        $container["engine"] = function($c) {
96
            return new Engine
97 1
                ( $c["log"]
98 1
                , $c["config"]
99 1
                , $c["database_factory"]
100 1
                , $c["indexer_factory"]
101 1
                , $c["analyzer_factory"]
102 1
                , $c["source_status"]
103 1
                );
104
        };
105
106
        $container["log"] = function () {
107 2
            return new CLILogger();
108
        };
109
110
        $container["database_factory"] = function() {
111 1
            return new DBFactory();
112
        };
113
114
        $container["indexer_factory"] = function($c) {
115
            return new \Lechimp\Dicto\Indexer\IndexerFactory
116 2
                ( $c["log"]
117 2
                , $c["php_parser"]
118 2
                , array
119 2
                    ( new \Lechimp\Dicto\Rules\ContainText()
120 2
                    , new \Lechimp\Dicto\Rules\DependOn()
121 2
                    , new \Lechimp\Dicto\Rules\Invoke()
122 2
                    )
123 2
                );
124
        };
125
126
        $container["analyzer_factory"] = function($c) {
127
            return new \Lechimp\Dicto\Analysis\AnalyzerFactory
128 1
                ( $c["log"]
129 1
                , $c["ruleset"]
130 1
                );
131
        };
132
133
        $container["php_parser"] = function() {
134 2
            return (new ParserFactory)->create(ParserFactory::PREFER_PHP7);
135
        };
136
137
        $container["report_generator"] = function() {
138
            return new CLIReportGenerator();
139
        };
140
141
        $container["source_status"] = function($c) {
142 2
            return new SourceStatusGit($c["config"]->project_root());
143
        };
144
145
        $container["schemas"] = function($c) {
146 2
            return $this->load_schemas($c["config"]->rules_schemas());
147
        };
148
149
        $container["properties"] = function($c) {
150 2
            return $this->load_properties($c["config"]->rules_properties());
151
        };
152
153 2
        $container["variables"] = function($c) {
154 2
            return $this->load_variables($c["config"]->rules_variables());
155
        };
156
157 6
        return $container;
158
    }
159
160
    /**
161
     * Configure php runtime.
162
     *
163
     * @param   Config  $config
164
     * @return  null
165
     */
166 2
    protected function configure_runtime(Config $config) {
167 2
        if ($config->runtime_check_assertions()) {
168 1
            assert_options(ASSERT_ACTIVE, true);
169 1
            assert_options(ASSERT_WARNING, true);
170 1
            assert_options(ASSERT_BAIL, false);
171 1
        }
172
        else {
173 1
            assert_options(ASSERT_ACTIVE, false);
174 1
            assert_options(ASSERT_WARNING, false);
175 1
            assert_options(ASSERT_BAIL, false);
176
        }
177 2
    }
178
179
    /**
180
     * Load extra configs from yaml files.
181
     *
182
     * @param   array   $config_file_paths
183
     * @return  array
184
     */
185 6
    protected function load_configs(array $config_file_paths) {
186 6
        $configs_array = array();
187 6
        $config_file_path = null;
188 6
        foreach ($config_file_paths as $config_file) {
189 6
            if (!file_exists($config_file)) {
190
                throw new \RuntimeException("Unknown config-file '$config_file'");
191
            }
192 6
            if ($config_file_path === null) {
193 6
                $config_file_path = $config_file;
194 6
            }
195 6
            $configs_array[] = Yaml::parse(file_get_contents($config_file));
196 6
        }
197 6
        return array($config_file_path, $configs_array);
198
    }
199
200
    /**
201
     * Loads the schemas defined in the config.
202
     *
203
     * @param   array   $schema_classes
204
     * @return  R\Schema[]
205
     */
206 3
    protected function load_schemas(array $schema_classes) {
207 3
        $schemas = array();
208 3
        foreach ($schema_classes as $schema_class) {
209 3
            $schema = new $schema_class;
210 3
            if (!($schema instanceof R\Schema)) {
211
                throw new \RuntimeException("'$schema_class' is not a Schema-class.");
212
            }
213 3
            $schemas[] = $schema;
214 3
        }
215 3
        return $schemas;
216
    }
217
218
    /**
219
     * Loads the properties defined in the config.
220
     *
221
     * @param   array   $property_classes
222
     * @return  R\Schema[]
223
     */
224 3
    protected function load_properties(array $property_classes) {
225 3
        $properties = array();
226 3
        foreach ($property_classes as $property_class) {
227 3
            $property = new $property_class;
228 3
            if (!($property instanceof V\Property)) {
229
                throw new \RuntimeException("'$property_class' is not a Schema-class.");
230
            }
231 3
            $properties[] = $property;
232 3
        }
233 3
        return $properties;
234
    }
235
236
    /**
237
     * Loads the variables defined in the config.
238
     *
239
     * @param   array   $variable_classes
240
     * @return  R\Schema[]
241
     */
242 3
    protected function load_variables(array $variable_classes) {
243 3
        $variables = array();
244 3
        foreach ($variable_classes as $variable_class) {
245 3
            $variable = new $variable_class;
246 3
            if (!($variable instanceof V\Variable)) {
247
                throw new \RuntimeException("'$variable_class' is not a Schema-class.");
248
            }
249 3
            $variables[] = $variable;
250 3
        }
251 3
        return $variables;
252
    }
253
}
254