Test Failed
Pull Request — stable (#106)
by
unknown
02:04
created

Builder   A

Complexity

Total Complexity 17

Size/Duplication

Total Lines 215
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 2

Importance

Changes 0
Metric Value
dl 0
loc 215
rs 10
c 0
b 0
f 0
wmc 17
lcom 1
cbo 2

10 Methods

Rating   Name   Duplication   Size   Complexity  
A handle() 0 13 3
A build() 0 12 1
B compile() 0 24 3
A getCompiler() 0 13 2
A makeFolder() 0 8 2
A cleanUp() 0 7 1
A setPermissions() 0 7 1
A prepare() 0 14 1
A finish() 0 8 1
A __destruct() 0 6 2
1
<?php
2
3
namespace LaravelZero\Framework\Commands\App;
4
5
use Phar;
6
use FilesystemIterator;
7
use UnexpectedValueException;
8
use LaravelZero\Framework\Commands\Command;
9
10
/**
11
 * This is the Laravel Zero Framework builder command class.
12
 *
13
 * @author Nuno Maduro <[email protected]>
14
 */
15
class Builder extends Command
16
{
17
    /**
18
     * The directory that contains your application builds.
19
     */
20
    const BUILD_PATH = BASE_PATH.DIRECTORY_SEPARATOR.'builds';
21
22
    /**
23
     * Contains the default app structure.
24
     *
25
     * @var []string
26
     */
27
    protected $structure = [
28
        'app'.DIRECTORY_SEPARATOR,
29
        'bootstrap'.DIRECTORY_SEPARATOR,
30
        'vendor'.DIRECTORY_SEPARATOR,
31
        'config'.DIRECTORY_SEPARATOR,
32
    ];
33
34
    /**
35
     * {@inheritdoc}
36
     */
37
    protected $signature = 'app:build {name=application : The build name}';
38
39
    /**
40
     * {@inheritdoc}
41
     */
42
    protected $description = 'Perform an application build';
43
44
    /**
45
     * Holds the configuration on is original state.
46
     *
47
     * @var string
48
     */
49
    protected static $config;
50
51
    /**
52
     * {@inheritdoc}
53
     */
54
    public function handle(): void
55
    {
56
        $this->alert('Building the application...');
57
58
        if (Phar::canWrite()) {
59
            $this->build($this->input->getArgument('name') ?: self::BUILD_NAME);
60
        } else {
61
            $this->error(
62
                'Unable to compile a phar because of php\'s security settings. '.'phar.readonly must be disabled in php.ini. '.PHP_EOL.PHP_EOL.'You will need to edit '.php_ini_loaded_file(
63
                ).' and add or set'.PHP_EOL.PHP_EOL.'    phar.readonly = Off'.PHP_EOL.PHP_EOL.'to continue. Details here: http://php.net/manual/en/phar.configuration.php'
64
            );
65
        }
66
    }
67
68
    /**
69
     * Builds the application.
70
     *
71
     * @param string $name
72
     *
73
     * @return $this
74
     */
75
    protected function build(string $name): Builder
76
    {
77
        $this->prepare()
78
            ->compile($name)
79
            ->cleanUp($name)
80
            ->setPermissions($name)
81
            ->finish();
82
83
        $this->info('Standalone application compiled into: builds'.DIRECTORY_SEPARATOR.$name);
84
85
        return $this;
86
    }
87
88
    /**
89
     * Compiles the standalone application.
90
     *
91
     * @param string $name
92
     *
93
     * @return $this
94
     */
95
    protected function compile(string $name): Builder
96
    {
97
        $this->info('Compiling code...');
98
99
        $compiler = $this->makeFolder()
100
            ->getCompiler($name);
101
102
        $structure = config('app.structure') ?: $this->structure;
103
        
104
        // See - https://github.com/laravel-zero/framework/pull/102
105
        $regex = '#'.implode('|', $structure).'#';
106
107
        if (stristr(PHP_OS, "WINNT") != FALSE) {
0 ignored issues
show
Bug Best Practice introduced by
It seems like you are loosely comparing stristr(PHP_OS, 'WINNT') of type string to the boolean FALSE. If you are specifically checking for a non-empty string, consider using the more explicit !== '' instead.
Loading history...
108
            $compiler->buildFromDirectory(BASE_PATH, str_replace('\\', '/', $regex));
109
        } else {
110
            // Linux, OS X
111
            $compiler->buildFromDirectory(BASE_PATH, $regex);
112
        }
113
        $compiler->setStub(
114
            "#!/usr/bin/env php \n".$compiler->createDefaultStub('bootstrap'.DIRECTORY_SEPARATOR.'init.php')
115
        );
116
117
        return $this;
118
    }
119
120
    /**
121
     * Gets a new instance of the compiler.
122
     *
123
     * @param string $name
124
     *
125
     * @return \Phar
126
     */
127
    protected function getCompiler(string $name): \Phar
128
    {
129
        try {
130
            return new Phar(
131
                self::BUILD_PATH.DIRECTORY_SEPARATOR.$name.'.phar',
132
                FilesystemIterator::CURRENT_AS_FILEINFO | FilesystemIterator::KEY_AS_FILENAME,
133
                $name
134
            );
135
        } catch (UnexpectedValueException $e) {
136
            $this->error("You can't perform a build.");
137
            exit(0);
138
        }
139
    }
140
141
    /**
142
     * Creates the folder for the builds.
143
     *
144
     * @return $this
145
     */
146
    protected function makeFolder(): Builder
147
    {
148
        if (! file_exists(self::BUILD_PATH)) {
149
            mkdir(self::BUILD_PATH);
150
        }
151
152
        return $this;
153
    }
154
155
    /**
156
     * Moves the compiled files to the builds folder.
157
     *
158
     * @param string $name
159
     *
160
     * @return $this
161
     */
162
    protected function cleanUp(string $name): Builder
163
    {
164
        $file = self::BUILD_PATH.DIRECTORY_SEPARATOR.$name;
165
        rename("$file.phar", $file);
166
167
        return $this;
168
    }
169
170
    /**
171
     * Sets the executable mode on the standalone application file.
172
     *
173
     * @param string $name
174
     *
175
     * @return $this
176
     */
177
    protected function setPermissions($name): Builder
178
    {
179
        $file = self::BUILD_PATH.DIRECTORY_SEPARATOR.$name;
180
        chmod($file, 0755);
181
182
        return $this;
183
    }
184
185
    /**
186
     * Prepares the application for build.
187
     *
188
     * @return $this
189
     */
190
    protected function prepare(): Builder
191
    {
192
        $file = BASE_PATH.DIRECTORY_SEPARATOR.'config'.DIRECTORY_SEPARATOR.'app.php';
193
        static::$config = file_get_contents($file);
194
        $config = include $file;
195
196
        $config['production'] = true;
197
198
        $this->info('Moving configuration to production mode...');
199
200
        file_put_contents($file, '<?php return '.var_export($config, true).';'.PHP_EOL);
201
202
        return $this;
203
    }
204
205
    /**
206
     * Prepares the application for build.
207
     *
208
     * @return $this
209
     */
210
    protected function finish(): Builder
211
    {
212
        file_put_contents(BASE_PATH.DIRECTORY_SEPARATOR.'config'.DIRECTORY_SEPARATOR.'app.php', static::$config);
213
214
        static::$config = null;
215
216
        return $this;
217
    }
218
219
    /**
220
     * Makes sure that the finish is performed even
221
     * if the command fails.
222
     */
223
    public function __destruct()
224
    {
225
        if (static::$config !== null) {
226
            file_put_contents(BASE_PATH.DIRECTORY_SEPARATOR.'config'.DIRECTORY_SEPARATOR.'app.php', static::$config);
227
        }
228
    }
229
}
230