Completed
Push — master ( a670ca...f3dfc7 )
by Siad
13:36
created

MoveTask::doWork()   D

Complexity

Conditions 21
Paths 96

Size

Total Lines 103
Code Lines 67

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 37
CRAP Score 54.1182

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 21
eloc 67
c 1
b 0
f 0
nc 96
nop 0
dl 0
loc 103
ccs 37
cts 64
cp 0.578
crap 54.1182
rs 4.1666

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
 * Moves a file or directory to a new file or directory.
22
 *
23
 * By default, the destination file is overwritten if it
24
 * already exists.  When overwrite is turned off, then files
25
 * are only moved if the source file is newer than the
26
 * destination file, or when the destination file does not
27
 * exist.
28
 *
29
 * Source files and directories are only deleted when the file or
30
 * directory has been copied to the destination successfully.
31
 *
32
 * @package phing.tasks.system
33
 */
34
class MoveTask extends CopyTask
35
{
36 5
    public function __construct()
37
    {
38 5
        parent::__construct();
39 5
        $this->overwrite = true;
40 5
    }
41
42
    /**
43
     * Validates attributes coming in from XML
44
     *
45
     * @return void
46
     *
47
     * @throws BuildException
48
     */
49 5
    protected function validateAttributes()
50
    {
51 5
        if ($this->file !== null && $this->file->isDirectory()) {
52
            if (
53 1
                ($this->destFile !== null
54 1
                && $this->destDir !== null)
55 1
                || ($this->destFile === null
56
                && $this->destDir === null)
57
            ) {
58
                throw new BuildException("One and only one of tofile and todir must be set.");
59
            }
60
61 1
            if ($this->destFile === null) {
62
                $this->destFile = new PhingFile($this->destDir, $this->file->getName());
63
            }
64
65 1
            if ($this->destDir === null) {
66 1
                $this->destDir = $this->destFile->getParentFile();
67
            }
68
69 1
            $this->completeDirMap[$this->file->getAbsolutePath()] = $this->destFile->getAbsolutePath();
70
71 1
            $this->file = null;
72
        } else {
73 4
            parent::validateAttributes();
74
        }
75 5
    }
76
77 5
    protected function doWork()
78
    {
79 5
        if (count($this->completeDirMap) > 0) {
80 1
            foreach ($this->completeDirMap as $from => $to) {
81 1
                $f = new PhingFile($from);
82 1
                $d = new PhingFile($to);
83
84
                try { // try to rename
85 1
                    $this->log("Attempting to rename $from to $to", $this->verbosity);
86 1
                    if (!empty($this->filterChains)) {
87
                        $this->fileUtils->copyFile(
88
                            $f,
89
                            $d,
90
                            $this->getProject(),
91
                            $this->overwrite,
92
                            $this->preserveLMT,
93
                            $this->filterChains,
94
                            $this->mode,
95
                            $this->preservePermissions
96
                        );
97
                        $f->delete(true);
98
                    } else {
99 1
                        $this->fileUtils->renameFile($f, $d, $this->overwrite);
100
                    }
101
                } catch (IOException $ioe) {
102
                    $this->logError("Failed to rename $from to $to: " . $ioe->getMessage());
103
                }
104
            }
105
        }
106
107 5
        $copyMapSize = count($this->fileCopyMap);
108 5
        if ($copyMapSize > 0) {
109
            // files to move
110 3
            $this->log("Moving $copyMapSize files to " . $this->destDir->getAbsolutePath());
111
112 3
            foreach ($this->fileCopyMap as $from => $to) {
113 3
                if ($from == $to) {
114
                    $this->log("Skipping self-move of $from", $this->verbosity);
115
                    continue;
116
                }
117
118 3
                $f = new PhingFile($from);
119 3
                $d = new PhingFile($to);
120
121
                try { // try to move
122 3
                    $this->log("Moving $from to $to", $this->verbosity);
123
124 3
                    $this->fileUtils->copyFile(
125 3
                        $f,
126 3
                        $d,
127 3
                        $this->getProject(),
128 3
                        $this->overwrite,
129 3
                        $this->preserveLMT,
130 3
                        $this->filterChains,
131 3
                        $this->mode,
132 3
                        $this->preservePermissions
133
                    );
134
135 3
                    $f->delete();
136
                } catch (IOException $ioe) {
137
                    $this->logError("Failed to move $from to $to: " . $ioe->getMessage(), $this->getLocation());
138
                }
139
            } // foreach fileCopyMap
140
        } // if copyMapSize
141
142
        // handle empty dirs if appropriate
143 5
        if ($this->includeEmpty) {
144 5
            $count = 0;
145 5
            foreach ($this->dirCopyMap as $srcDir => $destDir) {
146
                $d = new PhingFile((string) $destDir);
147
                if (!$d->exists()) {
148
                    if (!$d->mkdirs()) {
149
                        $this->logError("Unable to create directory " . $d->getAbsolutePath());
150
                    } else {
151
                        $count++;
152
                    }
153
                }
154
            }
155 5
            if ($count > 0) {
156
                $this->log(
157
                    "moved $count empty director" . ($count == 1 ? "y" : "ies") . " to " . $this->destDir->getAbsolutePath(
158
                    )
159
                );
160
            }
161
        }
162
163 5
        if (count($this->filesets) > 0) {
164
            // process filesets
165 1
            foreach ($this->filesets as $fs) {
166 1
                $dir = $fs->getDir($this->project);
167 1
                if ($this->okToDelete($dir)) {
168 1
                    $this->deleteDir($dir);
169
                }
170
            }
171
        }
172
173 5
        $dirsets = $this->getDirSets();
174 5
        if (count($dirsets) > 0) {
175
            // process dirsets
176
            foreach ($dirsets as $ds) {
177
                $dir = $ds->getDir($this->project);
178
                if ($this->okToDelete($dir)) {
179
                    $this->deleteDir($dir);
180
                }
181
            }
182
        }
183 5
    }
184
185
    /**
186
     * Its only ok to delete a dir tree if there are no files in it.
187
     *
188
     * @param $d
189
     *
190
     * @throws IOException
191
     *
192
     * @return bool
193
     */
194 1
    private function okToDelete(PhingFile $d)
195
    {
196 1
        $list = $d->listDir();
197 1
        if ($list === null) {
198
            return false; // maybe io error?
199
        }
200
201 1
        foreach ($list as $s) {
202 1
            $f = new PhingFile($d, $s);
203 1
            if ($f->isDirectory()) {
204 1
                if (!$this->okToDelete($f)) {
205
                    return false;
206
                }
207
            } else {
208
                // found a file
209
                return false;
210
            }
211
        }
212
213 1
        return true;
214
    }
215
216
    /**
217
     * Go and delete the directory tree.
218
     *
219
     * @param $d
220
     *
221
     * @throws BuildException
222
     * @throws IOException
223
     */
224 1
    private function deleteDir(PhingFile $d)
225
    {
226 1
        $list = $d->listDir();
227 1
        if ($list === null) {
228
            return; // on an io error list() can return null
229
        }
230
231 1
        foreach ($list as $fname) {
232 1
            $f = new PhingFile($d, $fname);
233 1
            if ($f->isDirectory()) {
234 1
                $this->deleteDir($f);
235
            } else {
236
                throw new BuildException("UNEXPECTED ERROR - The file " . $f->getAbsolutePath() . " should not exist!");
237
            }
238
        }
239
240 1
        $this->log("Deleting directory " . $d->getPath(), $this->verbosity);
241
        try {
242 1
            $d->delete();
243
        } catch (Exception $e) {
244
            $this->logError("Unable to delete directory " . $d->__toString() . ": " . $e->getMessage());
245
        }
246 1
    }
247
}
248