Passed
Push — dependabot/composer/friendsofp... ( e63e41 )
by
unknown
13:54 queued 06:58
created

ChownTask::setGroup()   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
eloc 1
dl 0
loc 3
ccs 0
cts 2
cp 0
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
crap 2
1
<?php
2
3
/**
4
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
5
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
6
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
7
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
8
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
9
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
10
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
11
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
12
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
13
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
14
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
15
 *
16
 * This software consists of voluntary contributions made by many individuals
17
 * and is licensed under the LGPL. For more information please see
18
 * <http://phing.info>.
19
 */
20
21
namespace Phing\Task\System;
22
23
use Exception;
24
use Phing\Exception\BuildException;
25
use Phing\Io\File;
26
use Phing\Project;
27
use Phing\Task;
28
use Phing\Type\Element\DirSetAware;
29
use Phing\Type\Element\FileSetAware;
30
31
/**
32
 * Task that changes the permissions on a file/directory.
33
 *
34
 * @author  Mehmet Emre Yilmaz <[email protected]>
35
 */
36
class ChownTask extends Task
37
{
38
    use DirSetAware;
39
    use FileSetAware;
40
41
    private $file;
42
43
    private $user;
44
    private $group;
45
46
    private $quiet = false;
47
    private $failonerror = true;
48
    private $verbose = true;
49
50
    /**
51
     * This flag means 'note errors to the output, but keep going'.
52
     *
53
     * @see   setQuiet()
54
     */
55
    public function setFailonerror(bool $failOnError)
56
    {
57
        $this->failonerror = $failOnError;
58
    }
59
60
    /**
61
     * Set quiet mode, which suppresses warnings if chown() fails.
62
     *
63
     * @see   setFailonerror()
64
     */
65
    public function setQuiet(bool $quiet)
66
    {
67
        $this->quiet = $quiet;
68
        if ($this->quiet) {
69
            $this->failonerror = false;
70
        }
71
    }
72
73
    /**
74
     * Set verbosity, which if set to false surpresses all but an overview
75
     * of what happened.
76
     */
77
    public function setVerbose(bool $verbose): void
78
    {
79
        $this->verbose = $verbose;
80
    }
81
82
    /**
83
     * Sets a single source file to touch.  If the file does not exist
84
     * an empty file will be created.
85
     */
86
    public function setFile(File $file): void
87
    {
88
        $this->file = $file;
89
    }
90
91
    /**
92
     * Sets the user.
93
     */
94 1
    public function setUser(string $user): void
95
    {
96 1
        $this->user = $user;
97
    }
98
99
    /**
100
     * Sets the group.
101
     */
102
    public function setGroup(string $group): void
103
    {
104
        $this->group = $group;
105
    }
106
107
    /**
108
     * Execute the touch operation.
109
     */
110 1
    public function main()
111
    {
112
        // Check Parameters
113 1
        $this->checkParams();
114 1
        $this->chown();
115
    }
116
117
    /**
118
     * Ensure that correct parameters were passed in.
119
     *
120
     * @throws BuildException
121
     */
122 1
    private function checkParams(): void
123
    {
124 1
        if (null === $this->file && empty($this->filesets) && empty($this->dirsets)) {
125
            throw new BuildException('Specify at least one source - a file or a fileset.');
126
        }
127
128 1
        if (null === $this->user && null === $this->group) {
129
            throw new BuildException('You have to specify either an owner or a group for chown.');
130
        }
131
    }
132
133
    /**
134
     * Does the actual work.
135
     */
136 1
    private function chown(): void
137
    {
138 1
        $userElements = explode('.', $this->user);
139
140 1
        $user = $userElements[0];
141
142 1
        if (count($userElements) > 1) {
143 1
            $group = $userElements[1];
144
        } else {
145
            $group = $this->group;
146
        }
147
148
        // counters for non-verbose output
149 1
        $total_files = 0;
150 1
        $total_dirs = 0;
151
152
        // one file
153 1
        if (null !== $this->file) {
154
            $total_files = 1;
155
            $this->chownFile($this->file, $user, $group);
156
        }
157
158 1
        $this->filesets = array_merge($this->filesets, $this->dirsets);
159
160
        // filesets
161 1
        foreach ($this->filesets as $fs) {
162 1
            $ds = $fs->getDirectoryScanner($this->project);
163 1
            $fromDir = $fs->getDir($this->project);
164
165 1
            $srcFiles = $ds->getIncludedFiles();
166 1
            $srcDirs = $ds->getIncludedDirectories();
167
168 1
            $filecount = count($srcFiles);
169 1
            $total_files += $filecount;
170 1
            for ($j = 0; $j < $filecount; ++$j) {
171 1
                $this->chownFile(new File($fromDir, $srcFiles[$j]), $user, $group);
172
            }
173
174 1
            $dircount = count($srcDirs);
175 1
            $total_dirs += $dircount;
176 1
            for ($j = 0; $j < $dircount; ++$j) {
177
                $this->chownFile(new File($fromDir, $srcDirs[$j]), $user, $group);
178
            }
179
        }
180
181 1
        if (!$this->verbose) {
182
            $this->log('Total files changed to ' . $user . ($group ? '.' . $group : '') . ': ' . $total_files);
183
            $this->log('Total directories changed to ' . $user . ($group ? '.' . $group : '') . ': ' . $total_dirs);
184
        }
185
    }
186
187
    /**
188
     * Actually change the mode for the file.
189
     *
190
     * @param string $user
191
     * @param string $group
192
     *
193
     * @throws BuildException
194
     * @throws Exception
195
     */
196 1
    private function chownFile(File $file, $user, $group = ''): void
197
    {
198 1
        if (!$file->exists()) {
199
            throw new BuildException('The file ' . $file->__toString() . ' does not exist');
200
        }
201
202
        try {
203 1
            if (!empty($user)) {
204 1
                $file->setUser($user);
205
            }
206
207 1
            if (!empty($group)) {
208 1
                $file->setGroup($group);
209
            }
210
211 1
            if ($this->verbose) {
212 1
                $this->log(
213 1
                    "Changed file owner on '" . $file->__toString() . "' to " . $user . ($group ? '.' . $group : '')
214 1
                );
215
            }
216
        } catch (Exception $e) {
217
            if ($this->failonerror) {
218
                throw $e;
219
            }
220
221
            $this->log($e->getMessage(), $this->quiet ? Project::MSG_VERBOSE : Project::MSG_WARN);
222
        }
223
    }
224
}
225