Test Failed
Pull Request — stable (#73)
by Nuno
04:10
created

Builder   A

Complexity

Total Complexity 16

Size/Duplication

Total Lines 204
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 2

Importance

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

10 Methods

Rating   Name   Duplication   Size   Complexity  
A handle() 0 13 3
A build() 0 12 1
A compile() 0 14 2
A getCompiler() 0 13 2
A makeFolder() 0 8 2
A cleanUp() 0 7 1
A setPermissions() 0 7 1
A prepare() 0 13 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.'/builds';
21
22
    /**
23
     * Contains the default app structure.
24
     *
25
     * @var []string
26
     */
27
    protected $structure = [
28
        'app/',
29
        'bootstrap/',
30
        'vendor/',
31
        'config/',
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): self
76
    {
77
        $this->prepare()
78
            ->compile($name)
79
            ->cleanUp($name)
80
            ->setPermissions($name)
81
            ->finish();
82
83
        $this->info("Standalone application compiled into: builds/$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): self
96
    {
97
        $this->info('Compiling code...');
98
99
        $compiler = $this->makeFolder()
100
            ->getCompiler($name);
101
102
        $structure = config('app.structure') ?: $this->structure;
103
104
        $compiler->buildFromDirectory(BASE_PATH, '#'.implode('|', $structure).'#');
105
        $compiler->setStub("#!/usr/bin/env php \n".$compiler->createDefaultStub('bootstrap/init.php'));
106
107
        return $this;
108
    }
109
110
    /**
111
     * Gets a new instance of the compiler.
112
     *
113
     * @param string $name
114
     *
115
     * @return \Phar
116
     */
117
    protected function getCompiler(string $name): \Phar
118
    {
119
        try {
120
            return new Phar(
121
                self::BUILD_PATH.'/'.$name.'.phar',
122
                FilesystemIterator::CURRENT_AS_FILEINFO | FilesystemIterator::KEY_AS_FILENAME,
123
                $name
124
            );
125
        } catch (UnexpectedValueException $e) {
126
            $this->error("You can't perform a build.");
127
            exit(0);
128
        }
129
    }
130
131
    /**
132
     * Creates the folder for the builds.
133
     *
134
     * @return $this
135
     */
136
    protected function makeFolder(): self
137
    {
138
        if (! file_exists(self::BUILD_PATH)) {
139
            mkdir(self::BUILD_PATH);
140
        }
141
142
        return $this;
143
    }
144
145
    /**
146
     * Moves the compiled files to the builds folder.
147
     *
148
     * @param string $name
149
     *
150
     * @return $this
151
     */
152
    protected function cleanUp(string $name): self
153
    {
154
        $file = self::BUILD_PATH."/$name";
155
        rename("$file.phar", $file);
156
157
        return $this;
158
    }
159
160
    /**
161
     * Sets the executable mode on the standalone application file.
162
     *
163
     * @param string $name
164
     *
165
     * @return $this
166
     */
167
    protected function setPermissions($name): self
168
    {
169
        $file = self::BUILD_PATH."/$name";
170
        chmod($file, 0755);
171
172
        return $this;
173
    }
174
175
    /**
176
     * Prepares the application for build.
177
     *
178
     * @return $this
179
     */
180
    protected function prepare(): self
181
    {
182
        $file = BASE_PATH.'/config/app.php';
183
        static::$config = file_get_contents($file);
184
        $config = include $file;
185
186
        $config['production'] = true;
187
        file_put_contents($file, '<?php return '.var_export($config, true).';'.PHP_EOL);
188
189
        $this->info('Moving configuration to production mode...');
190
191
        return $this;
192
    }
193
194
    /**
195
     * Prepares the application for build.
196
     *
197
     * @return $this
198
     */
199
    protected function finish(): self
200
    {
201
        file_put_contents(BASE_PATH.'/config/app.php', static::$config);
202
203
        static::$config = null;
204
205
        return $this;
206
    }
207
208
    /**
209
     * Makes sure that the finish is performed even
210
     * if the command fails.
211
     */
212
    public function __destruct()
213
    {
214
        if (static::$config !== null) {
215
            file_put_contents(BASE_PATH.'/config/app.php', static::$config);
216
        }
217
    }
218
}
219