Passed
Push — master ( c742ba...7e2193 )
by Nils
04:49 queued 02:15
created

DnfPackageCollector::collectPackages()   B

Complexity

Conditions 7
Paths 4

Size

Total Lines 43
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 13
Bugs 0 Features 0
Metric Value
cc 7
eloc 18
c 13
b 0
f 0
nc 4
nop 0
dl 0
loc 43
rs 8.8333
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
        $result = [
28
            'packages' => $this->collectPackages(),
29
            'updatable' => $this->collectUpdatablePackages()
30
        ];
31
32
        var_dump($result);
0 ignored issues
show
Security Debugging Code introduced by
var_dump($result) looks like debug code. Are you sure you do not want to remove it?
Loading history...
33
        die;
0 ignored issues
show
Bug Best Practice introduced by
In this branch, the function will implicitly return null which is incompatible with the type-hinted return array. Consider adding a return statement or allowing null as return value.

For hinted functions/methods where all return statements with the correct type are only reachable via conditions, ?null? gets implicitly returned which may be incompatible with the hinted type. Let?s take a look at an example:

interface ReturnsInt {
    public function returnsIntHinted(): int;
}

class MyClass implements ReturnsInt {
    public function returnsIntHinted(): int
    {
        if (foo()) {
            return 123;
        }
        // here: null is implicitly returned
    }
}
Loading history...
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
34
35
        return $result;
0 ignored issues
show
Unused Code introduced by
return $result is not reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
36
    }
37
38
    private function collectPackages(): array
39
    {
40
        if (!Runner::getInstance()->commandExists('rpm')) {
41
            return [];
42
        }
43
44
        $command = 'rpm -qa --qf "%{NAME} %{VERSION}-%{RELEASE}\n"';
45
46
        $output = Runner::getInstance()->run($command)->getOutput();
47
48
        // var_dump($output);
49
50
        $packages = (explode("\n", $output));
51
52
        $packageList = [];
53
54
        foreach ($packages as $packageObject) {
55
            $parts = explode(' ', $packageObject);
56
            if (count($parts) > 0 && $parts[0]) {
57
                $packageList[$parts[0]] = $parts[1];
58
            }
59
        }
60
61
62
        // Format as JSON array
63
        // $output = "[" . preg_replace("/,\n$/", "\n", trim($output)) . "]";
64
65
        var_dump($packageList);
0 ignored issues
show
Security Debugging Code introduced by
var_dump($packageList) looks like debug code. Are you sure you do not want to remove it?
Loading history...
66
67
        return $packageList;
68
69
        // $packageList = json_decode($output, true);
70
71
        if (!is_array($packageList)) {
0 ignored issues
show
Unused Code introduced by
IfNode is not reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
72
            return [];
73
        }
74
75
        $result = [];
76
        foreach ($packageList as $package) {
77
            $result[$package['package']] = [$package['version']];
78
        }
79
80
        return $result;
81
    }
82
83
    private function collectUpdatablePackages(): array
84
    {
85
        if (!Runner::getInstance()->commandExists('dnf')) {
86
            return [];
87
        }
88
89
        $output = Runner::getInstance()->run('dnf check-update -q || true')->getOutput();
90
        $lines = explode("\n", $output);
91
92
        $packages = [];
93
94
        foreach ($lines as $line) {
95
            if (preg_match('/^(\S+)\s+(\S+)\s+(\S+)/', $line, $matches)) {
96
                $packages[$matches[1]] = [
97
                    'currentVersion' => null, // Fedora does not show current version here
98
                    'newVersion' => $matches[2]
99
                ];
100
            }
101
        }
102
103
        return $packages;
104
    }
105
}