Completed
Push — master ( 24d81b...f92269 )
by Andrii
02:51
created

GitController::loadHistory()   B

Complexity

Conditions 5
Paths 5

Size

Total Lines 23
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 30

Importance

Changes 3
Bugs 2 Features 0
Metric Value
c 3
b 2
f 0
dl 0
loc 23
ccs 0
cts 23
cp 0
rs 8.5906
cc 5
eloc 16
nc 5
nop 0
crap 30
1
<?php
2
3
/*
4
 * Task runner, code generator and build tool for easier continuos integration
5
 *
6
 * @link      https://github.com/hiqdev/hidev
7
 * @package   hidev
8
 * @license   BSD-3-Clause
9
 * @copyright Copyright (c) 2015-2016, HiQDev (http://hiqdev.com/)
10
 */
11
12
namespace hidev\controllers;
13
14
use yii\base\InvalidConfigException;
15
16
/**
17
 * Controller for Git.
18
 */
19
class GitController extends VcsController
20
{
21
    protected $_before = ['.gitignore'];
22
23
    /**
24
     * @var array VCS tags
25
     */
26
    protected $_tags = [];
27
28
    public function getTags()
29
    {
30
        return $this->_tags;
31
    }
32
33
    public function loadTags()
34
    {
35
        exec("git log --date=short --tags --simplify-by-decoration --pretty='format:%cd %d'", $logs);
36
        foreach ($logs as $log) {
0 ignored issues
show
Bug introduced by
The expression $logs of type null|array is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
37
            preg_match('/^([0-9-]+)\s*(\(.*\))?$/', $log, $m);
38
            $this->_tags[$this->matchTag($m[2]) ?: $this->initTag] = $m[1];
39
        }
40
    }
41
42
    /**
43
     * @var string current tag
44
     */
45
    protected $tag;
46
47
    /**
48
     * @var array VCS history
49
     */
50
    protected $_history = [];
51
52
    /**
53
     * @var array all the commits
54
     */
55
    protected $_commits = [];
56
57
    public function getCommits()
58
    {
59
        return $this->_commits;
60
    }
61
62
    public function getHistory()
63
    {
64
        return $this->_history;
65
    }
66
67
    public function addHistory($commit)
68
    {
69
        $this->tag                         = $this->matchTag($commit['tag']) ?: $this->tag;
70
        $commit['tag']                     = $this->tag;
71
        $hash                              = (string) $commit['hash'];
72
        $this->_commits[$hash]             = $commit;
73
        $this->_history[$this->tag][$hash] = $commit;
74
    }
75
76
    /**
77
     * Loads raw git history.
78
     * @throws InvalidConfigException
79
     */
80
    public function loadHistory()
81
    {
82
        if (!file_exists('.git')) {
83
            return;
84
        }
85
        exec("git log --date=short --pretty='format:%h %ad %ae %s |%d'", $logs);
86
        $this->tag = $this->lastTag;
87
        if (empty($logs)) {
88
            return;
89
        }
90
        foreach ($logs as $log) {
91
            if (!preg_match('/^(\w+) ([0-9-]+) (\S+) (.*?)\s+\| ?(\([^\(\)]+\))?$/', $log, $m)) {
92
                throw new InvalidConfigException('failed parse git log');
93
            }
94
            $this->addHistory([
95
                'hash'    => $m[1],
96
                'date'    => $m[2],
97
                'email'   => $m[3],
98
                'comment' => $m[4],
99
                'tag'     => $m[5],
100
            ]);
101
        }
102
    }
103
104
    public function matchTag($str)
105
    {
106
        preg_match('/^\((.*?)\)$/', $str, $m);
107
        $refs = explode(', ', $m[1]);
108
        foreach ($refs as $ref) {
109
            if (preg_match('/^tag: (.*)$/', $ref, $m)) {
110
                return $m[1];
111
            }
112
        }
113
114
        return false;
115
    }
116
117
    public function actionLoad()
118
    {
119
        $this->loadTags();
120
        $this->loadHistory();
121
    }
122
123
    public function actionPush()
124
    {
125
        return $this->passthru('git', 'push');
126
    }
127
128
    public function getUserName()
129
    {
130
        return trim(`git config --get user.name`);
131
    }
132
133
    public function getUserEmail()
134
    {
135
        return trim(`git config --get user.email`);
136
    }
137
138
    public function getYear()
139
    {
140
        $tags = $this->getTags();
141
        if (empty($tags)) {
142
            $date = `git log --reverse --pretty=%ai | head -n 1`;
143
        } else {
144
            $date = array_pop($tags);
145
        }
146
        $year = $date ? date('Y', strtotime($date)) : '';
147
148
        return $year;
149
    }
150
}
151