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

PhingTask   F

Complexity

Total Complexity 102

Size/Duplication

Total Lines 724
Duplicated Lines 0 %

Test Coverage

Coverage 76.49%

Importance

Changes 4
Bugs 0 Features 0
Metric Value
eloc 270
dl 0
loc 724
ccs 218
cts 285
cp 0.7649
rs 2
c 4
b 0
f 0
wmc 102

22 Methods

Rating   Name   Duplication   Size   Complexity  
A setHaltOnFailure() 0 3 1
B main() 0 47 8
B reinit() 0 37 9
A init() 0 5 1
A setUseNativeBasedir() 0 3 1
A __construct() 0 6 2
A setPhingFile() 0 6 1
A getNewProject() 0 6 2
B addReferences() 0 45 9
A setDir() 0 3 1
A overrideProperties() 0 20 6
A addReference() 0 3 1
A copyReference() 0 27 5
A setTarget() 0 7 2
F initializeProject() 0 56 10
A setInheritAll() 0 3 1
A createProperty() 0 9 1
A setOutput() 0 3 1
A setInheritRefs() 0 3 1
B addAlmostAll() 0 17 9
F processFile() 0 141 29
A setBuildfile() 0 3 1

How to fix   Complexity   

Complex Class

Complex classes like PhingTask often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use PhingTask, and based on these observations, apply Extract Interface, too.

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 invokes phing on another build file.
22
 *
23
 * Use this task, for example, if you have nested buildfiles in your project. Unlike
24
 * AntTask, PhingTask can even support filesets:
25
 *
26
 * <pre>
27
 *   <phing>
28
 *    <fileset dir="${srcdir}">
29
 *      <include name="** /build.xml" /> <!-- space added after ** is there because of PHP comment syntax -->
30
 *      <exclude name="build.xml" />
31
 *    </fileset>
32
 *   </phing>
33
 * </pre>
34
 *
35
 * @author  Hans Lellelid <[email protected]>
36
 * @package phing.tasks.system
37
 */
38
class PhingTask extends Task
39
{
40
    use FileSetAware;
41
42
    /**
43
     * the basedir where is executed the build file
44
     * @var PhingFile
45
     */
46
    private $dir;
47
48
    /**
49
     * build.xml (can be absolute) in this case dir will be ignored
50
     */
51
    private $phingFile;
52
53
    /**
54
     * the target to call if any
55
     * @var Target
56
     */
57
    protected $newTarget;
58
59
    /**
60
     * should we inherit properties from the parent ?
61
     */
62
    private $inheritAll = true;
63
64
    /**
65
     * should we inherit references from the parent ?
66
     */
67
    private $inheritRefs = false;
68
69
    /**
70
     * the properties to pass to the new project
71
     */
72
    private $properties = [];
73
74
    /**
75
     * the references to pass to the new project
76
     */
77
    private $references = [];
78
79
    /**
80
     * The temporary project created to run the build file
81
     *
82
     * @var Project
83
     */
84
    private $newProject;
85
86
    /**
87
     * Fail the build process when the called build fails?
88
     */
89
    private $haltOnFailure = false;
90
91
    /**
92
     * Whether the basedir of the new project should be the same one
93
     * as it would be when running the build file directly -
94
     * independent of dir and/or inheritAll settings.
95
     */
96
    private $useNativeBasedir = false;
97
98
    /**
99
     * @var OutputStream
100
     */
101
    private $out;
102
103
    /** @var string */
104
    private $output;
105
106
    /**
107
     * @var array
108
     */
109
    private $locals;
110
111 34
    public function __construct(Task $owner = null)
112
    {
113 34
        if ($owner !== null) {
114 11
            $this->bindToOwner($owner);
115
        }
116 34
        parent::__construct();
117 34
    }
118
119
    /**
120
     *  If true, abort the build process if there is a problem with or in the target build file.
121
     *  Defaults to false.
122
     *
123
     * @param bool $hof new value
124
     */
125 15
    public function setHaltOnFailure($hof)
126
    {
127 15
        $this->haltOnFailure = (bool) $hof;
128 15
    }
129
130
    /**
131
     * Whether the basedir of the new project should be the same one
132
     * as it would be when running the build file directly -
133
     * independent of dir and/or inheritAll settings.
134
     *
135
     * @param bool $b
136
     */
137
    public function setUseNativeBasedir(bool $b)
138
    {
139
        $this->useNativeBasedir = $b;
140
    }
141
142
    /**
143
     * Creates a Project instance for the project to call.
144
     *
145
     * @return void
146
     */
147 34
    public function init()
148
    {
149 34
        $this->newProject = $this->getProject()->createSubProject();
150 34
        $tdf = $this->project->getTaskDefinitions();
151 34
        $this->newProject->addTaskDefinition("property", $tdf["property"]);
152 34
    }
153
154
    /**
155
     * Called in execute or createProperty if newProject is null.
156
     *
157
     * <p>This can happen if the same instance of this task is run
158
     * twice as newProject is set to null at the end of execute (to
159
     * save memory and help the GC).</p>
160
     *
161
     * <p>Sets all properties that have been defined as nested
162
     * property elements.</p>
163
     */
164 4
    private function reinit()
165
    {
166 4
        $this->init();
167
168 4
        $count = count($this->properties);
169 4
        for ($i = 0; $i < $count; $i++) {
170
            /**
171
             * @var PropertyTask $p
172
             */
173 4
            $p = $this->properties[$i] ?? null;
174 4
            if ($p !== null) {
175
                /** @var PropertyTask $newP */
176 4
                $newP = $this->newProject->createTask("property");
177 4
                $newP->setName($p->getName());
178 4
                if ($p->getValue() !== null) {
179 4
                    $newP->setValue($p->getValue());
180
                }
181 4
                if ($p->getFile() !== null) {
182
                    $newP->setFile($p->getFile());
183
                }
184 4
                if ($p->getPrefix() !== null) {
185
                    $newP->setPrefix($p->getPrefix());
186
                }
187 4
                if ($p->getRefid() !== null) {
188
                    $newP->setRefid($p->getRefid());
189
                }
190 4
                if ($p->getEnvironment() !== null) {
191
                    $newP->setEnvironment($p->getEnvironment());
192
                }
193 4
                if ($p->getUserProperty() !== null) {
194 4
                    $newP->setUserProperty($p->getUserProperty());
195
                }
196 4
                $newP->setOverride($p->getOverride());
197 4
                $newP->setLogoutput($p->getLogoutput());
198 4
                $newP->setQuiet($p->getQuiet());
199
200 4
                $this->properties[$i] = $newP;
201
            }
202
        }
203 4
    }
204
205
    /**
206
     * Main entry point for the task.
207
     *
208
     * @return void
209
     */
210 31
    public function main()
211
    {
212
        // Call Phing on the file set with the attribute "phingfile"
213 31
        if ($this->phingFile !== null || $this->dir !== null) {
214 31
            $this->processFile();
215
        }
216
217
        // if no filesets are given stop here; else process filesets
218 25
        if (!empty($this->filesets)) {
219
            // preserve old settings
220
            $savedDir = $this->dir;
221
            $savedPhingFile = $this->phingFile;
222
            $savedTarget = $this->newTarget;
223
224
            // set no specific target for files in filesets
225
            // [HL] I'm commenting this out; I don't know why this should not be supported!
226
            // $this->newTarget = null;
227
228
            foreach ($this->filesets as $fs) {
229
                $ds = $fs->getDirectoryScanner($this->project);
230
231
                $fromDir = $fs->getDir($this->project);
0 ignored issues
show
Unused Code introduced by
The assignment to $fromDir is dead and can be removed.
Loading history...
232
                $srcFiles = $ds->getIncludedFiles();
233
234
                foreach ($srcFiles as $fname) {
235
                    $f = new PhingFile($ds->getbasedir(), $fname);
236
                    $f = $f->getAbsoluteFile();
237
                    $this->phingFile = $f->getAbsolutePath();
238
                    $this->dir = $f->getParentFile();
239
                    $this->processFile(); // run Phing!
240
                }
241
            }
242
243
            // side effect free programming ;-)
244
            $this->dir = $savedDir;
245
            $this->phingFile = $savedPhingFile;
246
            $this->newTarget = $savedTarget;
247
248
            // [HL] change back to correct dir
249
            if ($this->dir !== null) {
250
                chdir($this->dir->getAbsolutePath());
251
            }
252
        }
253
254
        // Remove any dangling references to help the GC
255 25
        foreach ($this->properties as $property) {
256 10
            $property->setFallback(null);
257
        }
258 25
    }
259
260
    /**
261
     * Execute phing file.
262
     *
263
     * @throws BuildException
264
     */
265 31
    private function processFile(): void
266
    {
267 31
        $buildFailed = false;
268 31
        $savedDir = $this->dir;
269 31
        $savedPhingFile = $this->phingFile;
270 31
        $savedTarget = $this->newTarget;
271
272 31
        $savedBasedirAbsPath = null; // this is used to save the basedir *if* we change it
273
274
        try {
275 31
            $this->getNewProject();
276
277 31
            $this->initializeProject();
278
279 31
            if ($this->dir !== null) {
280 12
                if (!$this->useNativeBasedir) {
281 12
                    $this->newProject->setBasedir($this->dir);
282 12
                    if ($savedDir !== null) { // has been set explicitly
283 12
                        $this->newProject->setInheritedProperty('project.basedir', $this->dir->getAbsolutePath());
284
                    }
285
                }
286
            } else {
287
                // Since we're not changing the basedir here (for file resolution),
288
                // we don't need to worry about any side-effects in this scanrio.
289 20
                $this->dir = $this->getProject()->getBasedir();
290
            }
291
292 31
            $this->overrideProperties();
293 31
            $this->phingFile = $this->phingFile ?? 'build.xml';
294
295 31
            $fu = new FileUtils();
296 31
            $file = $fu->resolveFile($this->dir, $this->phingFile);
297 31
            $this->phingFile = $file->getAbsolutePath();
298 31
            $this->log('calling target(s) '
299 31
                . (empty($this->locals) ? '[default]' : implode(', ', $this->locals))
300 31
                . ' in build file ' . $this->phingFile, Project::MSG_VERBOSE);
301
302 31
            $this->newProject->setUserProperty("phing.file", $this->phingFile);
303
304 31
            if (empty($this->locals)) {
305 31
                $defaultTarget = $this->newProject->getDefaultTarget();
306 31
                if (!empty($defaultTarget)) {
307 31
                    $this->locals[] = $defaultTarget;
308
                }
309
            }
310
311 31
            $thisPhingFile = $this->getProject()->getProperty('phing.file');
312
            // Are we trying to call the target in which we are defined (or
313
            // the build file if this is a top level task)?
314
            if (
315 31
                $thisPhingFile !== null
316 31
                && $this->getOwningTarget() !== null
317 31
                && $thisPhingFile === $file->getPath()
318 15
                && $this->getOwningTarget()->getName() === ''
319
            ) {
320
                if ('phingcall' === $this->getTaskName()) {
321
                    throw new BuildException('phingcall must not be used at the top level.');
322
                }
323
                throw new BuildException(
324
                    sprintf(
325
                        '%s task at the top level must not invoke its own build file.',
326
                        $this->getTaskName()
327
                    )
328
                );
329
            }
330
331 31
            ProjectConfigurator::configureProject($this->newProject, new PhingFile($this->phingFile));
332
333 27
            if ($this->newTarget === null) {
334 2
                $this->newTarget = $this->newProject->getDefaultTarget();
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->newProject->getDefaultTarget() of type string is incompatible with the declared type Target of property $newTarget.

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...
335
            }
336
337
            // Are we trying to call the target in which we are defined?
338
            if (
339 27
                $this->newProject->getBasedir()->equals($this->project->getBasedir())
340 18
                && $this->newProject->getProperty('phing.file') === $this->project->getProperty('phing.file')
341 15
                && $this->getOwningTarget() !== null
342
            ) {
343 15
                $owningTargetName = $this->getOwningTarget()->getName();
344 15
                if ($this->newTarget === $owningTargetName) {
345 2
                    throw new BuildException(
346 2
                        sprintf(
347 2
                            "%s task calling its own parent target",
348 2
                            $this->getTaskName()
349
                        )
350
                    );
351
                }
352
353 13
                $targets = $this->getProject()->getTargets();
354 13
                $taskName = $this->getTaskName();
355
356 13
                foreach ($this->locals as $local) {
357 13
                    if (isset($targets[$local])) {
358 7
                        if ($targets[$local]->dependsOn($owningTargetName)) {
359
                            throw new BuildException(
360
                                sprintf(
361
                                    "%s task calling a target that depends on its parent target '%s'.",
362
                                    $taskName,
363
                                    $owningTargetName
364
                                )
365
                            );
366
                        }
367
                    }
368
                }
369
            }
370
371 25
            $this->addReferences();
372 25
            $this->newProject->executeTarget($this->newTarget);
373 7
        } catch (Exception $e) {
374 7
            $buildFailed = true;
375 7
            $this->log($e->getMessage(), Project::MSG_ERR);
376 7
            if (Phing::getMsgOutputLevel() <= Project::MSG_DEBUG) {
377 7
                $lines = explode("\n", $e->getTraceAsString());
378 7
                foreach ($lines as $line) {
379 7
                    $this->log($line, Project::MSG_DEBUG);
380
                }
381
            }
382 25
        } finally {
383
            // reset environment values to prevent side-effects.
384
385 31
            $this->newProject = null;
386 31
            $pkeys = array_keys($this->properties);
387 31
            foreach ($pkeys as $k) {
388 10
                $this->properties[$k]->setProject(null);
389
            }
390
391 31
            if ($this->output !== null && $this->out !== null) {
392 1
                $this->out->close();
393
            }
394
395 31
            $this->dir = $savedDir;
396 31
            $this->phingFile = $savedPhingFile;
397 31
            $this->newTarget = $savedTarget;
398
399
            // If the basedir for any project was changed, we need to set that back here.
400 31
            if ($savedBasedirAbsPath !== null) {
0 ignored issues
show
introduced by
The condition $savedBasedirAbsPath !== null is always false.
Loading history...
401
                chdir($savedBasedirAbsPath);
402
            }
403
404 31
            if ($this->haltOnFailure && $buildFailed) {
405 31
                throw new BuildException('Execution of the target buildfile failed. Aborting.');
406
            }
407
        }
408 25
    }
409
410
    /**
411
     * Get the (sub)-Project instance currently in use.
412
     *
413
     * @return Project
414
     */
415 31
    protected function getNewProject(): \Project
416
    {
417 31
        if ($this->newProject === null) {
418 4
            $this->reinit();
419
        }
420 31
        return $this->newProject;
421
    }
422
423
    /**
424
     * Configure the Project, i.e. make intance, attach build listeners
425
     * (copy from father project), add Task and Datatype definitions,
426
     * copy properties and references from old project if these options
427
     * are set via the attributes of the XML tag.
428
     *
429
     * Developer note:
430
     * This function replaces the old methods "init", "_reinit" and
431
     * "_initializeProject".
432
     */
433 31
    private function initializeProject()
434
    {
435 31
        $this->newProject->setInputHandler($this->project->getInputHandler());
436
437 31
        foreach ($this->project->getBuildListeners() as $listener) {
438 31
            $this->newProject->addBuildListener($listener);
439
        }
440
441
        /* Copy things from old project. Datatypes and Tasks are always
442
         * copied, properties and references only if specified so/not
443
         * specified otherwise in the XML definition.
444
         */
445
        // Add Datatype definitions
446 31
        foreach ($this->project->getDataTypeDefinitions() as $typeName => $typeClass) {
447 31
            $this->newProject->addDataTypeDefinition($typeName, $typeClass);
448
        }
449
450
        // Add Task definitions
451 31
        foreach ($this->project->getTaskDefinitions() as $taskName => $taskClass) {
452 31
            if ($taskClass === 'phing.tasks.system.PropertyTask') {
453
                // we have already added this taskdef in init()
454 31
                continue;
455
            }
456 31
            $this->newProject->addTaskDefinition($taskName, $taskClass);
457
        }
458
459 31
        if ($this->output !== null) {
460
            try {
461 1
                if ($this->dir !== null) {
462 1
                    $outfile = (new FileUtils())->resolveFile($this->dir, $this->output);
463
                } else {
464 1
                    $outfile = $this->getProject()->resolveFile($this->output);
465
                }
466 1
                $this->out = new FileOutputStream($outfile);
467 1
                $logger = new DefaultLogger();
468 1
                $logger->setMessageOutputLevel(Project::MSG_INFO);
469 1
                $logger->setOutputStream($this->out);
470 1
                $logger->setErrorStream($this->out);
471 1
                $this->newProject->addBuildListener($logger);
472
            } catch (Exception $ex) {
473
                $this->log("Phing: Can't set output to " . $this->output);
474
            }
475
        }
476
477 31
        if ($this->useNativeBasedir) {
478
            $this->addAlmostAll($this->getProject()->getUserProperties(), 'user');
479
        } else {
480 31
            $this->project->copyUserProperties($this->newProject);
481
        }
482
483 31
        if (!$this->inheritAll) {
484
            // set System built-in properties separately,
485
            // b/c we won't inherit them.
486 11
            $this->newProject->setSystemProperties();
487
        } else {
488 21
            $this->addAlmostAll($this->getProject()->getProperties(), 'plain');
489
        }
490 31
    }
491
492
    /**
493
     * Copies all properties from the given table to the new project -
494
     * omitting those that have already been set in the new project as
495
     * well as properties named basedir or phing.file.
496
     * @param array $props properties <code>Hashtable</code> to copy to the
497
     * new project.
498
     * @param string $type the type of property to set (a plain Phing property, a
499
     * user property or an inherited property).
500
     */
501 21
    private function addAlmostAll(array $props, string $type): void
502
    {
503 21
        foreach ($props as $name => $value) {
504 21
            if ($name === 'basedir' || $name === 'phing.file' || $name === 'phing.version') {
505
                // basedir and phing.file get special treatment in main()
506 21
                continue;
507
            }
508 21
            if ($type === 'plain') {
509
                // don't re-set user properties, avoid the warning message
510 21
                if ($this->newProject->getProperty($name) === null) {
511
                    // no user property
512 21
                    $this->newProject->setNewProperty($name, $value);
513
                }
514
            } elseif ($type === 'user') {
515
                $this->newProject->setUserProperty($name, $value);
516
            } elseif ($type === 'inherited') {
517
                $this->newProject->setInheritedProperty($name, $value);
518
            }
519
        }
520 21
    }
521
522
    /**
523
     * Override the properties in the new project with the one
524
     * explicitly defined as nested elements here.
525
     *
526
     * @return void
527
     * @throws BuildException
528
     */
529 31
    private function overrideProperties()
530
    {
531
        // remove duplicate properties - last property wins
532 31
        $properties = array_reverse($this->properties);
533 31
        $set = [];
534 31
        foreach ($properties as $i => $p) {
535 10
            if ($p->getName() !== null && $p->getName() !== '') {
536 10
                if (in_array($p->getName(), $set)) {
537 5
                    unset($this->properties[$i]);
538
                } else {
539 10
                    $set[] = $p->getName();
540
                }
541
            }
542 10
            $p->setProject($this->newProject);
543 10
            $p->main();
544
        }
545 31
        if ($this->useNativeBasedir) {
546
            $this->addAlmostAll($this->getProject()->getInheritedProperties(), 'inherited');
547
        } else {
548 31
            $this->project->copyInheritedProperties($this->newProject);
549
        }
550 31
    }
551
552
    /**
553
     * Add the references explicitly defined as nested elements to the
554
     * new project.  Also copy over all references that don't override
555
     * existing references in the new project if inheritrefs has been
556
     * requested.
557
     *
558
     * @return void
559
     * @throws BuildException
560
     */
561 25
    private function addReferences()
562
    {
563
564
        // parent project references
565 25
        $projReferences = $this->project->getReferences();
566
567 25
        $newReferences = $this->newProject->getReferences();
568
569 25
        $subprojRefKeys = [];
570
571 25
        if (count($this->references) > 0) {
572
            for ($i = 0, $count = count($this->references); $i < $count; $i++) {
573
                /** @var Reference $ref */
574
                $ref = $this->references[$i];
575
                $refid = $ref->getRefId();
576
577
                if ($refid === null) {
578
                    throw new BuildException('the refid attribute is required for reference elements');
579
                }
580
                if (!isset($projReferences[$refid])) {
581
                    $this->log("Parent project doesn't contain any reference '" . $refid . "'", Project::MSG_WARN);
582
                    continue;
583
                }
584
585
                $subprojRefKeys[] = $refid;
586
                unset($this->references[$i]);//thisReferences.remove(refid);
587
                $toRefid = $ref->getToRefid();
0 ignored issues
show
Bug introduced by
The method getToRefid() does not exist on Reference. Did you maybe mean getRefId()? ( Ignorable by Annotation )

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

587
                /** @scrutinizer ignore-call */ 
588
                $toRefid = $ref->getToRefid();

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
588
                if ($toRefid === null) {
589
                    $toRefid = $refid;
590
                }
591
                $this->copyReference($refid, $toRefid);
592
            }
593
        }
594
595
        // Now add all references that are not defined in the
596
        // subproject, if inheritRefs is true
597 25
        if ($this->inheritRefs) {
598
            // get the keys that are were not used by the subproject
599 2
            $unusedRefKeys = array_diff(array_keys($projReferences), $subprojRefKeys);
600
601 2
            foreach ($unusedRefKeys as $key) {
602 2
                if (isset($newReferences[$key])) {
603 2
                    continue;
604
                }
605 2
                $this->copyReference($key, $key);
606
            }
607
        }
608 25
    }
609
610
    /**
611
     * Try to clone and reconfigure the object referenced by oldkey in
612
     * the parent project and add it to the new project with the key
613
     * newkey.
614
     *
615
     * <p>If we cannot clone it, copy the referenced object itself and
616
     * keep our fingers crossed.</p>
617
     *
618
     * @param  string $oldKey
619
     * @param  string $newKey
620
     * @throws BuildException
621
     * @return void
622
     */
623 2
    private function copyReference($oldKey, $newKey)
624
    {
625 2
        $orig = $this->project->getReference($oldKey);
626 2
        if ($orig === null) {
627
            $this->log(
628
                "No object referenced by " . $oldKey . ". Can't copy to "
629
                . $newKey,
630
                Project::MSG_WARN
631
            );
632
633
            return;
634
        }
635
636 2
        $copy = clone $orig;
637
638 2
        if ($copy instanceof ProjectComponent) {
639 2
            $copy->setProject($this->newProject);
640 2
        } elseif (in_array('setProject', get_class_methods(get_class($copy)))) {
641
            $copy->setProject($this->newProject);
642 2
        } elseif (!($copy instanceof Project)) {
643
            // don't copy the old "Project" itself
644
            $msg = "Error setting new project instance for "
645
                . "reference with id " . $oldKey;
646
            throw new BuildException($msg);
647
        }
648
649 2
        $this->newProject->addReference($newKey, $copy);
650 2
    }
651
652
    /**
653
     * If true, pass all properties to the new phing project.
654
     * Defaults to true.
655
     *
656
     * @param $value
657
     */
658 18
    public function setInheritAll($value)
659
    {
660 18
        $this->inheritAll = (bool) $value;
661 18
    }
662
663
    /**
664
     * If true, pass all references to the new phing project.
665
     * Defaults to false.
666
     *
667
     * @param $value
668
     */
669 10
    public function setInheritRefs($value)
670
    {
671 10
        $this->inheritRefs = (bool) $value;
672 10
    }
673
674
    /**
675
     * The directory to use as a base directory for the new phing project.
676
     * Defaults to the current project's basedir, unless inheritall
677
     * has been set to false, in which case it doesn't have a default
678
     * value. This will override the basedir setting of the called project.
679
     *
680
     * @param PhingFile $d
681
     */
682 12
    public function setDir(PhingFile $d): void
683
    {
684 12
        $this->dir = $d;
685 12
    }
686
687
    /**
688
     * The build file to use.
689
     * Defaults to "build.xml". This file is expected to be a filename relative
690
     * to the dir attribute given.
691
     *
692
     * @param $s
693
     */
694 31
    public function setPhingFile($s)
695
    {
696
        // it is a string and not a file to handle relative/absolute
697
        // otherwise a relative file will be resolved based on the current
698
        // basedir.
699 31
        $this->phingFile = $s;
700 31
    }
701
702
    /**
703
     * Alias function for setPhingfile
704
     *
705
     * @param $s
706
     */
707 8
    public function setBuildfile($s)
708
    {
709 8
        $this->setPhingFile($s);
710 8
    }
711
712
    /**
713
     * The target of the new Phing project to execute.
714
     * Defaults to the new project's default target.
715
     *
716
     * @param string $s
717
     */
718 30
    public function setTarget(string $s)
719
    {
720 30
        if ('' === $s) {
721 1
            throw new BuildException("target attribute must not be empty");
722
        }
723
724 29
        $this->newTarget = $s;
0 ignored issues
show
Documentation Bug introduced by
It seems like $s of type string is incompatible with the declared type Target of property $newTarget.

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...
725 29
    }
726
727
    /**
728
     * Set the filename to write the output to. This is relative to the value
729
     * of the dir attribute if it has been set or to the base directory of the
730
     * current project otherwise.
731
     * @param string $outputFile the name of the file to which the output should go.
732
     */
733 1
    public function setOutput(string $outputFile): void
734
    {
735 1
        $this->output = $outputFile;
736 1
    }
737
738
    /**
739
     * Property to pass to the new project.
740
     * The property is passed as a 'user property'
741
     */
742 10
    public function createProperty()
743
    {
744 10
        $p = new PropertyTask();
745 10
        $p->setFallback($this->getNewProject());
746 10
        $p->setUserProperty(true);
747 10
        $p->setTaskName('property');
748 10
        $this->properties[] = $p;
749
750 10
        return $p;
751
    }
752
753
    /**
754
     * Reference element identifying a data type to carry
755
     * over to the new project.
756
     *
757
     * @param PhingReference $ref
758
     */
759 1
    public function addReference(PhingReference $ref)
760
    {
761 1
        $this->references[] = $ref;
762 1
    }
763
}
764