Passed
Push — master ( b5ca42...8fe651 )
by Siad
05:05
created

ChmodTask::setQuiet()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
cc 2
eloc 3
nc 2
nop 1
dl 0
loc 5
ccs 0
cts 4
cp 0
crap 6
rs 10
c 0
b 0
f 0
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
use Phing\Exception\BuildException;
21
use Phing\Io\File;
22
use Phing\Project;
23
use Phing\Task;
24
25
/**
26
 * Task that changes the permissions on a file/directory.
27
 *
28
 * @author  Manuel Holtgrewe <[email protected]>
29
 * @author  Hans Lellelid <[email protected]>
30
 * @package phing.tasks.system
31
 */
32
class ChmodTask extends Task
33
{
34
    use DirSetAware;
35
    use FileSetAware;
36
37
    private $file;
38
39
    private $mode;
40
41
    private $quiet = false;
42
    private $failonerror = true;
43
    private $verbose = true;
44
45
    /**
46
     * This flag means 'note errors to the output, but keep going'
47
     *
48
     * @see   setQuiet()
49
     * @param $bool
50
     */
51 6
    public function setFailonerror($bool)
52
    {
53 6
        $this->failonerror = $bool;
54 6
    }
55
56
    /**
57
     * Set quiet mode, which suppresses warnings if chmod() fails.
58
     *
59
     * @see   setFailonerror()
60
     * @param $bool
61
     */
62
    public function setQuiet($bool)
63
    {
64
        $this->quiet = $bool;
65
        if ($this->quiet) {
66
            $this->failonerror = false;
67
        }
68
    }
69
70
    /**
71
     * Set verbosity, which if set to false surpresses all but an overview
72
     * of what happened.
73
     *
74
     * @param $bool
75
     */
76
    public function setVerbose(bool $bool)
77
    {
78
        $this->verbose = $bool;
79
    }
80
81
    /**
82
     * Sets a single source file to touch.  If the file does not exist
83
     * an empty file will be created.
84
     *
85
     * @param File $file
86
     */
87 6
    public function setFile(File $file)
88
    {
89 6
        $this->file = $file;
90 6
    }
91
92
    /**
93
     * @param $str
94
     */
95 14
    public function setMode($str)
96
    {
97 14
        $this->mode = $str;
98 14
    }
99
100
    /**
101
     * Execute the touch operation.
102
     *
103
     * @return void
104
     */
105 14
    public function main()
106
    {
107
        // Check Parameters
108 14
        $this->checkParams();
109 14
        $this->chmod();
110 14
    }
111
112
    /**
113
     * Ensure that correct parameters were passed in.
114
     *
115
     * @throws BuildException
116
     * @return void
117
     */
118 14
    private function checkParams()
119
    {
120 14
        if ($this->file === null && empty($this->filesets) && empty($this->dirsets)) {
121
            throw new BuildException(
122
                "Specify at least one source - a file, dirset or a fileset."
123
            );
124
        }
125
126 14
        if ($this->mode === null) {
127
            throw new BuildException("You have to specify an octal mode for chmod.");
128
        }
129
130
        // check for mode to be in the correct format
131 14
        if (!preg_match('/^([0-7]){3,4}$/', $this->mode)) {
132
            throw new BuildException("You have specified an invalid mode.");
133
        }
134 14
    }
135
136
    /**
137
     * Does the actual work.
138
     *
139
     * @return void
140
     */
141 14
    private function chmod()
142
    {
143 14
        if (strlen($this->mode) === 4) {
144 3
            $mode = octdec($this->mode);
145
        } else {
146
            // we need to prepend the 0 before converting
147 11
            $mode = octdec("0" . $this->mode);
148
        }
149
150
        // counters for non-verbose output
151 14
        $total_files = 0;
152 14
        $total_dirs = 0;
153
154
        // one file
155 14
        if ($this->file !== null) {
156 6
            $total_files = 1;
157 6
            $this->chmodFile($this->file, $mode);
0 ignored issues
show
Bug introduced by
It seems like $mode can also be of type double; however, parameter $mode of ChmodTask::chmodFile() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

157
            $this->chmodFile($this->file, /** @scrutinizer ignore-type */ $mode);
Loading history...
158
        }
159
160 14
        $this->filesets = array_merge($this->filesets, $this->dirsets);
161
162
        // filesets
163 14
        foreach ($this->filesets as $fs) {
164 8
            $ds = $fs->getDirectoryScanner($this->project);
165 8
            $fromDir = $fs->getDir($this->project);
166
167 8
            $srcFiles = $ds->getIncludedFiles();
168 8
            $srcDirs = $ds->getIncludedDirectories();
169
170 8
            $filecount = count($srcFiles);
171 8
            $total_files += $filecount;
172 8
            for ($j = 0; $j < $filecount; $j++) {
173 1
                $this->chmodFile(new File($fromDir, $srcFiles[$j]), $mode);
174
            }
175
176 8
            $dircount = count($srcDirs);
177 8
            $total_dirs += $dircount;
178 8
            for ($j = 0; $j < $dircount; $j++) {
179 7
                $this->chmodFile(new File($fromDir, $srcDirs[$j]), $mode);
180
            }
181
        }
182
183 14
        if (!$this->verbose) {
184
            $this->log('Total files changed to ' . vsprintf('%o', [$mode]) . ': ' . $total_files);
185
            $this->log('Total directories changed to ' . vsprintf('%o', [$mode]) . ': ' . $total_dirs);
186
        }
187 14
    }
188
189
    /**
190
     * Actually change the mode for the file.
191
     *
192
     * @param  File $file
193
     * @param  int $mode
194
     * @throws BuildException
195
     * @throws Exception
196
     */
197 14
    private function chmodFile(File $file, $mode)
198
    {
199 14
        if (!$file->exists()) {
200
            throw new BuildException("The file " . $file->__toString() . " does not exist");
201
        }
202
203
        try {
204 14
            $file->setMode($mode);
205 14
            if ($this->verbose) {
206 14
                $this->log("Changed file mode on '" . $file->__toString() . "' to " . vsprintf("%o", [$mode]));
207
            }
208
        } catch (Exception $e) {
209
            if ($this->failonerror) {
210
                throw $e;
211
            }
212
213
            $this->log($e->getMessage(), $this->quiet ? Project::MSG_VERBOSE : Project::MSG_WARN);
214
        }
215 14
    }
216
}
217