Passed
Push — master ( b9bc63...f1e2bc )
by Michiel
06: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
eloc 100
dl 0
loc 159
ccs 4
cts 96
cp 0.0417
rs 0
c 0
b 0
f 0
cc 31
nc 7058
nop 0
crap 876.7224

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