Passed
Push — master ( ee419d...7b6010 )
by Nils
02:55
created

DnfPackageCollector::collect()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 5
c 1
b 0
f 0
nc 2
nop 0
dl 0
loc 9
rs 10
1
<?php
2
3
namespace Startwind\Inventorio\Collector\Package\Dnf;
4
5
use Startwind\Inventorio\Collector\Collector;
6
use Startwind\Inventorio\Collector\OperatingSystem\OperatingSystemCollector;
7
use Startwind\Inventorio\Exec\Runner;
8
9
/**
10
 * This collector returns details about all installed DNF (RPM-based) packages.
11
 */
12
class DnfPackageCollector implements Collector
13
{
14
    protected const COLLECTION_IDENTIFIER = 'DnfPackages';
15
16
    public function getIdentifier(): string
17
    {
18
        return self::COLLECTION_IDENTIFIER;
19
    }
20
21
    public function collect(): array
22
    {
23
        if (OperatingSystemCollector::getOsFamily() !== OperatingSystemCollector::OS_FAMILY_LINUX) {
24
            return [];
25
        }
26
27
        return [
28
            'packages' => $this->collectPackages(),
29
            'updatable' => $this->collectUpdatablePackages()
30
        ];
31
    }
32
33
    private function collectPackages(): array
34
    {
35
        if (!Runner::getInstance()->commandExists('rpm')) {
36
            return [];
37
        }
38
39
        $output = Runner::getInstance()->run('rpm -qa --qf \'{"package":"%{NAME}", "version":"%{VERSION}-%{RELEASE}"},\n\'')->getOutput();
40
41
        // Format as JSON array
42
        $output = "[" . preg_replace("/,\n$/", "\n", trim($output)) . "]";
43
44
        $packageList = json_decode($output, true);
45
46
        if (!is_array($packageList)) {
47
            return [];
48
        }
49
50
        $result = [];
51
        foreach ($packageList as $package) {
52
            $result[$package['package']] = [$package['version']];
53
        }
54
55
        return $result;
56
    }
57
58
    private function collectUpdatablePackages(): array
59
    {
60
        if (!Runner::getInstance()->commandExists('dnf')) {
61
            return [];
62
        }
63
64
        $output = Runner::getInstance()->run('dnf check-update -q || true')->getOutput();
65
        $lines = explode("\n", $output);
66
67
        $packages = [];
68
69
        foreach ($lines as $line) {
70
            if (preg_match('/^(\S+)\s+(\S+)\s+(\S+)/', $line, $matches)) {
71
                $packages[$matches[1]] = [
72
                    'currentVersion' => null, // Fedora does not show current version here
73
                    'newVersion' => $matches[2]
74
                ];
75
            }
76
        }
77
78
        return $packages;
79
    }
80
}