Passed
Push — master ( 4d6caf...4726e4 )
by Siad
10:49
created

ChmodTask::setVerbose()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

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

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