aboutsummaryrefslogtreecommitdiffstats
path: root/library/kzykhys/git/src/PHPGit/Command/ShortlogCommand.php
blob: 23c66e4642389cd7da12496e4e3930addec847c8 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
<?php

namespace PHPGit\Command;

use PHPGit\Command;

/**
 * Summarize 'git log' output - `git shortlog`
 *
 * @author Kazuyuki Hayashi <hayashi@valnur.net>
 */
class ShortlogCommand extends Command
{

    /**
     * Summarize 'git log' output
     *
     * ``` php
     * $git = new PHPGit\Git();
     * $git->setRepository('/path/to/repo');
     * $shortlog = $git->shortlog();
     * ```
     *
     * ##### Output Example
     *
     * ``` php
     * [
     *     'John Doe <john@example.com>' => [
     *         0 => ['commit' => '589de67', 'date' => new \DateTime('2014-02-10 12:56:15 +0300'), 'subject' => 'Update README'],
     *         1 => ['commit' => '589de67', 'date' => new \DateTime('2014-02-15 12:56:15 +0300'), 'subject' => 'Update README'],
     *     ],
     *     //...
     * ]
     * ```
     * @param string|array|\Traversable $commits [optional] Defaults to HEAD
     *
     * @return array
     */
    public function __invoke($commits = 'HEAD')
    {
        $builder = $this->git->getProcessBuilder()
            ->add('shortlog')
            ->add('--numbered')
            ->add('--format=')
            ->add('-w256,2,2')
            ->add('-e');

        if (!is_array($commits) && !($commits instanceof \Traversable)) {
            $commits = array($commits);
        }

        foreach ($commits as $commit) {
            $builder->add($commit);
        }

        $process = $builder->getProcess();
        $process->setCommandLine(str_replace('--format=', '--format=%h|%ci|%s', $process->getCommandLine()));

        $output = $this->git->run($process);
        $lines  = $this->split($output);
        $result = array();
        $author = null;

        foreach ($lines as $line) {
            if (substr($line, 0, 1) != ' ') {
                if (preg_match('/([^<>]*? <[^<>]+>)/', $line, $matches)) {
                    $author = $matches[1];
                    $result[$author] = array();
                }
                continue;
            }

            list ($commit, $date, $subject) = explode('|', trim($line), 3);
            $result[$author][] = array(
                'commit'  => $commit,
                'date'    => new \DateTime($date),
                'subject' => $subject
            );
        }

        return $result;
    }

    /**
     * Suppress commit description and provide a commit count summary only
     *
     * ``` php
     * $git = new PHPGit\Git();
     * $git->setRepository('/path/to/repo');
     * $shortlog = $git->shortlog->summary();
     * ```
     *
     * ##### Output Example
     *
     * ``` php
     * [
     *     'John Doe <john@example.com>' => 153,
     *     //...
     * ]
     * ```
     *
     * @param string $commits [optional] Defaults to HEAD
     *
     * @return array
     */
    public function summary($commits = 'HEAD')
    {
        $builder = $this->git->getProcessBuilder()
            ->add('shortlog')
            ->add('--numbered')
            ->add('--summary')
            ->add('-e');

        if (!is_array($commits) && !($commits instanceof \Traversable)) {
            $commits = array($commits);
        }

        foreach ($commits as $commit) {
            $builder->add($commit);
        }

        $output = $this->git->run($builder->getProcess());
        $lines  = $this->split($output);
        $result = array();

        foreach ($lines as $line) {
            list ($commits, $author) = explode("\t", trim($line), 2);
            $result[$author] = (int) $commits;
        }

        return $result;
    }

}