Task::getCommitMessage()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 0 Features 1
Metric Value
eloc 3
c 3
b 0
f 1
dl 0
loc 6
rs 10
cc 2
nc 2
nop 0
1
<?php
2
/**
3
 * mu stands for Module Object
4
 */
5
6
namespace Sunnysideup\UpgradeToSilverstripe4\Tasks;
7
8
use Sunnysideup\UpgradeToSilverstripe4\ModuleUpgrader;
9
use Sunnysideup\UpgradeToSilverstripe4\Tasks\Helpers\Git;
10
11
abstract class Task
12
{
13
    /**
14
     * Are we running in debug mode?
15
     * @var bool
16
     */
17
    protected $debug = false;
18
19
    /**
20
     * set a specific task name if needed
21
     * @var string
22
     */
23
    protected $taskName = '';
24
25
    protected $taskStep = 's99';
26
27
    /**
28
     * Array of params that define this task, holds information such as its taskName etc.
29
     * @var mixed
30
     */
31
    protected $params = [];
32
33
    /**
34
     * @var ModuleUpgrader|null the 'Manager' of all the modules responsible for holding Meta data and runtime
35
     * specific runtime arguments.
36
     */
37
    protected $mu = null;
38
39
    /**
40
     * What to write in the commit message after the task is run, only useful if hasCommitAndPush() returns true
41
     * @var string message
42
     */
43
    protected $commitMessage = '';
44
45
    /**
46
     * A static array for holding all the different Tasks that are running
47
     * @var Task[]
48
     */
49
    private static $singletons = [];
50
51
    /**
52
     * On instantiation sets the parameters and a refernece to the parent ModuleUpgrader
53
     * @param ModuleUpgrader $mu Reference to the master ModuleUpgrader
54
     * @param array  $params All parameters that define this task or are required at any stage during its execution
55
     */
56
    public function __construct($mu, $params = [])
57
    {
58
        $this->mu = $mu;
59
        $this->params = $params;
60
        $this->mu = ModuleUpgrader::create();
61
    }
62
63
    public function getTaskName()
64
    {
65
        return $this->taskName;
66
    }
67
68
    public function getTaskStepCode()
69
    {
70
        return $this->taskStep;
71
    }
72
73
    public function getTaskStep($currentStepCode = '')
74
    {
75
        $taskSteps = $this->mu()->getTaskSteps();
0 ignored issues
show
Bug introduced by
The method getTaskSteps() does not exist on Sunnysideup\UpgradeToSilverstripe4\ModuleUpgrader. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

75
        $taskSteps = $this->mu()->/** @scrutinizer ignore-call */ getTaskSteps();
Loading history...
Bug introduced by
It seems like getTaskSteps() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

75
        $taskSteps = $this->mu()->/** @scrutinizer ignore-call */ getTaskSteps();
Loading history...
76
        if (! $currentStepCode) {
77
            $currentStepCode = $this->getTaskStepCode();
78
        }
79
80
        return $taskSteps[$currentStepCode];
81
    }
82
83
    /**
84
     * Creates all the singletons and puts them in the array of singletons. Depending on if they exist already or not.
85
     * While creating the new instances it also passes a reference to the ModuleUpgrader or MU for short.
86
     *
87
     * @param  ModuleUpgrader $mu A reference to the ModuleUpgrader; to be passed on to all instantiated singletons
88
     * @param  array  $params Params that should be passed on to the given Task once it is instantiated
89
     * @return Task Returns the newly created task
90
     */
91
    public static function create($mu, $params = [])
92
    {
93
        $className = static::class;
94
        if (empty(self::$singletons[$params['taskName']])) {
95
            self::$singletons[$params['taskName']] = new $className($mu, $params);
96
        }
97
98
        return self::$singletons[$params['taskName']];
99
    }
100
101
    /**
102
     * Deletes reference to given task and removes it from list of tasks
103
     *
104
     * @param array $params array containing the 'taskName' of target task to delete
105
     */
106
    public static function deleteTask($params)
107
    {
108
        unset(self::$singletons[$params['taskName']]);
109
110
        return null;
111
    }
112
113
    public function mu()
114
    {
115
        if (! $this->mu) {
116
            $this->mu = ModuleUpgrader::create();
117
        }
118
119
        return $this->mu;
120
    }
121
122
    /**
123
     * returns title of the task at hand ...
124
     *
125
     * @return string
126
     */
127
    abstract public function getTitle();
128
129
    /**
130
     * @return string
131
     */
132
    abstract public function getDescription();
133
134
    /**
135
     * remove white space from description and add # at the end
136
     * lines are also wordwrapped
137
     *
138
     * @return string
139
     */
140
    public function getDescriptionNice()
141
    {
142
        $des = $this->getDescription();
143
        $des = trim(preg_replace('/\s+/', ' ', $des));
144
        $des = trim(wordwrap($des));
145
        return str_replace("\n", "\n" . '# ', $des);
146
    }
147
148
    /**
149
     * Executes the seperate stages of this task in chronological ordering
150
     */
151
    public function run()
152
    {
153
        $this->starter($this->params);
154
        $error = $this->runActualTask($this->params);
155
        if (is_string($error) && strlen($error) > 0) {
156
            $this->mu()->colourPrint("\n\n" . '------------------- EXIT WITH ERROR -------------------------', 'red');
0 ignored issues
show
Bug introduced by
It seems like colourPrint() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

156
            $this->mu()->/** @scrutinizer ignore-call */ colourPrint("\n\n" . '------------------- EXIT WITH ERROR -------------------------', 'red');
Loading history...
157
            $this->mu()->colourPrint($error, 'red');
158
            $this->mu()->colourPrint("\n\n" . '------------------- EXIT WITH ERROR -------------------------', 'red');
159
            die("\n\n\n---");
0 ignored issues
show
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...
160
        }
161
        $this->ender($this->params);
162
    }
163
164
    /**
165
     * runs the actual task and needs to be defined in any class that extends
166
     * this class.
167
     *
168
     * When it returns a string, we regard this to be a description of a fatal error!
169
     */
170
    abstract public function runActualTask($params = []): ?string;
171
172
    public function setCommitMessage($s)
173
    {
174
        $this->commitMessage = $s;
175
176
        return $this;
177
    }
178
179
    /**
180
     * Runs everything that should be run and begining of execution, I.e commiting everything to get or creating a
181
     * backup branch before making changes
182
     */
183
    protected function starter($params = [])
184
    {
185
        $this->setParams($params);
186
    }
187
188
    protected function setParams($params = [])
189
    {
190
        foreach ($params as $paramKey => $paramValue) {
191
            $method = 'set' . $paramKey;
192
            if (method_exists($this, $method)) {
193
                $this->{$method}($paramValue);
194
            } else {
195
                $paramKey = lcfirst($paramKey);
196
                if (property_exists($this, $paramKey)) {
197
                    $this->{$paramKey} = $paramValue;
198
                } else {
199
                    user_error(
200
                        'You are trying to set ' . $paramKey . '
201
                        but it is meaningless to this class: ' . static::class
202
                    );
203
                }
204
            }
205
        }
206
    }
207
208
    /**
209
     * Executed as the last step of a task. Used primarily for finishing off of changes made during execution of task.
210
     * I.e Making a git commit or tagging the new branch etc etc after all changes are made
211
     */
212
    protected function ender($params = [])
213
    {
214
        if ($this->hasCommitAndPush()) {
215
            $this->commitAndPush();
216
        }
217
    }
218
219
    /**
220
     * Does the task require the module changes to be committed after the task has run.
221
     * @return bool Defaults to true
222
     */
223
    abstract protected function hasCommitAndPush();
224
225
    /**
226
     * The commit message that is used for the final git commit after running this task. IF none are set it will
227
     * return a default message
228
     * @return string commit message
229
     */
230
    protected function getCommitMessage()
231
    {
232
        if (! $this->commitMessage) {
233
            $this->commitMessage = 'API:  upgrade to new version of Silverstripe - step: ' . $this->getTitle();
234
        }
235
        return $this->commitMessage;
236
    }
237
238
    /**
239
     * Adds all files to Git staging and commits them with set commit message after execution and pushes it via git
240
     */
241
    protected function commitAndPush()
242
    {
243
        if ($this->mu()->getIsModuleUpgrade()) {
0 ignored issues
show
Bug introduced by
It seems like getIsModuleUpgrade() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

243
        if ($this->mu()->/** @scrutinizer ignore-call */ getIsModuleUpgrade()) {
Loading history...
Bug introduced by
The method getIsModuleUpgrade() does not exist on Sunnysideup\UpgradeToSilverstripe4\ModuleUpgrader. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

243
        if ($this->mu()->/** @scrutinizer ignore-call */ getIsModuleUpgrade()) {
Loading history...
244
            $moduleDirs = $this->mu()->getExistingModuleDirLocations();
0 ignored issues
show
Bug introduced by
It seems like getExistingModuleDirLocations() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

244
            $moduleDirs = $this->mu()->/** @scrutinizer ignore-call */ getExistingModuleDirLocations();
Loading history...
245
        } else {
246
            $moduleDirs = [$this->mu()->getWebRootDirLocation()];
0 ignored issues
show
Bug introduced by
The method getWebRootDirLocation() does not exist on Sunnysideup\UpgradeToSilverstripe4\ModuleUpgrader. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

246
            $moduleDirs = [$this->mu()->/** @scrutinizer ignore-call */ getWebRootDirLocation()];
Loading history...
Bug introduced by
It seems like getWebRootDirLocation() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

246
            $moduleDirs = [$this->mu()->/** @scrutinizer ignore-call */ getWebRootDirLocation()];
Loading history...
247
        }
248
        foreach ($moduleDirs as $moduleDir) {
249
            return Git::inst($this->mu())
250
                ->commitAndPush(
251
                    $moduleDir,
252
                    $this->getCommitMessage(),
253
                    $this->mu()->getNameOfTempBranch()
0 ignored issues
show
Bug introduced by
It seems like getNameOfTempBranch() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

253
                    $this->mu()->/** @scrutinizer ignore-call */ getNameOfTempBranch()
Loading history...
Bug introduced by
The method getNameOfTempBranch() does not exist on Sunnysideup\UpgradeToSilverstripe4\ModuleUpgrader. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

253
                    $this->mu()->/** @scrutinizer ignore-call */ getNameOfTempBranch()
Loading history...
254
                );
255
        }
256
    }
257
258
    /**
259
     * Runs the SilverStripe made upgrader
260
     * @param  string $task
261
     * @param  string $param1
262
     * @param  string $param2
263
     * @param  string $rootDirForCommand  modules root directory
264
     * @param  string $settings
265
     * @param  string  $keyNotesLogFileLocation
266
     */
267
    protected function runSilverstripeUpgradeTask(
268
        $task,
269
        $param1 = '',
270
        $param2 = '',
271
        $rootDirForCommand = '',
272
        $settings = '',
273
        $keyNotesLogFileLocation = ''
274
    ) {
275
        if (! $rootDirForCommand) {
276
            $rootDirForCommand = $this->mu()->getWebRootDirLocation();
277
        }
278
        if (! $keyNotesLogFileLocation) {
279
            $fileName = '/upgrade_notes';
280
            if (file_exists($param1)) {
281
                $keyNotesLogFileLocation = $param1 . $fileName;
282
            } else {
283
                $keyNotesLogFileLocation = $rootDirForCommand . $fileName;
284
            }
285
        }
286
        $dir = $this->mu()->getLocationOfSSUpgradeModule();
0 ignored issues
show
Bug introduced by
It seems like getLocationOfSSUpgradeModule() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

286
        $dir = $this->mu()->/** @scrutinizer ignore-call */ getLocationOfSSUpgradeModule();
Loading history...
287
        $this->mu()->execMe(
0 ignored issues
show
Bug introduced by
It seems like execMe() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

287
        $this->mu()->/** @scrutinizer ignore-call */ execMe(
Loading history...
288
            $this->mu()->getWebRootDirLocation(),
0 ignored issues
show
Bug introduced by
It seems like $this->mu()->getWebRootDirLocation() can also be of type Sunnysideup\UpgradeToSilverstripe4\ModuleUpgrader and Sunnysideup\UpgradeToSilverstripe4\Traits\Creator and null; however, parameter $newDir of Sunnysideup\UpgradeToSil...oduleUpgrader::execMe() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

288
            /** @scrutinizer ignore-type */ $this->mu()->getWebRootDirLocation(),
Loading history...
289
            'php ' . $dir . ' ' . $task . ' ' . $param1 . ' ' . $param2 .
290
                ' --root-dir=' . $rootDirForCommand . ' --write -vvv ' . $settings,
291
            'running php upgrade ' . $task . ' see: https://github.com/silverstripe/silverstripe-upgrader',
292
            false,
293
            $keyNotesLogFileLocation
294
        );
295
    }
296
297
    protected function findModuleNames(): array
298
    {
299
        $moduleNames = [];
300
        if ($this->mu()->getIsModuleUpgrade()) {
301
            $moduleNames = [
302
                $this->mu()->getVendorName() . '/' . $this->mu()->getPackageName(),
0 ignored issues
show
Bug introduced by
It seems like getPackageName() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

302
                $this->mu()->getVendorName() . '/' . $this->mu()->/** @scrutinizer ignore-call */ getPackageName(),
Loading history...
Bug introduced by
The method getVendorName() does not exist on Sunnysideup\UpgradeToSilverstripe4\ModuleUpgrader. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

302
                $this->mu()->/** @scrutinizer ignore-call */ getVendorName() . '/' . $this->mu()->getPackageName(),
Loading history...
Bug introduced by
The method getPackageName() does not exist on Sunnysideup\UpgradeToSilverstripe4\ModuleUpgrader. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

302
                $this->mu()->getVendorName() . '/' . $this->mu()->/** @scrutinizer ignore-call */ getPackageName(),
Loading history...
Bug introduced by
It seems like getVendorName() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

302
                $this->mu()->/** @scrutinizer ignore-call */ getVendorName() . '/' . $this->mu()->getPackageName(),
Loading history...
303
            ];
304
        } else {
305
            foreach ($this->mu()->getExistingModuleDirLocations() as $location) {
306
                $moduleNames[] = $location;
307
            }
308
        }
309
        return $moduleNames;
310
    }
311
312
    protected function findModuleNameLocation(string $moduleName): string
313
    {
314
        if (strpos($moduleName, '/')) {
315
            $moduleNameLocation = 'vendor/' . $moduleName;
316
        } else {
317
            $moduleNameLocation = $moduleName;
318
        }
319
320
        return $moduleNameLocation;
321
    }
322
}
323