Passed
Push — main ( 753ff6...d2ec7d )
by Siad
06:31
created

ReflexiveTask::main()   C

Complexity

Conditions 12
Paths 256

Size

Total Lines 69
Code Lines 41

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 134.9558

Importance

Changes 0
Metric Value
eloc 41
dl 0
loc 69
ccs 2
cts 39
cp 0.0513
rs 5.4333
c 0
b 0
f 0
cc 12
nc 256
nop 0
crap 134.9558

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 Exception;
23
use Phing\Exception\BuildException;
24
use Phing\Exception\NullPointerException;
25
use Phing\Io\File;
26
use Phing\Io\FileReader;
27
use Phing\Io\FileUtils;
28
use Phing\Io\FileWriter;
29
use Phing\Io\IOException;
30
use Phing\Project;
31
use Phing\Task;
32
use Phing\Type\Element\FileSetAware;
33
use Phing\Type\Element\FilterChainAware;
34
35
/**
36
 * This task is for using filter chains to make changes to files and overwrite the original files.
37
 *
38
 * This task was created to serve the need for "cleanup" tasks -- e.g. a ReplaceRegexp task or strip task
39
 * being used to modify files and then overwrite the modified files.  In many (most?) cases you probably
40
 * should just use a copy task  to preserve the original source files, but this task supports situations
41
 * where there is no src vs. build directory, and modifying source files is actually desired.
42
 *
43
 * <code>
44
 *    <reflexive>
45
 *        <fileset dir=".">
46
 *            <include pattern="*.html">
47
 *        </fileset>
48
 *        <filterchain>
49
 *            <replaceregexp>
50
 *                <regexp pattern="\n\r" replace="\n"/>
51
 *            </replaceregexp>
52
 *        </filterchain>
53
 *    </reflexive>
54
 * </code>
55
 *
56
 * @author Hans Lellelid <[email protected]>
57
 *
58
 */
59
class ReflexiveTask extends Task
60
{
61
    use FileSetAware;
62
    use FilterChainAware;
63
64
    /**
65
     * Single file to process.
66
     * @var File
67
     */
68
    private $file;
69
70
    /**
71
     * Alias for setFrom()
72
     *
73
     */
74 2
    public function setFile(File $f)
75
    {
76 2
        $this->file = $f;
77 2
    }
78
79
    /**
80
     * Append the file(s).
81
     * @throws IOException|NullPointerException
82
     */
83 3
    public function main()
84
    {
85 3
        $this->validateAttributes();
86
87
        // compile a list of all files to modify, both file attrib and fileset elements
88
        // can be used.
89
90
        $files = [];
91
92
        if ($this->file !== null) {
93
            $files[] = $this->file;
94
        }
95
96
        if (!empty($this->filesets)) {
97
            foreach ($this->filesets as $fs) {
98
                try {
99
                    $ds = $fs->getDirectoryScanner($this->project);
100
                    $filenames = $ds->getIncludedFiles(); // get included filenames
101
                    $dir = $fs->getDir($this->project);
102
                    foreach ($filenames as $fname) {
103
                        $files[] = new File($dir, $fname);
104
                    }
105
                } catch (BuildException $be) {
106
                    $this->log($be->getMessage(), Project::MSG_WARN);
107
                }
108
            }
109
        }
110
111
        $this->log("Applying reflexive processing to " . count($files) . " files.");
112
113
        // These "slots" allow filters to retrieve information about the currently-being-process files
114
        $slot = $this->getRegisterSlot("currentFile");
115
        $basenameSlot = $this->getRegisterSlot("currentFile.basename");
116
117
        foreach ($files as $file) {
118
            // set the register slots
119
120
            $slot->setValue($file->getPath());
121
            $basenameSlot->setValue($file->getName());
122
123
            // 1) read contents of file, pulling through any filters
124
            $in = null;
0 ignored issues
show
Unused Code introduced by
The assignment to $in is dead and can be removed.
Loading history...
125
            $out = null;
0 ignored issues
show
Unused Code introduced by
The assignment to $out is dead and can be removed.
Loading history...
126
            $contents = "";
127
128
            try {
129
                $in = FileUtils::getChainedReader(new FileReader($file), $this->filterChains, $this->project);
130
                while (-1 !== ($buffer = $in->read())) {
131
                    $contents .= $buffer;
132
                }
133
                $in->close();
134
            } catch (Exception $e) {
135
                if ($in) {
136
                    $in->close();
137
                }
138
                $this->log("Error reading file: " . $e->getMessage(), Project::MSG_WARN);
139
            }
140
141
            try {
142
                // now create a FileWriter w/ the same file, and write to the file
143
                $out = new FileWriter($file);
144
                $out->write($contents);
145
                $out->close();
146
                $this->log("Applying reflexive processing to " . $file->getPath(), Project::MSG_VERBOSE);
147
            } catch (Exception $e) {
148
                if ($out) {
149
                    $out->close();
150
                }
151
                $this->log("Error writing file back: " . $e->getMessage(), Project::MSG_WARN);
152
            }
153
        }
154
    }
155
156
    /**
157
     * Validate task attributes.
158
     * @throws IOException
159
     */
160 3
    private function validateAttributes(): void
161
    {
162 3
        if ($this->file === null && empty($this->filesets)) {
163 1
            throw new BuildException('You must specify a file or fileset(s) for the <reflexive> task.');
164
        }
165
166 2
        if ($this->file->isDirectory()) {
167 1
            throw new BuildException('File cannot be a directory.');
168
        }
169
170 1
        if (empty($this->filterChains)) {
171 1
            throw new BuildException('You must specify a filterchain for the <reflexive> task.');
172
        }
173
    }
174
}
175