Conditions | 28 |
Paths | 2438 |
Total Lines | 204 |
Code Lines | 117 |
Lines | 0 |
Ratio | 0 % |
Changes | 0 |
Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.
For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.
Commonly applied refactorings include:
If many parameters/temporary variables are present:
1 | <?php |
||
40 | public function fetchProjectData($project): array |
||
41 | { |
||
42 | |||
43 | $projectName = $project['name']; |
||
44 | |||
45 | // Check if git is installed |
||
46 | $process = new Process('command -v git'); |
||
47 | $process->run(); |
||
48 | |||
49 | if ($process->getOutput() == '') { |
||
50 | throw new \Exception('Git is not installed!'); |
||
51 | } |
||
52 | |||
53 | // Check if composer is installed |
||
54 | $process = new Process('command -v composer'); |
||
55 | $process->run(); |
||
56 | |||
57 | if ($process->getOutput() == '') { |
||
58 | throw new \Exception('Composer is not installed!'); |
||
59 | } |
||
60 | |||
61 | // If project already exists, just pull updates. Otherwise clone the repository. |
||
62 | // ToDo: "git reset" pulls every file of the git |
||
63 | if (is_dir('var/data/' . $project['name'])) { |
||
64 | $process = new Process('cd var/data/' . $project['name'] . ' && git reset --hard origin/master'); |
||
65 | } else { |
||
66 | $process = new Process('git clone -n ' . $project['git'] . ' var/data/' . $project['name'] . ' --depth 1 -b master --single-branch'); |
||
67 | } |
||
68 | |||
69 | $process->setTimeout(3600); |
||
70 | $process->run(); |
||
71 | |||
72 | if (!$process->isSuccessful()) { |
||
73 | throw new ProcessFailedException($process); |
||
74 | } |
||
75 | |||
76 | // Check if composer.json exists in project |
||
77 | $process = new Process( |
||
78 | 'cd var/data/' . $project['name'] . '/ && ' . |
||
79 | 'git cat-file -e origin/master:' . $project['path'] . 'composer.json && echo true' |
||
80 | ); |
||
81 | $process->run(); |
||
82 | |||
83 | if (trim($process->getOutput()) != 'true') { |
||
84 | throw new \Exception('No composer.json found in the project ' . $projectName); |
||
85 | } |
||
86 | |||
87 | // Check if composer.lock exists in project |
||
88 | $process = new Process( |
||
89 | 'cd var/data/' . $project['name'] . '/ && ' . |
||
90 | 'git cat-file -e origin/master:' . $project['path'] . 'composer.lock && echo true' |
||
91 | ); |
||
92 | $process->run(); |
||
93 | $composerLock = false; |
||
94 | |||
95 | if (trim($process->getOutput()) == 'true') { |
||
96 | $composerLock = true; |
||
97 | } |
||
98 | |||
99 | // Preparing composer project setup |
||
100 | // ToDo: Is it possible to combine multiple processes in a better way? |
||
101 | $process = new Process( |
||
102 | 'cd var/data/' . $project['name'] . '/ && ' . |
||
103 | // Checkout composer.json file |
||
104 | 'git checkout HEAD ' . $project['path'] . 'composer.json && ' . |
||
105 | // Checkout composer.lock file |
||
106 | (($composerLock) ? 'git checkout HEAD ' . $project['path'] . 'composer.lock && ' : '') . |
||
107 | // Change directory |
||
108 | (($project['path'] != '') ? 'cd ' . $project['path'] . ' && ' : '') . |
||
109 | // Install composer dependencies |
||
110 | 'composer install --no-dev --no-autoloader --no-scripts --ignore-platform-reqs' |
||
111 | ); |
||
112 | |||
113 | $process->setTimeout(3600); |
||
114 | $process->run(); |
||
115 | |||
116 | if (!$process->isSuccessful()) { |
||
117 | throw new ProcessFailedException($process); |
||
118 | } |
||
119 | |||
120 | $process = new Process( |
||
121 | 'cd var/data/' . $project['name'] . ' && ' . |
||
122 | 'git describe --tags $(git rev-list --tags --max-count=1)' |
||
123 | ); |
||
124 | $process->run(); |
||
125 | $gitTag = $process->getOutput(); |
||
126 | |||
127 | $process = new Process( |
||
128 | 'cd var/data/' . $project['name'] . '/' . $project['path'] . ' && ' . |
||
129 | 'composer show --latest --minor-only --format json' |
||
130 | ); |
||
131 | $process->run(); |
||
132 | |||
133 | if (!$process->isSuccessful()) { |
||
134 | throw new ProcessFailedException($process); |
||
135 | } |
||
136 | |||
137 | $data = json_decode($process->getOutput()); |
||
138 | |||
139 | if (empty($data)) { |
||
140 | throw new \Exception('Empty result of "composer show" for project ' . $projectName); |
||
141 | } |
||
142 | |||
143 | $process = new Process( |
||
144 | 'curl -H "Accept: application/json" https://security.sensiolabs.org/check_lock -F lock=@var/data/' . $project['name'] . '/' . $project['path'] . 'composer.lock' |
||
145 | ); |
||
146 | $process->run(); |
||
147 | |||
148 | if (!$process->isSuccessful()) { |
||
149 | throw new ProcessFailedException($process); |
||
150 | } |
||
151 | $vulnerabilities = json_decode($process->getOutput()); |
||
152 | |||
153 | // |
||
154 | // Evaluate data |
||
155 | // |
||
156 | |||
157 | $result = []; |
||
158 | |||
159 | // Saving composer information about project to result |
||
160 | $result['composer'] = json_decode(file_get_contents('var/data/' . $project['name'] . '/' . $project['path'] . 'composer.json')); |
||
161 | $result['self'] = $project; |
||
162 | |||
163 | $requiredPackagesCount = 0; |
||
164 | $statesCount = [ |
||
165 | VersionHelper::STATE_UP_TO_DATE => 0, |
||
166 | VersionHelper::STATE_PINNED_OUT_OF_DATE => 0, |
||
167 | VersionHelper::STATE_OUT_OF_DATE => 0, |
||
168 | VersionHelper::STATE_INSECURE => 0 |
||
169 | ]; |
||
170 | $requiredStatesCount = [ |
||
171 | VersionHelper::STATE_UP_TO_DATE => 0, |
||
172 | VersionHelper::STATE_PINNED_OUT_OF_DATE => 0, |
||
173 | VersionHelper::STATE_OUT_OF_DATE => 0, |
||
174 | VersionHelper::STATE_INSECURE => 0 |
||
175 | ]; |
||
176 | $projectState = VersionHelper::STATE_UP_TO_DATE; |
||
177 | |||
178 | foreach ($data->installed as $dependency) { |
||
179 | // Workaround for adding requirement information to dependencies |
||
180 | foreach ($result['composer']->require as $name => $require) { |
||
181 | if ($dependency->name == $name) { |
||
182 | $dependency->required = $require; |
||
183 | $requiredPackagesCount++; |
||
184 | } |
||
185 | |||
186 | // Which project type? |
||
187 | if (array_key_exists($name, $this->projectTypes)) { |
||
188 | $result['self']['projectType'] = $this->projectTypes[$name]; |
||
189 | } |
||
190 | } |
||
191 | |||
192 | // Is dependency outdated? |
||
193 | if (isset($dependency->latest)) { |
||
194 | $require = isset($dependency->required) ? $dependency->required : null; |
||
195 | $state = VersionHelper::compareVersions($dependency->version, $dependency->latest, $require); |
||
196 | $statesCount[$state]++; |
||
197 | if ($require) { |
||
198 | $requiredStatesCount[$state]++; |
||
199 | } |
||
200 | $dependency->state = $state; |
||
201 | } else { |
||
202 | $dependency->state = VersionHelper::STATE_UP_TO_DATE; |
||
203 | } |
||
204 | |||
205 | // Is dependency a security issue? |
||
206 | foreach ($vulnerabilities as $name => $vulnerability) { |
||
207 | if ($name == $dependency->name) { |
||
208 | $dependency->state = VersionHelper::STATE_INSECURE; |
||
209 | $array = []; |
||
210 | foreach ($vulnerability->advisories as $advisory) { |
||
211 | array_push($array, $advisory); |
||
212 | } |
||
213 | $dependency->vulnerability = $array; |
||
214 | if (isset($dependency->required)) { |
||
215 | $requiredStatesCount[VersionHelper::STATE_INSECURE]++; |
||
216 | } else { |
||
217 | $statesCount[VersionHelper::STATE_INSECURE]++; |
||
218 | } |
||
219 | } |
||
220 | } |
||
221 | |||
222 | $result['dependencies'][] = $dependency; |
||
223 | } |
||
224 | |||
225 | if ($requiredStatesCount[4] > 0) { |
||
226 | $projectState = VersionHelper::STATE_INSECURE; |
||
227 | } elseif ($requiredStatesCount[3] > 2) { |
||
228 | $projectState = VersionHelper::STATE_OUT_OF_DATE; |
||
229 | } elseif ($requiredStatesCount[3] <= 2 && $requiredStatesCount[2] >= 1) { |
||
230 | $projectState = VersionHelper::STATE_PINNED_OUT_OF_DATE; |
||
231 | } |
||
232 | |||
233 | $metadata = [ |
||
234 | 'requiredPackagesCount' => $requiredPackagesCount, |
||
235 | 'statesCount' => $statesCount, |
||
236 | 'requiredStatesCount' => $requiredStatesCount, |
||
237 | 'projectState' => $projectState, |
||
238 | 'gitTag' => $gitTag |
||
239 | ]; |
||
240 | |||
241 | $result['meta'] = $metadata; |
||
242 | |||
243 | return $result; |
||
244 | } |
||
256 | } |