Passed
Push — master ( e5c614...6595be )
by Siad
13:10
created

ImportTask::setFile()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 1
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 1
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
 * Imports another build file into the current project.
22
 *
23
 * Targets and properties of the imported file can be overrridden
24
 * by targets and properties of the same name declared in the importing file.
25
 *
26
 * The imported file will have a new synthetic property of
27
 * "phing.file.<projectname>" declared which gives the full path to the
28
 * imported file. Additionally each target in the imported file will be
29
 * declared twice: once with the normal name and once with "<projectname>."
30
 * prepended. The "<projectname>.<targetname>" synthetic targets allow the
31
 * importing file a mechanism to call the imported files targets as
32
 * dependencies or via the <phing> or <phingcall> task mechanisms.
33
 *
34
 * @author  Bryan Davis <[email protected]>
35
 * @package phing.tasks.system
36
 */
37
class ImportTask extends Task
38
{
39
    use ResourceAware;
40
41
    /**
42
     * @var FileSystem
43
     */
44
    protected $fs;
45
46
    /**
47
     * @var PhingFile
48
     */
49
    protected $file;
50
51
    /**
52
     * @var bool
53
     */
54
    protected $optional = false;
55
56
    /**
57
     * @var string
58
     */
59
    private $targetPrefix;
60
61
    /**
62
     * @var string
63
     */
64
    private $prefixSeparator = '.';
65
66
    /**
67
     * Initialize task.
68
     *
69
     * @return void
70
     */
71 100
    public function init()
72
    {
73 100
        $this->fs = FileSystem::getFileSystem();
74 100
    }
75
76
    /**
77
     * Set the file to import.
78
     *
79
     * @param  string $f Path to file
80
     * @return void
81
     */
82 100
    public function setFile($f)
83
    {
84 100
        $this->file = $f;
0 ignored issues
show
Documentation Bug introduced by
It seems like $f of type string is incompatible with the declared type PhingFile of property $file.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
85 100
    }
86
87
    /**
88
     * The prefix to use when prefixing the imported target names.
89
     *
90
     * @param string $prefix
91
     */
92
    public function setAs(string $prefix)
93
    {
94
        $this->targetPrefix = $prefix;
95
    }
96
97
    /**
98
     * The separator to use between prefix and target name, default is
99
     * ".".
100
     *
101
     * @param string $s
102
     */
103
    public function setPrefixSeparator(string $s)
104
    {
105
        $this->prefixSeparator = $s;
106
    }
107
108
    /**
109
     * Is this include optional?
110
     *
111
     * @param  bool $opt If true, do not stop the build if the file does not
112
     *                   exist
113
     * @return void
114
     */
115 1
    public function setOptional($opt)
116
    {
117 1
        $this->optional = $opt;
118 1
    }
119
120
    /**
121
     * Parse a Phing build file and copy the properties, tasks, data types and
122
     * targets it defines into the current project.
123
     *
124
     * @throws BuildException
125
     * @return void
126
     */
127 100
    public function main()
128
    {
129 100
        if ($this->file === null && count($this->filesets) === 0) {
130
            throw new BuildException(
131
                'import requires file attribute or at least one nested fileset'
132
            );
133
        }
134 100
        if ($this->getOwningTarget() === null || $this->getOwningTarget()->getName() !== '') {
135 1
            throw new BuildException('import only allowed as a top-level task');
136
        }
137 100
        if ($this->getLocation() === null || $this->getLocation()->getFileName() === null) {
138
            throw new BuildException("Unable to get location of import task");
139
        }
140
141
        // Single file.
142 100
        if ($this->file !== null) {
143 100
            $file = new PhingFile($this->file);
144 100
            if (!$file->isAbsolute()) {
145 100
                $file = new PhingFile($this->project->getBasedir(), $this->file);
146
            }
147 100
            if (!$file->exists()) {
148
                $msg = "Unable to find build file: {$file->getPath()}";
149
                if ($this->optional) {
150
                    $this->log($msg . '... skipped');
151
                    return;
152
                }
153
154
                throw new BuildException($msg);
155
            }
156 100
            $this->importFile($file);
157
        }
158
159
        // Filesets.
160 100
        $total_files = 0;
161 100
        $total_dirs = 0;
162
        /** @var FileSet $fs */
163 100
        foreach ($this->filesets as $fs) {
164 1
            $ds = $fs->getDirectoryScanner($this->project);
165 1
            $fromDir = $fs->getDir($this->project);
166
167 1
            $srcFiles = $ds->getIncludedFiles();
168 1
            $srcDirs = $ds->getIncludedDirectories();
169
170 1
            $filecount = count($srcFiles);
171 1
            $total_files += $filecount;
172 1
            for ($j = 0; $j < $filecount; $j++) {
173 1
                $this->importFile(new PhingFile($fromDir, $srcFiles[$j]));
174
            }
175
176 1
            $dircount = count($srcDirs);
177 1
            $total_dirs += $dircount;
178 1
            for ($j = 0; $j < $dircount; $j++) {
179
                $this->importFile(new PhingFile($fromDir, $srcDirs[$j]));
180
            }
181
        }
182 100
    }
183
184
    /**
185
     * Parse a Phing build file and copy the properties, tasks, data types and
186
     * targets it defines into the current project.
187
     *
188
     * @throws BuildException
189
     * @return void
190
     */
191 100
    protected function importFile(PhingFile $file)
192
    {
193
        /** @var PhingXMLContext $ctx */
194 100
        $ctx = $this->project->getReference(ProjectConfigurator::PARSING_CONTEXT_REFERENCE);
195 100
        $cfg = $ctx->getConfigurator();
0 ignored issues
show
Unused Code introduced by
The assignment to $cfg is dead and can be removed.
Loading history...
Bug introduced by
Are you sure the assignment to $cfg is correct as $ctx->getConfigurator() targeting PhingXMLContext::getConfigurator() seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
196
        // Import xml file into current project scope
197
        // Since this is delayed until after the importing file has been
198
        // processed, the properties and targets of this new file may not take
199
        // effect if they have alreday been defined in the outer scope.
200 100
        $this->log(
201 100
            "Importing file {$file->getAbsolutePath()} from "
202 100
            . $this->getLocation()->getFileName(),
203 100
            Project::MSG_VERBOSE
204
        );
205 100
        ProjectConfigurator::configureProject($this->project, $file);
206 100
    }
207
208
    /**
209
     * Whether the task is in include (as opposed to import) mode.
210
     *
211
     * <p>In include mode included targets are only known by their
212
     * prefixed names and their depends lists get rewritten so that
213
     * all dependencies get the prefix as well.</p>
214
     *
215
     * <p>In import mode imported targets are known by an adorned as
216
     * well as a prefixed name and the unadorned target may be
217
     * overwritten in the importing build file.  The depends list of
218
     * the imported targets is not modified at all.</p>
219
     *
220
     * @return bool
221
     */
222
    protected function isInIncludeMode(): bool
223
    {
224
        return 'include' === $this->getTaskType();
225
    }
226
}
227