Completed
Push — master ( c115fe...75ea5a )
by Andreas
22:20 queued 22:20
created

midcom_services_rcs_backend_git::exec()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 1
c 0
b 0
f 0
nc 1
nop 1
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 1
rs 10
1
<?php
2
/**
3
 * @package midcom.services.rcs
4
 * @author CONTENT CONTROL https://contentcontrol.berlin
5
 * @copyright CONTENT CONTROL https://contentcontrol.berlin
6
 */
7
8
/**
9
 * @package midcom.services.rcs
10
 */
11
class midcom_services_rcs_backend_git extends midcom_services_rcs_backend
12
{
13
    /**
14
     * Save a new revision
15
     */
16 1
    public function update(string $updatemessage = '')
17
    {
18 1
        $author = midcom::get()->auth->user->id ?? 'NOBODY';
19 1
        $author .= ' <' . $author . '@' . $_SERVER['REMOTE_ADDR'] . '>';
20
21 1
        $this->exec('add ' . $this->relative_path($this->write_object()));
22 1
        $command = 'commit -q --allow-empty --allow-empty-message -m ' . escapeshellarg($updatemessage) .
23 1
            ' --author ' . escapeshellarg($author);
24 1
        $this->exec($command);
25
    }
26
27
    /**
28
     * Get a revision
29
     */
30
    public function get_revision(string $revision) : array
31
    {
32
        $filename = $this->generate_filename();
33
        $lines = $this->read_handle('show ' . $revision . ':' . $this->relative_path($filename));
34
        $mapper = new midcom_helper_exporter_xml();
35
        return $mapper->data2array(implode("\n", $lines));
36
    }
37
38 1
    protected function load_history() : array
39
    {
40 1
        $filename = $this->generate_filename();
41 1
        if (!is_readable($filename)) {
42 1
            debug_add('file ' . $filename . ' is not readable, returning empty result', MIDCOM_LOG_INFO);
43 1
            return [];
44
        }
45
46 1
        $lines = $this->read_handle('log --shortstat --format=format:"%h%n%ae%n%at%n%s" ' . $this->relative_path($filename));
47 1
        $total = count($lines);
48 1
        $revisions = [];
49
50 1
        for ($i = 0; $i < $total; $i += 6) {
51 1
            [$user, $ip] = explode('@', $lines[$i + 1], 2);
52 1
            $stat = preg_replace('/.*?\d file changed/', '', $lines[$i + 4]);
53 1
            $stat = preg_replace('/, (\d+) .+?tions?\(([\+\-])\)/', '$2$1 ', $stat);
54
55 1
            $revisions[$lines[$i]] = [
56 1
                'revision' => $lines[$i],
57 1
                'date' => $lines[$i + 2],
58
                'lines' => $stat,
59
                'user' => $user,
60
                'ip' => $ip,
61 1
                'message' => $lines[$i + 3]
62
            ];
63
        }
64
65 1
        return $revisions;
66
    }
67
68 1
    protected function generate_filename() : string
69
    {
70 1
        $root = $this->config->get_rootdir();
71 1
        $initialized = true;
72 1
        if (!file_exists($root . '/.git')) {
73 1
            if ((count(scandir($root)) > 2)) {
74
                // This is probably an old rcs dir
75
                throw new midcom_error($root . ' is not empty. Run tools/rcs2git to convert');
76
            }
77 1
            $initialized = false;
78
        }
79 1
        $filename = parent::generate_filename();
80
81 1
        if (!$initialized) {
82 1
            $this->exec('init');
83 1
            $this->exec('config user.email "midcom.rcs@localhost"');
84 1
            $this->exec('config user.name "midcom.rcs"');
85
        }
86 1
        return $filename;
87
    }
88
89 1
    protected function read_handle(string $command) : array
90
    {
91 1
        return parent::read_handle('git -C ' . $this->config->get_rootdir() . ' ' . $command);
92
    }
93
94 1
    private function exec(string $command)
95
    {
96 1
        $this->run_command('git -C ' . $this->config->get_rootdir() . ' ' . $command);
97
    }
98
99 1
    private function relative_path(string $filename) : string
100
    {
101 1
        $relative_path = substr($filename, strlen($this->config->get_rootdir()));
102 1
        return escapeshellarg(trim($relative_path, '/'));
103
    }
104
}
105