Passed
Push — master ( ae0137...9d50f2 )
by Andreas
37:09
created

midcom_services_rcs_backend_git::relative_path()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

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