DependSet::main()   F
last analyzed

Complexity

Conditions 31
Paths 7058

Size

Total Lines 163
Code Lines 100

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 100
dl 0
loc 163
rs 0
c 0
b 0
f 0
cc 31
nc 7058
nop 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
/**
4
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
5
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
6
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
7
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
8
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
9
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
10
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
11
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
12
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
13
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
14
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
15
 *
16
 * This software consists of voluntary contributions made by many individuals
17
 * and is licensed under the LGPL. For more information please see
18
 * <http://phing.info>.
19
 */
20
21
namespace Phing\Task\System;
22
23
use DateTime;
24
use Phing\Exception\BuildException;
25
use Phing\Io\File;
26
use Phing\Project;
27
use Phing\Type\FileList;
28
use Phing\Type\FileSet;
29
30
/**
31
 * Examines and removes out of date target files.  If any of the target files
32
 * are out of date with respect to any of the source files, all target
33
 * files are removed.  This is useful where dependencies cannot be
34
 * computed (for example, dynamically interpreted parameters or files
35
 * that need to stay in synch but are not directly linked) or where
36
 * the phing task in question could compute them but does not.
37
 *
38
 * nested arguments:
39
 * <ul>
40
 * <li>srcfileset     (fileset describing the source files to examine)
41
 * <li>srcfilelist    (filelist describing the source files to examine)
42
 * <li>targetfileset  (fileset describing the target files to examine)
43
 * <li>targetfilelist (filelist describing the target files to examine)
44
 * </ul>
45
 * At least one instance of either a fileset or filelist for both source and
46
 * target are required.
47
 * <p>
48
 * This task will examine each of the source files against each of the target
49
 * files. If any target files are out of date with respect to any of the source
50
 * files, all targets are removed. If any files named in a (src or target)
51
 * filelist do not exist, all targets are removed.
52
 * Hint: If missing files should be ignored, specify them as include patterns
53
 * in filesets, rather than using filelists.
54
 * </p><p>
55
 * This task attempts to optimize speed of dependency checking.  It will stop
56
 * after the first out of date file is found and remove all targets, rather
57
 * than exhaustively checking every source vs target combination unnecessarily.
58
 * </p>
59
 *
60
 * @author  Siad Ardroumli <[email protected]>
61
 */
62
class DependSet extends MatchingTask
63
{
64
    /**
65
     * @var FileSet[]
66
     */
67
    private $sourceFileSets = [];
68
69
    /**
70
     * @var FileList[]
71
     */
72
    private $sourceFileLists = [];
73
74
    /**
75
     * @var FileSet[]
76
     */
77
    private $targetFileSets = [];
78
79
    /**
80
     * @var FileList[]
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
    public function addSrcfilelist(FileList $fl)
100
    {
101
        $this->sourceFileLists[] = $fl;
102
    }
103
104
    /**
105
     * Add a set of target files.
106
     *
107
     * @param FileSet $fs the FileSet to add
108
     */
109
    public function addTargetfileset(FileSet $fs)
110
    {
111
        $this->targetFileSets[] = $fs;
112
    }
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
    public function main()
130
    {
131
        if ((0 === count($this->sourceFileSets)) && (0 === count($this->sourceFileLists))) {
132
            throw new BuildException(
133
                'At least one <srcfileset> or <srcfilelist>'
134
                . ' element must be set'
135
            );
136
        }
137
        if ((0 === count($this->targetFileSets)) && (0 === count($this->targetFileLists))) {
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
                    null === $oldestTarget
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
192
                    continue;
193
                }
194
195
                $allTargets[] = $dest;
196
                if ($dest->lastModified() > $now) {
197
                    $this->log(
198
                        'Warning: ' . $targetFile . ' modified in the future.',
199
                        Project::MSG_WARN
200
                    );
201
                }
202
                if (
203
                    null === $oldestTarget
204
                    || $dest->lastModified() < $oldestTargetTime
205
                ) {
206
                    $oldestTargetTime = $dest->lastModified();
207
                    $oldestTarget = $dest;
208
                }
209
            }
210
        }
211
        if (null !== $oldestTarget) {
212
            $this->log($oldestTarget . ' is oldest target file', Project::MSG_VERBOSE);
213
        } else {
214
            // no target files, then we cannot remove any target files and
215
            // skip the following tests right away
216
            $upToDate = false;
217
        }
218
        // Check targets vs source files specified via filelists:
219
        if ($upToDate) {
220
            foreach ($this->sourceFileLists as $sourceFL) {
221
                $sourceFiles = $sourceFL->getFiles($this->getProject());
222
223
                foreach ($sourceFiles as $sourceFile) {
224
                    $src = new File($sourceFL->getDir($this->getProject()), $sourceFile);
225
226
                    if ($src->lastModified() > $now) {
227
                        $this->log(
228
                            'Warning: ' . $sourceFile
229
                            . ' modified in the future.',
230
                            Project::MSG_WARN
231
                        );
232
                    }
233
                    if (!$src->exists()) {
234
                        $this->log(
235
                            $sourceFile . ' does not exist.',
236
                            Project::MSG_VERBOSE
237
                        );
238
                        $upToDate = false;
239
240
                        break 2;
241
                    }
242
                    if ($src->lastModified() > $oldestTargetTime) {
243
                        $upToDate = false;
244
                        $this->log(
245
                            $oldestTarget . ' is out of date with respect to '
246
                            . $sourceFile,
247
                            Project::MSG_VERBOSE
248
                        );
249
250
                        break 2;
251
                    }
252
                }
253
            }
254
        }
255
        // Check targets vs source files specified via filesets:
256
        if ($upToDate) {
257
            foreach ($this->sourceFileSets as $sourceFS) {
258
                $sourceDS = $sourceFS->getDirectoryScanner($this->getProject());
259
                $sourceFiles = $sourceDS->getIncludedFiles();
260
261
                foreach ($sourceFiles as $sourceFile) {
262
                    $src = new File($sourceFS->getDir($this->getProject()), $sourceFile);
263
264
                    if ($src->lastModified() > $now) {
265
                        $this->log(
266
                            'Warning: ' . $sourceFile
267
                            . ' modified in the future.',
268
                            Project::MSG_WARN
269
                        );
270
                    }
271
                    if ($src->lastModified() > $oldestTargetTime) {
272
                        $upToDate = false;
273
                        $this->log(
274
                            $oldestTarget . ' is out of date with respect to '
275
                            . $sourceFile,
276
                            Project::MSG_VERBOSE
277
                        );
278
279
                        break 2;
280
                    }
281
                }
282
            }
283
        }
284
        if (!$upToDate) {
285
            $this->log('Deleting all target files. ', Project::MSG_VERBOSE);
286
            foreach ($allTargets as $fileToRemove) {
287
                $this->log(
288
                    'Deleting file ' . $fileToRemove->getAbsolutePath(),
289
                    Project::MSG_VERBOSE
290
                );
291
                $fileToRemove->delete();
292
            }
293
        }
294
    }
295
}
296