Passed
Push — master ( 44fbe0...ac8f8c )
by Allan
02:36 queued 10s
created

OutputGenerator::createOutputLines()   B

Complexity

Conditions 7
Paths 9

Size

Total Lines 26
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 7
eloc 13
nc 9
nop 1
dl 0
loc 26
rs 8.8333
c 0
b 0
f 0
1
<?php
2
/**
3
 * Copyright © Vaimo Group. All rights reserved.
4
 * See LICENSE_VAIMO.txt for license details.
5
 */
6
namespace Vaimo\ComposerPatches\Console;
7
8
class OutputGenerator
9
{
10
    /**
11
     * @var \Vaimo\ComposerPatches\Logger
12
     */
13
    private $logger;
14
    
15
    public function __construct(
16
        \Vaimo\ComposerPatches\Logger $logger
17
    ) {
18
        $this->logger = $logger;
19
    }
20
21
    public function generateForException(\Exception $exception)
22
    {
23
        if ($exception instanceof \Vaimo\ComposerPatches\Exceptions\ApplierFailure) {
24
            $errors = array_filter($exception->getErrors());
25
            
26
            if (empty($errors)) {
27
                return;
28
            }
29
30
            $prioritizedErrors = $this->prioritizeErrors($errors);
31
            
32
            $lines = array_merge(
33
                array('Probable causes for the failure:', ''),
34
                $this->createOutputLines($prioritizedErrors),
35
                array('', '(For full, unfiltered details please use: composer patch:apply -vvv)')
36
            );
37
38
            $this->logger->writeNotice('warning', $lines);
39
        }
40
    }
41
42
    private function createOutputLines(array $errors)
43
    {
44
        $lines = array();
45
46
        foreach ($errors as $type => $groups) {
47
            if (!empty($lines)) {
48
                $lines[] = '';
49
            }
50
51
            $lines[] = sprintf('> %s', $type);
52
53
            foreach ($groups as $path => $messages) {
54
                $details = array(
55
                    '@' => $path,
56
                    '!' => reset($messages)
57
                );
58
59
                foreach (array_filter($details) as $marker => $value) {
60
                    foreach (explode(PHP_EOL, $value) as $index => $item) {
61
                        $lines[] = sprintf('  %s %s', !$index ? $marker : ' ', $item);
62
                    }
63
                }
64
            }
65
        }
66
67
        return $lines;
68
    }
69
    
70
    private function prioritizeErrors(array $errors)
71
    {
72
        $filters = array(
73
            'can\'t find file',
74
            'unable to find file',
75
            'no such file',
76
            'no file to patch'
77
        );
78
79
        $filterPattern = sprintf('/(%s)/i', implode('|', $filters));
80
81
        $result = array();
82
83
        foreach ($errors as $code => $groups) {
84
            $result[$code] = array();
85
86
            foreach ($groups as $path => $messages) {
87
                $messages = array_unique($messages);
88
89
                $fileNotFoundMessages = preg_grep($filterPattern, $messages);
90
91
                if ($fileNotFoundMessages !== $messages) {
92
                    $messages = array_merge(
93
                        array_diff($messages, $fileNotFoundMessages),
94
                        $fileNotFoundMessages
95
                    );
96
                }
97
98
                $result[$code][$path] = $messages;
99
            }
100
        }
101
102
        return array_map(function (array $items) {
103
            $filteredItems = array_filter($items);
104
            
105
            if (isset($filteredItems['']) && count($filteredItems) > 1) {
106
                unset($filteredItems['']);
107
            }
108
            
109
            return $filteredItems;
110
        }, $result);
111
    }
112
}
113