Changelog::log()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 5
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
1
<?php
2
3
namespace Robo\Task\Development;
4
5
use Robo\Task\BaseTask;
6
use Robo\Result;
7
use Robo\Contract\BuilderAwareInterface;
8
use Robo\Common\BuilderAwareTrait;
9
10
/**
11
 * Helps to manage changelog file.
12
 * Creates or updates `changelog.md` file with recent changes in current version.
13
 *
14
 * ``` php
15
 * <?php
16
 * $version = "0.1.0";
17
 * $this->taskChangelog()
18
 *  ->version($version)
19
 *  ->change("released to github")
20
 *  ->run();
21
 * ?>
22
 * ```
23
 *
24
 * Changes can be asked from Console
25
 *
26
 * ``` php
27
 * <?php
28
 * $this->taskChangelog()
29
 *  ->version($version)
30
 *  ->askForChanges()
31
 *  ->run();
32
 * ?>
33
 * ```
34
 */
35
class Changelog extends BaseTask implements BuilderAwareInterface
36
{
37
    use BuilderAwareTrait;
38
39
    /**
40
     * @var string
41
     */
42
    protected $filename;
43
44
    /**
45
     * @var array
46
     */
47
    protected $log = [];
48
49
    /**
50
     * @var string
51
     */
52
    protected $anchor = "# Changelog";
53
54
    /**
55
     * @var string
56
     */
57
    protected $version = "";
58
59
    /**
60
     * @var string
61
     */
62
    protected $body = "";
63
64
    /**
65
     * @var string
66
     */
67
    protected $header = "";
68
69
    /**
70
     * @param string $filename
71
     *
72
     * @return $this
73
     */
74
    public function filename($filename)
75
    {
76
        $this->filename = $filename;
77
        return $this;
78
    }
79
80
    /**
81
     * Sets the changelog body text.
82
     *
83
     * This method permits the raw changelog text to be set directly If this is set, $this->log changes will be ignored.
84
     *
85
     * @param string $body
86
     *
87
     * @return $this
88
     */
89
    public function setBody($body)
90
    {
91
        $this->body = $body;
92
        return $this;
93
    }
94
95
    /**
96
     * @param string $header
97
     *
98
     * @return $this
99
     */
100
    public function setHeader($header)
101
    {
102
        $this->header = $header;
103
        return $this;
104
    }
105
106
    /**
107
     * @param string $item
108
     *
109
     * @return $this
110
     */
111
    public function log($item)
112
    {
113
        $this->log[] = $item;
114
        return $this;
115
    }
116
117
    /**
118
     * @param string $anchor
119
     *
120
     * @return $this
121
     */
122
    public function anchor($anchor)
123
    {
124
        $this->anchor = $anchor;
125
        return $this;
126
    }
127
128
    /**
129
     * @param string $version
130
     *
131
     * @return $this
132
     */
133
    public function version($version)
134
    {
135
        $this->version = $version;
136
        return $this;
137
    }
138
139
    /**
140
     * @param string $filename
141
     */
142
    public function __construct($filename)
143
    {
144
        $this->filename = $filename;
145
    }
146
147
    /**
148
     * @param array $data
149
     *
150
     * @return $this
151
     */
152
    public function changes(array $data)
153
    {
154
        $this->log = array_merge($this->log, $data);
155
        return $this;
156
    }
157
158
    /**
159
     * @param string $change
160
     *
161
     * @return $this
162
     */
163
    public function change($change)
164
    {
165
        $this->log[] = $change;
166
        return $this;
167
    }
168
169
    /**
170
     * @return array
171
     */
172
    public function getChanges()
173
    {
174
        return $this->log;
175
    }
176
177
    /**
178
     * {@inheritdoc}
179
     */
180
    public function run()
181
    {
182
        if (empty($this->body)) {
183
            if (empty($this->log)) {
184
                return Result::error($this, "Changelog is empty");
185
            }
186
            $this->body = $this->generateBody();
187
        }
188
        if (empty($this->header)) {
189
            $this->header = $this->generateHeader();
190
        }
191
192
        $text = $this->header . $this->body;
193
194
        if (!file_exists($this->filename)) {
195
            $this->printTaskInfo('Creating {filename}', ['filename' => $this->filename]);
196
            $res = file_put_contents($this->filename, $this->anchor);
197
            if ($res === false) {
198
                return Result::error($this, "File {filename} cant be created", ['filename' => $this->filename]);
199
            }
200
        }
201
202
        /** @var \Robo\Result $result */
203
        // trying to append to changelog for today
204
        $result = $this->collectionBuilder()->taskReplaceInFile($this->filename)
0 ignored issues
show
Documentation Bug introduced by
The method taskReplaceInFile does not exist on object<Robo\Collection\CollectionBuilder>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
205
            ->from($this->header)
206
            ->to($text)
207
            ->run();
208
209
        if (!isset($result['replaced']) || !$result['replaced']) {
210
            $result = $this->collectionBuilder()->taskReplaceInFile($this->filename)
0 ignored issues
show
Documentation Bug introduced by
The method taskReplaceInFile does not exist on object<Robo\Collection\CollectionBuilder>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
211
                ->from($this->anchor)
212
                ->to($this->anchor . "\n\n" . $text)
213
                ->run();
214
        }
215
216
        return new Result($this, $result->getExitCode(), $result->getMessage(), $this->log);
217
    }
218
219
    /**
220
     * @return string
221
     */
222
    protected function generateBody()
223
    {
224
        $text = implode("\n", array_map([$this, 'processLogRow'], $this->log));
225
        $text .= "\n";
226
227
        return $text;
228
    }
229
230
    /**
231
     * @return string
232
     */
233
    protected function generateHeader()
234
    {
235
        return "#### {$this->version}\n\n";
236
    }
237
238
    /**
239
     * @param string $i
240
     *
241
     * @return string
242
     */
243
    public function processLogRow($i)
244
    {
245
        return "* $i *" . date('Y-m-d') . "*";
246
    }
247
}
248