Passed
Push — master ( fedd27...f10ad5 )
by Michiel
11:13
created

TouchTask::_touch()   F

Complexity

Conditions 16
Paths 961

Size

Total Lines 66
Code Lines 38

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 35
CRAP Score 16.0405

Importance

Changes 1
Bugs 1 Features 0
Metric Value
cc 16
eloc 38
nc 961
nop 0
dl 0
loc 66
ccs 35
cts 37
cp 0.9459
crap 16.0405
rs 1.4541
c 1
b 1
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
/**
21
 * Touch a file and/or fileset(s); corresponds to the Unix touch command.
22
 *
23
 * If the file to touch doesn't exist, an empty one is created.
24
 *
25
 * @package phing.tasks.system
26
 */
27
class TouchTask extends Task
28
{
29
    use FileListAware;
30
    use FileSetAware;
31
32
    /**
33
     * @var PhingFile $file
34
     */
35
    private $file;
36
    private $millis = -1;
37
    private $dateTime;
38
    private $fileUtils;
39
    private $mkdirs = false;
40
    private $verbose = true;
41
42
    /** @var Mapper $mapperElement */
43
    private $mapperElement;
44
45
    /**
46
     *
47
     */
48 66
    public function __construct()
49
    {
50 66
        parent::__construct();
51 66
        $this->fileUtils = new FileUtils();
52 66
    }
53
54
    /**
55
     * Sets a single source file to touch.  If the file does not exist
56
     * an empty file will be created.
57
     *
58
     * @param  PhingFile $file
59
     * @return void
60
     */
61 64
    public function setFile(PhingFile $file)
62
    {
63 64
        $this->file = $file;
64 64
    }
65
66
    /**
67
     * the new modification time of the file
68
     * in milliseconds since midnight Jan 1 1970.
69
     * Optional, default=now
70
     *
71
     * @param  $millis
72
     * @return void
73
     */
74 8
    public function setMillis($millis)
75
    {
76 8
        $this->millis = (int) $millis;
77 8
    }
78
79
    /**
80
     * the new modification time of the file
81
     * in the format MM/DD/YYYY HH:MM AM or PM;
82
     * Optional, default=now
83
     *
84
     * @param  $dateTime
85
     * @return void
86
     */
87 6
    public function setDatetime($dateTime)
88
    {
89 6
        $this->dateTime = (string) $dateTime;
90 6
        $this->setMillis(strtotime($this->dateTime));
91 6
    }
92
93
    /**
94
     * Set whether nonexistent parent directories should be created
95
     * when touching new files.
96
     *
97
     * @param boolean $mkdirs whether to create parent directories.
98
     */
99 8
    public function setMkdirs($mkdirs)
100
    {
101 8
        $this->mkdirs = $mkdirs;
102 8
    }
103
104
    /**
105
     * Set whether the touch task will report every file it creates;
106
     * defaults to <code>true</code>.
107
     *
108
     * @param boolean $verbose flag.
109
     */
110
    public function setVerbose($verbose)
111
    {
112
        $this->verbose = $verbose;
113
    }
114
115
    /**
116
     * Execute the touch operation.
117
     *
118
     * @throws BuildException
119
     * @throws IOException
120
     */
121 2
    public function createMapper()
122
    {
123 2
        if ($this->mapperElement !== null) {
124
            throw new BuildException("Cannot define more than one mapper", $this->getLocation());
125
        }
126 2
        $this->mapperElement = new Mapper($this->project);
127
128 2
        return $this->mapperElement;
129
    }
130
131 66
    protected function checkConfiguration()
132
    {
133 66
        $savedMillis = $this->millis;
134
135 66
        if ($this->file === null && count($this->filesets) === 0 && count($this->filelists) === 0) {
136
            throw new BuildException("Specify at least one source - a file, a fileset or a filelist.");
137
        }
138
139 66
        if ($this->file !== null && $this->file->exists() && $this->file->isDirectory()) {
140
            throw new BuildException("Use a fileset to touch directories.");
141
        }
142
143
        try { // try to touch file
144 66
            if ($this->dateTime !== null) {
145 6
                if ($this->millis < 0) {
146
                    throw new BuildException("Date of {$this->dateTime} results in negative milliseconds value relative to epoch (January 1, 1970, 00:00:00 GMT).");
147
                }
148
            }
149
        } catch (Exception $ex) {
150
            throw new BuildException("Error touch()ing file", $ex, $this->getLocation());
151
        }
152 66
        $this->log(
153 66
            "Setting millis to " . $savedMillis . " from datetime attribute",
154 66
            ($this->millis < 0 ? Project::MSG_DEBUG : Project::MSG_VERBOSE)
155
        );
156
157 66
        $this->millis = $savedMillis;
158 66
    }
159
160
    /**
161
     * Execute the touch operation.
162
     * @throws BuildException
163
     */
164 66
    public function main()
165
    {
166 66
        $this->checkConfiguration();
167 66
        $this->_touch();
168 65
    }
169
170
    /**
171
     * Does the actual work.
172
     */
173 66
    public function _touch()
174
    {
175 66
        if ($this->file !== null) {
176 64
            if (!$this->file->exists()) {
177 57
                $this->log(
178 57
                    "Creating " . $this->file,
179 57
                    $this->verbose ? Project::MSG_INFO : Project::MSG_VERBOSE
180
                );
181
                try { // try to create file
182 57
                    $this->file->createNewFile($this->mkdirs);
183 1
                } catch (IOException  $ioe) {
184 1
                    throw new BuildException(
185 1
                        "Error creating new file " . $this->file,
186
                        $ioe,
187 1
                        $this->getLocation()
188
                    );
189
                }
190
            }
191
        }
192
193 65
        $resetMillis = false;
194 65
        if ($this->millis < 0) {
195 59
            $resetMillis = true;
196 59
            $this->millis = Phing::currentTimeMillis();
197
        }
198
199 65
        if ($this->file !== null) {
200 63
            $this->touchFile($this->file);
201
        }
202
203 65
        $project = $this->getProject();
204 65
        foreach ($this->filesets as $fs) {
205 2
            $ds = $fs->getDirectoryScanner($project);
206 2
            $fromDir = $fs->getDir($project);
207
208 2
            $srcFiles = $ds->getIncludedFiles();
209 2
            $srcDirs = $ds->getIncludedDirectories();
210
211 2
            for ($j = 0, $_j = count($srcFiles); $j < $_j; $j++) {
212 2
                foreach ($this->getMappedFileNames((string) $srcFiles[$j]) as $fileName) {
213 2
                    $this->touchFile(new PhingFile($fromDir, $fileName));
214
                }
215
            }
216
217 2
            for ($j = 0, $_j = count($srcDirs); $j < $_j; $j++) {
218
                foreach ($this->getMappedFileNames((string) $srcDirs[$j]) as $fileName) {
219
                    $this->touchFile(new PhingFile($fromDir, $fileName));
220
                }
221
            }
222
        }
223
224
        // deal with the filelists
225 65
        foreach ($this->filelists as $fl) {
226 2
            $fromDir = $fl->getDir($this->getProject());
227
228 2
            $srcFiles = $fl->getFiles($this->getProject());
229
230 2
            for ($j = 0, $_j = count($srcFiles); $j < $_j; $j++) {
231 2
                foreach ($this->getMappedFileNames((string) $srcFiles[$j]) as $fileName) {
232 2
                    $this->touchFile(new PhingFile($fromDir, $fileName));
233
                }
234
            }
235
        }
236
237 65
        if ($resetMillis) {
238 59
            $this->millis = -1;
239
        }
240 65
    }
241
242 4
    private function getMappedFileNames($file)
243
    {
244 4
        if ($this->mapperElement !== null) {
245 2
            $mapper = $this->mapperElement->getImplementation();
246 2
            $results = $mapper->main($file);
247 2
            if ($results === null) {
0 ignored issues
show
introduced by
The condition $results === null is always false.
Loading history...
248
                return '';
249
            }
250 2
            $fileNames = $results;
251
        } else {
252 2
            $fileNames = [$file];
253
        }
254
255 4
        return $fileNames;
256
    }
257
258
    /**
259
     * @param $file
260
     * @throws BuildException
261
     */
262 65
    private function touchFile(PhingFile $file)
263
    {
264 65
        if (!$file->canWrite()) {
265
            throw new BuildException("Can not change modification date of read-only file " . (string) $file);
266
        }
267 65
        $file->setLastModified($this->millis);
268 65
    }
269
}
270