Passed
Push — master ( e1f86a...4e1a3a )
by Siad
05:23
created

DependSet::main()   F

Complexity

Conditions 31
Paths 7058

Size

Total Lines 159
Code Lines 100

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 876.7224

Importance

Changes 0
Metric Value
cc 31
eloc 100
nc 7058
nop 0
dl 0
loc 159
ccs 4
cts 96
cp 0.0417
crap 876.7224
rs 0
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
4
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
5
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
6
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
7
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
8
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
9
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
10
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
11
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
12
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
13
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
14
 *
15
 * This software consists of voluntary contributions made by many individuals
16
 * and is licensed under the LGPL. For more information please see
17
 * <http://phing.info>.
18
 */
19
20
namespace Phing\Tasks\System;
21
22
use Phing\Exception\BuildException;
23
use Phing\Io\File;
24
use Phing\Project;
25
use Phing\Type\FileList;
26
use Phing\Type\FileSet;
27
28
/**
29
 * Examines and removes out of date target files.  If any of the target files
30
 * are out of date with respect to any of the source files, all target
31
 * files are removed.  This is useful where dependencies cannot be
32
 * computed (for example, dynamically interpreted parameters or files
33
 * that need to stay in synch but are not directly linked) or where
34
 * the phing task in question could compute them but does not.
35
 *
36
 * nested arguments:
37
 * <ul>
38
 * <li>srcfileset     (fileset describing the source files to examine)
39
 * <li>srcfilelist    (filelist describing the source files to examine)
40
 * <li>targetfileset  (fileset describing the target files to examine)
41
 * <li>targetfilelist (filelist describing the target files to examine)
42
 * </ul>
43
 * At least one instance of either a fileset or filelist for both source and
44
 * target are required.
45
 * <p>
46
 * This task will examine each of the source files against each of the target
47
 * files. If any target files are out of date with respect to any of the source
48
 * files, all targets are removed. If any files named in a (src or target)
49
 * filelist do not exist, all targets are removed.
50
 * Hint: If missing files should be ignored, specify them as include patterns
51
 * in filesets, rather than using filelists.
52
 * </p><p>
53
 * This task attempts to optimize speed of dependency checking.  It will stop
54
 * after the first out of date file is found and remove all targets, rather
55
 * than exhaustively checking every source vs target combination unnecessarily.
56
 * </p>
57
 *
58
 * @package phing.tasks.system
59
 * @author  Siad Ardroumli <[email protected]>
60
 */
61
class DependSet extends MatchingTask
62
{
63
    /**
64
     * @var FileSet[] $sourceFileSets
65
     */
66
    private $sourceFileSets = [];
67
68
    /**
69
     * @var FileList[] $sourceFileLists
70
     */
71
    private $sourceFileLists = [];
72
73
    /**
74
     * @var FileSet[] $targetFileSets
75
     */
76
    private $targetFileSets = [];
77
78
    /**
79
     * @var FileList[] $targetFileLists
80
     */
81
    private $targetFileLists = [];
82
83
    /**
84
     * Add a set of source files.
85
     *
86
     * @param FileSet $fs the FileSet to add.
87
     */
88
    public function addSrcfileset(FileSet $fs)
89
    {
90
        $this->sourceFileSets[] = $fs;
91
    }
92
93
    /**
94
     * Add a list of source files.
95
     *
96
     * @param FileList $fl the FileList to add.
97
     */
98 1
    public function addSrcfilelist(FileList $fl)
99
    {
100 1
        $this->sourceFileLists[] = $fl;
101 1
    }
102
103
    /**
104
     * Add a set of target files.
105
     *
106
     * @param FileSet $fs the FileSet to add.
107
     */
108 1
    public function addTargetfileset(FileSet $fs)
109
    {
110 1
        $this->targetFileSets[] = $fs;
111 1
    }
112
113
    /**
114
     * Add a list of target files.
115
     *
116
     * @param FileList $fl the FileList to add.
117
     */
118
    public function addTargetfilelist(FileList $fl)
119
    {
120
        $this->targetFileLists[] = $fl;
121
    }
122
123
    /**
124
     * Executes the task.
125
     *
126
     * @throws BuildException if errors occur.
127
     */
128 1
    public function main()
129
    {
130 1
        if ((count($this->sourceFileSets) === 0) && (count($this->sourceFileLists) === 0)) {
131 1
            throw new BuildException(
132
                'At least one <srcfileset> or <srcfilelist>'
133 1
                . ' element must be set'
134
            );
135
        }
136
        if ((count($this->targetFileSets) === 0) && (count($this->targetFileLists) === 0)) {
137
            throw new BuildException(
138
                'At least one <targetfileset> or'
139
                . ' <targetfilelist> element must be set'
140
            );
141
        }
142
        $now = (new \DateTime())->getTimestamp();
143
        /*
144
          We have to munge the time to allow for the filesystem time
145
          granularity.
146
        */
147
        // $now += FILE_UTILS . getFileTimestampGranularity();
148
149
        // Grab all the target files specified via filesets:
150
        $allTargets = [];
151
        $oldestTargetTime = 0;
152
        $oldestTarget = null;
153
        foreach ($this->targetFileSets as $targetFS) {
154
            if (!$targetFS->getDir($this->getProject())->exists()) {
155
                // this is the same as if it was empty, no target files found
156
                continue;
157
            }
158
            $targetDS = $targetFS->getDirectoryScanner($this->getProject());
159
            $targetFiles = $targetDS->getIncludedFiles();
160
161
            foreach ($targetFiles as $targetFile) {
162
                $dest = new File($targetFS->getDir($this->getProject()), $targetFile);
163
                $allTargets[] = $dest;
164
165
                if ($dest->lastModified() > $now) {
166
                    $this->log(
167
                        'Warning: ' . $targetFile . ' modified in the future.',
168
                        Project::MSG_WARN
169
                    );
170
                }
171
                if (
172
                    $oldestTarget === null
173
                    || $dest->lastModified() < $oldestTargetTime
174
                ) {
175
                    $oldestTargetTime = $dest->lastModified();
176
                    $oldestTarget = $dest;
177
                }
178
            }
179
        }
180
        // Grab all the target files specified via filelists:
181
        $upToDate = true;
182
        foreach ($this->targetFileLists as $targetFL) {
183
            $targetFiles = $targetFL->getFiles($this->getProject());
184
185
            foreach ($targetFiles as $targetFile) {
186
                $dest = new File($targetFL->getDir($this->getProject()), $targetFile);
187
                if (!$dest->exists()) {
188
                    $this->log($targetFile . ' does not exist.', Project::MSG_VERBOSE);
189
                    $upToDate = false;
190
                    continue;
191
                }
192
193
                $allTargets[] = $dest;
194
                if ($dest->lastModified() > $now) {
195
                    $this->log(
196
                        'Warning: ' . $targetFile . ' modified in the future.',
197
                        Project::MSG_WARN
198
                    );
199
                }
200
                if (
201
                    $oldestTarget === null
202
                    || $dest->lastModified() < $oldestTargetTime
203
                ) {
204
                    $oldestTargetTime = $dest->lastModified();
205
                    $oldestTarget = $dest;
206
                }
207
            }
208
        }
209
        if ($oldestTarget !== null) {
210
            $this->log($oldestTarget . ' is oldest target file', Project::MSG_VERBOSE);
211
        } else {
212
            // no target files, then we cannot remove any target files and
213
            // skip the following tests right away
214
            $upToDate = false;
215
        }
216
        // Check targets vs source files specified via filelists:
217
        if ($upToDate) {
218
            foreach ($this->sourceFileLists as $sourceFL) {
219
                $sourceFiles = $sourceFL->getFiles($this->getProject());
220
221
                foreach ($sourceFiles as $sourceFile) {
222
                    $src = new File($sourceFL->getDir($this->getProject()), $sourceFile);
223
224
                    if ($src->lastModified() > $now) {
225
                        $this->log(
226
                            'Warning: ' . $sourceFile
227
                            . ' modified in the future.',
228
                            Project::MSG_WARN
229
                        );
230
                    }
231
                    if (!$src->exists()) {
232
                        $this->log(
233
                            $sourceFile . ' does not exist.',
234
                            Project::MSG_VERBOSE
235
                        );
236
                        $upToDate = false;
237
                        break 2;
238
                    }
239
                    if ($src->lastModified() > $oldestTargetTime) {
240
                        $upToDate = false;
241
                        $this->log(
242
                            $oldestTarget . ' is out of date with respect to '
243
                            . $sourceFile,
244
                            Project::MSG_VERBOSE
245
                        );
246
                        break 2;
247
                    }
248
                }
249
            }
250
        }
251
        // Check targets vs source files specified via filesets:
252
        if ($upToDate) {
253
            foreach ($this->sourceFileSets as $sourceFS) {
254
                $sourceDS = $sourceFS->getDirectoryScanner($this->getProject());
255
                $sourceFiles = $sourceDS->getIncludedFiles();
256
257
                foreach ($sourceFiles as $sourceFile) {
258
                    $src = new File($sourceFS->getDir($this->getProject()), $sourceFile);
259
260
                    if ($src->lastModified() > $now) {
261
                        $this->log(
262
                            'Warning: ' . $sourceFile
263
                            . ' modified in the future.',
264
                            Project::MSG_WARN
265
                        );
266
                    }
267
                    if ($src->lastModified() > $oldestTargetTime) {
268
                        $upToDate = false;
269
                        $this->log(
270
                            $oldestTarget . ' is out of date with respect to '
271
                            . $sourceFile,
272
                            Project::MSG_VERBOSE
273
                        );
274
                        break 2;
275
                    }
276
                }
277
            }
278
        }
279
        if (!$upToDate) {
280
            $this->log('Deleting all target files. ', Project::MSG_VERBOSE);
281
            foreach ($allTargets as $fileToRemove) {
282
                $this->log(
283
                    'Deleting file ' . $fileToRemove->getAbsolutePath(),
284
                    Project::MSG_VERBOSE
285
                );
286
                $fileToRemove->delete();
287
            }
288
        }
289
    }
290
}
291