Completed
Push — master ( 32a903...cb8294 )
by Théo
02:52 queued 22s
created

functions.php ➔ iterables_to_iterator()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 17
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 10
nc 4
nop 1
dl 0
loc 17
rs 9.2
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the humbug/php-scoper package.
7
 *
8
 * Copyright (c) 2017 Théo FIDRY <[email protected]>,
9
 *                    Pádraic Brady <[email protected]>
10
 *
11
 * For the full copyright and license information, please view the LICENSE
12
 * file that was distributed with this source code.
13
 */
14
15
namespace Humbug\PhpScoper;
16
17
use AppendIterator;
18
use ArrayIterator;
19
use Humbug\PhpScoper\Console\Application;
20
use Humbug\PhpScoper\Console\Command\AddPrefixCommand;
21
use Humbug\PhpScoper\Console\Command\InitCommand;
22
use Humbug\PhpScoper\Console\Command\SelfUpdateCommand;
23
use Humbug\PhpScoper\Scoper\Composer\InstalledPackagesScoper;
24
use Humbug\PhpScoper\Scoper\Composer\JsonFileScoper;
25
use Humbug\PhpScoper\Scoper\NullScoper;
26
use Humbug\PhpScoper\Scoper\PatchScoper;
27
use Humbug\PhpScoper\Scoper\PhpScoper;
28
use Humbug\PhpScoper\Scoper\TraverserFactory;
29
use Humbug\SelfUpdate\Exception\RuntimeException as SelfUpdateRuntimeException;
30
use Humbug\SelfUpdate\Updater;
31
use Iterator;
32
use IteratorAggregate;
33
use PackageVersions\Versions;
34
use PhpParser\Node;
35
use PhpParser\Parser;
36
use PhpParser\ParserFactory;
37
use Symfony\Component\Console\Application as SymfonyApplication;
38
use Symfony\Component\Filesystem\Filesystem;
39
40
/**
41
 * @private
42
 */
43
function create_application(): SymfonyApplication
44
{
45
    $app = new Application('PHP Scoper', get_version());
46
47
    $app->addCommands([
48
        new AddPrefixCommand(
49
            new Filesystem(),
50
            create_scoper()
51
        ),
52
        new InitCommand(),
53
    ]);
54
55
    if ('phar:' === substr(__FILE__, 0, 5)) {
56
        try {
57
            $updater = new Updater();
58
        } catch (SelfUpdateRuntimeException $e) {
59
            /* Allow E2E testing of unsigned phar */
60
            $updater = new Updater(null, false);
61
        }
62
        $app->add(
63
            new SelfUpdateCommand(
64
                $updater
65
            )
66
        );
67
    }
68
69
    return $app;
70
}
71
72
/**
73
 * @private
74
 */
75
function get_version(): string
76
{
77
    $rawVersion = Versions::getVersion('humbug/php-scoper');
78
79
    list($prettyVersion, $commitHash) = explode('@', $rawVersion);
80
81
    return (1 === preg_match('/9{7}/', $prettyVersion)) ? $commitHash : $prettyVersion;
82
}
83
84
/**
85
 * @private
86
 */
87
function create_scoper(): Scoper
88
{
89
    return new PatchScoper(
90
        new JsonFileScoper(
91
            new InstalledPackagesScoper(
92
                new PhpScoper(
93
                    create_parser(),
94
                    new NullScoper(),
95
                    new TraverserFactory()
96
                )
97
            )
98
        )
99
    );
100
}
101
102
/**
103
 * @private
104
 */
105
function create_parser(): Parser
106
{
107
    return (new ParserFactory())->create(ParserFactory::ONLY_PHP7);
108
}
109
110
/**
111
 * @param string[] $paths Absolute paths
112
 *
113
 * @return string
114
 */
115
function get_common_path(array $paths): string
116
{
117
    if (0 === count($paths)) {
118
        return '';
119
    }
120
121
    $lastOffset = 1;
122
    $common = DIRECTORY_SEPARATOR;
123
124
    while (false !== ($index = strpos($paths[0], DIRECTORY_SEPARATOR, $lastOffset))) {
125
        $dirLen = $index - $lastOffset + 1;
126
        $dir = substr($paths[0], $lastOffset, $dirLen);
127
128
        foreach ($paths as $path) {
129
            if (substr($path, $lastOffset, $dirLen) !== $dir) {
130 View Code Duplication
                if (0 < strlen($common) && DIRECTORY_SEPARATOR === $common[strlen($common) - 1]) {
131
                    $common = substr($common, 0, strlen($common) - 1);
132
                }
133
134
                return $common;
135
            }
136
        }
137
138
        $common .= $dir;
139
        $lastOffset = $index + 1;
140
    }
141
142
    $common = substr($common, 0, -1);
143
144 View Code Duplication
    if (0 < strlen($common) && DIRECTORY_SEPARATOR === $common[strlen($common) - 1]) {
145
        $common = substr($common, 0, strlen($common) - 1);
146
    }
147
148
    return $common;
149
}
150
151
/**
152
 * In-house clone functions. Does a partial clone that should be enough to provide the immutability required in some
153
 * places for the scoper. It however does not guarantee a deep cloning as would be horribly slow for no good reasons.
154
 * A better alternative would be to find a way to push immutability upstream in PHP-Parser directly.
155
 *
156
 * @param Node $node
157
 *
158
 * @return Node
159
 */
160
function clone_node(Node $node): Node
161
{
162
    $clone = deep_clone($node);
163
164
    foreach ($node->getAttributes() as $key => $attribute) {
165
        $clone->setAttribute($key, $attribute);
166
    }
167
168
    return $clone;
169
}
170
171
/**
172
 * @param mixed $node
173
 *
174
 * @return mixed
175
 *
176
 * @internal
177
 */
178
function deep_clone($node)
179
{
180
    if (is_array($node)) {
181
        return array_map(__FUNCTION__, $node);
182
    }
183
184
    if (null === $node || is_scalar($node)) {
185
        return $node;
186
    }
187
188
    return unserialize(serialize($node));
189
}
190
191
function iterables_to_iterator(iterable ...$iterables): Iterator
192
{
193
    $iterator = new AppendIterator();
194
195
    foreach ($iterables as $iterable) {
196
        if (is_array($iterable)) {
197
            $iterator->append(new ArrayIterator($iterable));
198
        } elseif ($iterable instanceof IteratorAggregate) {
199
            $iterator->append($iterable->getIterator());
200
        } else {
201
            /* @var Iterator $iterable */
202
            $iterator->append($iterable);
203
        }
204
    }
205
206
    return $iterator;
207
}
208