Passed
Push — master ( ba0945...7a8c26 )
by Stephen
57s queued 11s
created

Changelog   A

Complexity

Total Complexity 11

Size/Duplication

Total Lines 113
Duplicated Lines 0 %

Importance

Changes 4
Bugs 0 Features 0
Metric Value
eloc 37
c 4
b 0
f 0
dl 0
loc 113
rs 10
wmc 11

4 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 3 1
A changelog() 0 33 6
A versionChanges() 0 12 2
A versions() 0 22 2
1
<?php
2
3
namespace Sfneal\Helpers\Laravel\Support;
4
5
use ErrorException;
6
use Illuminate\Support\Facades\Cache;
7
8
class Changelog
9
{
10
    // todo: add ability to replace package names (user/package) with github links
11
12
    /**
13
     * @var string
14
     */
15
    private $path;
16
17
    /**
18
     * Changelog constructor.
19
     *
20
     * @param string|null $path
21
     */
22
    public function __construct(string $path = null)
23
    {
24
        $this->path = $path ?? config('app-info.changelog_path');
25
    }
26
27
    /**
28
     * Read the application's changelog & return an array of changes.
29
     *
30
     * @return array
31
     */
32
    public function changelog(): array
33
    {
34
        return Cache::rememberForever((new CacheKey("changelog:$this->path", 'changelog'))->execute(), function () {
35
            // Read the changelog
36
            $file_lines = file($this->path);
37
            $changes = [];
38
39
            for ($row = 0; $row < count($file_lines); $row++) {
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
40
                // Check if line starts with 'version'
41
                if (substr(strtolower($file_lines[$row]), 0, strlen('version')) == 'version') {
42
                    $version_date = explode(', ', $file_lines[$row]);
43
44
                    // Extract version and date
45
                    $date = $version_date[1];
46
                    $version = explode(' ', $version_date[0])[1];
47
                    $changes[$version] = ['date' => trim($date), 'changes' => []];
48
49
                    // Skip ahead two lines to skip sep line
50
                    $row += 2;
51
52
                    // Keep iterating over rows until we get to a blank line
53
                    while ($row < count($file_lines) && strlen(trim($file_lines[$row])) > 1) {
54
                        if (substr(trim($file_lines[$row]), 0, 1) == '-') {
55
                            $changes[$version]['changes'][] = str_replace('- ', '', trim($file_lines[$row]));
56
                            $row++;
57
                        } else {
58
                            break;
59
                        }
60
                    }
61
                }
62
            }
63
64
            return $changes;
65
        });
66
    }
67
68
    /**
69
     * Retrieve an array of changes made to a particular application version.
70
     *
71
     * @param string|null $version
72
     * @return array|null
73
     */
74
    public function versionChanges(string $version): ?array
75
    {
76
        return Cache::rememberForever(
77
            // Cache key
78
            (new CacheKey("changelog:$this->path", $version))->execute(),
79
80
            // Value to cache
81
            function () use ($version) {
82
                try {
83
                    return $this->changelog()[$version];
84
                } catch (ErrorException $exception) {
85
                    return null;
86
                }
87
            }
88
        );
89
    }
90
91
    /**
92
     * Retrieve an array of the version history.
93
     *
94
     *  - optionally include the release date in the array values
95
     *
96
     * @param bool $releaseDates
97
     * @return array
98
     */
99
    public function versions(bool $releaseDates = false): array
100
    {
101
        // Flat array of versions
102
        $versions = array_keys($this->changelog());
103
104
        // Return an array of version keys & release date values
105
        if ($releaseDates) {
106
            // todo: optimize this
107
            return array_combine(
108
                $versions,
109
                array_map(
110
                    function ($array) {
111
                        return $array['date'];
112
                    },
113
                    array_values($this->changelog())
114
                )
115
            );
116
        }
117
118
        // Return a array of versions
119
        else {
120
            return $versions;
121
        }
122
    }
123
}
124