1 | <?php |
||
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 | 'composer.json', |
||
33 | ]; |
||
34 | |||
35 | /** |
||
36 | * {@inheritdoc} |
||
37 | */ |
||
38 | protected $signature = 'app:build {name=application : The build name}'; |
||
39 | |||
40 | /** |
||
41 | * {@inheritdoc} |
||
42 | */ |
||
43 | protected $description = 'Perform an application build'; |
||
44 | |||
45 | /** |
||
46 | * Holds the configuration on is original state. |
||
47 | * |
||
48 | * @var string |
||
49 | */ |
||
50 | protected static $config; |
||
51 | |||
52 | /** |
||
53 | * {@inheritdoc} |
||
54 | */ |
||
55 | 1 | public function handle(): void |
|
56 | { |
||
57 | 1 | $this->alert('Building the application...'); |
|
58 | |||
59 | 1 | if (Phar::canWrite()) { |
|
60 | 1 | $this->build($this->input->getArgument('name') ?: self::BUILD_NAME); |
|
61 | } else { |
||
62 | $this->error( |
||
63 | '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( |
||
64 | ).' 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' |
||
65 | ); |
||
66 | } |
||
67 | 1 | } |
|
68 | |||
69 | /** |
||
70 | * Builds the application. |
||
71 | * |
||
72 | * @param string $name |
||
73 | * |
||
74 | * @return $this |
||
75 | */ |
||
76 | 1 | protected function build(string $name): Builder |
|
77 | { |
||
78 | 1 | $this->prepare() |
|
79 | 1 | ->compile($name) |
|
80 | 1 | ->cleanUp($name) |
|
81 | 1 | ->setPermissions($name) |
|
82 | 1 | ->finish(); |
|
83 | |||
84 | 1 | $this->info('Standalone application compiled into: builds'.DIRECTORY_SEPARATOR.$name); |
|
85 | |||
86 | 1 | return $this; |
|
87 | } |
||
88 | |||
89 | /** |
||
90 | * Compiles the standalone application. |
||
91 | * |
||
92 | * @param string $name |
||
93 | * |
||
94 | * @return $this |
||
95 | */ |
||
96 | 1 | protected function compile(string $name): Builder |
|
97 | { |
||
98 | 1 | $this->info('Compiling code...'); |
|
99 | |||
100 | 1 | $compiler = $this->makeFolder() |
|
101 | 1 | ->getCompiler($name); |
|
102 | |||
103 | 1 | $structure = config('app.structure') ?: $this->structure; |
|
104 | |||
105 | 1 | $regex = '#'.implode('|', $structure).'#'; |
|
106 | |||
107 | 1 | if (stristr(PHP_OS, 'WINNT') !== false) { |
|
108 | $compiler->buildFromDirectory(BASE_PATH, str_replace('\\', '/', $regex)); |
||
109 | } else { |
||
110 | // Linux, OS X |
||
111 | 1 | $compiler->buildFromDirectory(BASE_PATH, $regex); |
|
112 | } |
||
113 | 1 | $compiler->setStub( |
|
114 | 1 | "#!/usr/bin/env php \n".$compiler->createDefaultStub('bootstrap'.DIRECTORY_SEPARATOR.'init.php') |
|
115 | ); |
||
116 | |||
117 | 1 | return $this; |
|
118 | } |
||
119 | |||
120 | /** |
||
121 | * Gets a new instance of the compiler. |
||
122 | * |
||
123 | * @param string $name |
||
124 | * |
||
125 | * @return \Phar |
||
126 | */ |
||
127 | 1 | protected function getCompiler(string $name): \Phar |
|
128 | { |
||
129 | try { |
||
130 | 1 | return new Phar( |
|
131 | 1 | self::BUILD_PATH.DIRECTORY_SEPARATOR.$name.'.phar', |
|
132 | 1 | FilesystemIterator::CURRENT_AS_FILEINFO | FilesystemIterator::KEY_AS_FILENAME, |
|
133 | 1 | $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 | 1 | protected function makeFolder(): Builder |
|
147 | { |
||
148 | 1 | if (! file_exists(self::BUILD_PATH)) { |
|
149 | 1 | mkdir(self::BUILD_PATH); |
|
150 | } |
||
151 | |||
152 | 1 | 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 | 1 | protected function cleanUp(string $name): Builder |
|
163 | { |
||
164 | 1 | $file = self::BUILD_PATH.DIRECTORY_SEPARATOR.$name; |
|
165 | 1 | rename("$file.phar", $file); |
|
166 | |||
167 | 1 | 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 | 1 | protected function setPermissions($name): Builder |
|
178 | { |
||
179 | 1 | $file = self::BUILD_PATH.DIRECTORY_SEPARATOR.$name; |
|
180 | 1 | chmod($file, 0755); |
|
181 | |||
182 | 1 | return $this; |
|
183 | } |
||
184 | |||
185 | /** |
||
186 | * Prepares the application for build. |
||
187 | * |
||
188 | * @return $this |
||
189 | */ |
||
190 | 1 | protected function prepare(): Builder |
|
191 | { |
||
192 | 1 | $file = BASE_PATH.DIRECTORY_SEPARATOR.'config'.DIRECTORY_SEPARATOR.'app.php'; |
|
193 | 1 | static::$config = file_get_contents($file); |
|
194 | 1 | $config = include $file; |
|
195 | |||
196 | 1 | $config['production'] = true; |
|
197 | |||
198 | 1 | $this->info('Moving configuration to production mode...'); |
|
199 | |||
200 | 1 | file_put_contents($file, '<?php return '.var_export($config, true).';'.PHP_EOL); |
|
201 | |||
202 | 1 | return $this; |
|
203 | } |
||
204 | |||
205 | /** |
||
206 | * Prepares the application for build. |
||
207 | * |
||
208 | * @return $this |
||
209 | */ |
||
210 | 1 | protected function finish(): Builder |
|
211 | { |
||
212 | 1 | file_put_contents(BASE_PATH.DIRECTORY_SEPARATOR.'config'.DIRECTORY_SEPARATOR.'app.php', static::$config); |
|
213 | |||
214 | 1 | static::$config = null; |
|
215 | |||
216 | 1 | return $this; |
|
217 | } |
||
218 | |||
219 | /** |
||
220 | * Makes sure that the finish is performed even |
||
221 | * if the command fails. |
||
222 | */ |
||
223 | public function __destruct() |
||
229 | } |
||
230 |