Completed
Push — master ( dc889e...13f9c8 )
by Andrii
02:52
created

History   B

Complexity

Total Complexity 49

Size/Duplication

Total Lines 224
Duplicated Lines 0 %

Coupling/Cohesion

Components 2
Dependencies 1

Test Coverage

Coverage 33.07%

Importance

Changes 3
Bugs 0 Features 1
Metric Value
wmc 49
c 3
b 0
f 1
lcom 2
cbo 1
dl 0
loc 224
ccs 42
cts 127
cp 0.3307
rs 8.5454

27 Methods

Rating   Name   Duplication   Size   Complexity  
A addHeader() 0 4 1
A setHeaders() 0 4 1
A getHeaders() 0 4 1
A addLink() 0 4 1
A setLinks() 0 4 1
A getLinks() 0 4 1
A getTags() 0 4 1
A setTags() 0 4 1
A findTag() 0 8 2
A hasTag() 0 4 1
A addTag() 0 4 1
A addNote() 0 4 1
A hasHash() 0 4 1
A addHash() 0 4 1
A addCommit() 0 5 1
A addComment() 0 4 1
A addHistory() 0 14 2
A addGitLog() 0 12 4
D render() 0 28 9
A arrayPop() 0 7 1
A renderNote() 0 4 1
A renderLines() 0 6 2
A renderCommit() 0 4 2
B skipCommit() 0 25 4
A renderTag() 0 8 3
A renderDate() 0 4 2
A renderHeader() 0 9 2

How to fix   Complexity   

Complex Class

Complex classes like History often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use History, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
/*
4
 * Changelog keeper
5
 *
6
 * @link      https://github.com/hiqdev/chkipper
7
 * @package   chkipper
8
 * @license   BSD-3-Clause
9
 * @copyright Copyright (c) 2016, HiQDev (http://hiqdev.com/)
10
 */
11
12
namespace hiqdev\chkipper\history;
13
14
/**
15
 * History class.
16
 * Holds history of commits.
17
 *
18
 * @author Andrii Vasyliev <[email protected]>
19
 */
20
class History
21
{
22
    protected $_headers = [];
23
    protected $_hashes  = [];
24
    protected $_links   = [];
25
    protected $_tags    = [];
26
27 2
    public function addHeader($str)
28
    {
29 2
        $this->_headers[$str] = $str;
30 2
    }
31
32 1
    public function setHeaders($value)
33
    {
34 1
        $this->_headers = $value;
35 1
    }
36
37 1
    public function getHeaders()
38
    {
39 1
        return $this->_headers;
40
    }
41
42 2
    public function addLink($link, $href)
43
    {
44 2
        $this->_links[$link] = $href;
45 2
    }
46
47 1
    public function setLinks($value)
48
    {
49 1
        $this->_links = $value;
50 1
    }
51
52 2
    public function getLinks()
53
    {
54 2
        return $this->_links;
55
    }
56
57 1
    public function getTags()
58
    {
59 1
        return $this->_tags;
60
    }
61
62 1
    public function setTags(array $value)
63
    {
64 1
        $this->_tags = $value;
65 1
    }
66
67 2
    public function findTag($tag)
68
    {
69 2
        if (!isset($this->_tags[$tag])) {
70 2
            $this->_tags[$tag] = new Tag($tag);
71 2
        }
72
73 2
        return $this->_tags[$tag];
74
    }
75
76
    public function hasTag($tag)
77
    {
78
        return array_key_exists($tag, $this->_tags);
79
    }
80
81 2
    public function addTag($tag, $date = null)
82
    {
83 2
        $this->findTag($tag)->setDate($date);
84 2
    }
85
86 2
    public function addNote($tag, $note)
87
    {
88 2
        $this->findTag($tag)->findNote($note);
89 2
    }
90
91
    public function hasHash($hash)
92
    {
93
        return array_key_exists((string) $hash, $this->_hashes);
94
    }
95
96 2
    public function addHash($hash, $label)
97
    {
98 2
        $this->_hashes[(string) $hash] = $label;
99 2
    }
100
101 2
    public function addCommit($tag, $note, $hash, $label = null)
102
    {
103 2
        $this->addHash($hash, $label);
104 2
        $this->findTag($tag)->findNote($note)->findCommit($hash)->setLabel($label);
105 2
    }
106
107 2
    public function addComment($tag, $note, $hash, $text = null)
108
    {
109 2
        $this->findTag($tag)->findNote($note)->findCommit($hash)->addComment($text);
110 2
    }
111
112
    public function addHistory($commit, $front = false)
113
    {
114
        $tag    = $commit['tag'];
115
        $note   = $commit['note'];
116
        $hash   = $commit['hash'];
117
        $render = static::renderCommit($commit);
118
        $hashes = &$this->_tags[$tag][$note];
119
        $hashes = (array) $hashes;
120
        if ($front) {
121
            $hashes = [$hash => [$render]] + $hashes;
122
        } else {
123
            $hashes[$hash][] = $render;
124
        }
125
    }
126
127
    public function addGitLog()
128
    {
129
        foreach (array_reverse(static::getVcs()->commits, true) as $hash => $commit) {
0 ignored issues
show
Bug introduced by
The method getVcs() does not seem to exist on object<hiqdev\chkipper\history\History>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
130
            if ($this->hasCommit($hash)) {
0 ignored issues
show
Bug introduced by
The method hasCommit() does not seem to exist on object<hiqdev\chkipper\history\History>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
131
                continue;
132
            }
133
            $this->addHistory($commit, true);
134
        }
135
        if (!$this->hasHistory(static::getVcs()->initTag)) {
0 ignored issues
show
Bug introduced by
The method getVcs() does not seem to exist on object<hiqdev\chkipper\history\History>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
Bug introduced by
The method hasHistory() does not seem to exist on object<hiqdev\chkipper\history\History>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
136
            $this->addHistory(['tag' => static::getVcs()->initTag]);
0 ignored issues
show
Bug introduced by
The method getVcs() does not seem to exist on object<hiqdev\chkipper\history\History>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
137
        }
138
    }
139
140
    public function render($data)
0 ignored issues
show
Unused Code introduced by
The parameter $data is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
141
    {
142
        $res = static::renderHeader('commits history');
143
144
        foreach ($this->_tags as $tag => $notes) {
145
            $prev = $res;
146
            $tag  = static::arrayPop($notes, 'tag') ?: $tag;
147
            $new  = static::arrayPop($notes, '') ?: [];
148
            $res .= static::renderTag($tag);
149
            $save = $res;
150
            foreach ($new as $hash => $lines) {
151
                $res .= static::renderLines($lines);
152
            }
153
            foreach ($notes as $note => $cs) {
154
                $note = static::arrayPop($cs, 'note');
155
                $res .= static::renderNote($note);
156
                foreach ($cs as $hash => $lines) {
157
                    $res .= static::renderLines($lines);
158
                }
159
            }
160
            if ($save === $res && stripos($tag, static::getVcs()->lastTag) !== false) {
0 ignored issues
show
Bug introduced by
The method getVcs() does not seem to exist on object<hiqdev\chkipper\history\History>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
161
                $res = $prev;
162
                unset($this->_tags[$tag]);
163
            }
164
        }
165
166
        return $res;
167
    }
168
169
    public static function arrayPop(&$array, $key)
170
    {
171
        $res = $array[$key];
172
        unset($array[$key]);
173
174
        return $res;
175
    }
176
177
    public static function renderNote($note)
178
    {
179
        return "- $note\n";
180
    }
181
182
    public static function renderLines(array $lines)
183
    {
184
        $res = implode("\n", array_filter($lines));
185
186
        return $res ? $res . "\n" : '';
187
    }
188
189
    public static function renderCommit($commit)
190
    {
191
        return static::skipCommit($commit) ? '' : "    - $commit[hash] $commit[date] $commit[comment] ($commit[email])";
192
    }
193
194
    public static function skipCommit($commit)
195
    {
196
        $comment = $commit['comment'];
197
198
        static $equals = [
199
            ''      => 1,
200
            'minor' => 1,
201
        ];
202
        if ($equals[$comment]) {
203
            return true;
204
        }
205
206
        static $starts = [
207
            'version bump',
208
            'bumped version',
209
            "merge branch 'master'",
210
        ];
211
        foreach ($starts as $start) {
212
            if (strtolower(substr($comment, 0, strlen($start))) === $start) {
213
                return true;
214
            }
215
        }
216
217
        return false;
218
    }
219
220
    public static function renderTag($tag)
221
    {
222
        if (strpos($tag, ' ') === false || $tag === static::getVcs()->initTag) {
0 ignored issues
show
Bug introduced by
The method getVcs() does not seem to exist on object<hiqdev\chkipper\history\History>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
223
            $tag .= static::renderDate(static::getVcs()->tags[$tag]);
0 ignored issues
show
Bug introduced by
The method getVcs() does not seem to exist on object<hiqdev\chkipper\history\History>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
224
        }
225
226
        return "\n## $tag\n\n";
227
    }
228
229
    public static function renderDate($date)
230
    {
231
        return $date ? date(' Y-m-d', strtotime($date)) : '';
232
    }
233
234
    public static function renderHeader($string)
0 ignored issues
show
Unused Code introduced by
The parameter $string is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
235
    {
236
        $res = '';
237
        foreach ($this->_headers as $str) {
0 ignored issues
show
Bug introduced by
The variable $this does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
238
            $res .= $str . "\n";
239
        }
240
241
        return $res;
242
    }
243
}
244