Skip to content

Commit 1ec2d91

Browse files
committedJul 28, 2017
Initial commit
0 parents  commit 1ec2d91

File tree

6 files changed

+299
-0
lines changed

6 files changed

+299
-0
lines changed
 

‎.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
/vendor
2+
.DS_Store

‎LICENSE.txt

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
The MIT License (MIT)
2+
3+
Copyright (c) <Marcel Pociot>
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in
13+
all copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21+
THE SOFTWARE.

‎botman

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#!/usr/bin/env php
2+
<?php
3+
4+
if (file_exists(__DIR__.'/../../autoload.php')) {
5+
require __DIR__.'/../../autoload.php';
6+
} else {
7+
require __DIR__.'/vendor/autoload.php';
8+
}
9+
10+
$app = new Symfony\Component\Console\Application('BotMan Installer', '1.0.0');
11+
$app->add(new BotMan\Installer\Console\NewCommand);
12+
13+
$app->run();

‎composer.json

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
{
2+
"name": "botman/installer",
3+
"description": "BotMan Studio installer.",
4+
"keywords": ["botman"],
5+
"license": "MIT",
6+
"authors": [
7+
{
8+
"name": "Marcel Pociot",
9+
"email": "m.pociot@gmail.com"
10+
}
11+
],
12+
"autoload": {
13+
"psr-4": {
14+
"BotMan\\Installer\\Console\\": "src/"
15+
}
16+
},
17+
"require": {
18+
"ext-zip": "*",
19+
"guzzlehttp/guzzle": "~4.0|~5.0|~6.0",
20+
"symfony/console": "~2.3|~3.0",
21+
"symfony/filesystem": "~2.3|~3.0",
22+
"symfony/process": "~2.3|~3.0"
23+
},
24+
"bin": [
25+
"botman"
26+
]
27+
}

‎src/NewCommand.php

+228
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,228 @@
1+
<?php
2+
3+
namespace BotMan\Installer\Console;
4+
5+
use ZipArchive;
6+
use RuntimeException;
7+
use GuzzleHttp\Client;
8+
use Symfony\Component\Process\Process;
9+
use Symfony\Component\Filesystem\Filesystem;
10+
use Symfony\Component\Console\Command\Command;
11+
use Symfony\Component\Console\Input\InputOption;
12+
use Symfony\Component\Console\Input\InputArgument;
13+
use Symfony\Component\Console\Input\InputInterface;
14+
use Symfony\Component\Console\Output\OutputInterface;
15+
use Symfony\Component\Filesystem\Exception\IOExceptionInterface;
16+
17+
class NewCommand extends Command
18+
{
19+
/**
20+
* Configure the command options.
21+
*
22+
* @return void
23+
*/
24+
protected function configure()
25+
{
26+
$this
27+
->setName('new')
28+
->setDescription('Create a new BotMan application.')
29+
->addArgument('name', InputArgument::OPTIONAL)
30+
->addOption('dev', null, InputOption::VALUE_NONE, 'Installs the latest "development" release')
31+
->addOption('force', null, InputOption::VALUE_NONE, 'Forces install even if the directory already exists');
32+
}
33+
34+
/**
35+
* Execute the command.
36+
*
37+
* @param \Symfony\Component\Console\Input\InputInterface $input
38+
* @param \Symfony\Component\Console\Output\OutputInterface $output
39+
* @return void
40+
*/
41+
protected function execute(InputInterface $input, OutputInterface $output)
42+
{
43+
if (! class_exists('ZipArchive')) {
44+
throw new RuntimeException('The Zip PHP extension is not installed. Please install it and try again.');
45+
}
46+
47+
$directory = ($input->getArgument('name')) ? getcwd().'/'.$input->getArgument('name') : getcwd();
48+
49+
if (! $input->getOption('force')) {
50+
$this->verifyApplicationDoesntExist($directory);
51+
}
52+
53+
$output->writeln('<info>Building your next great chatbot...</info>');
54+
55+
$version = $this->getVersion($input);
56+
57+
$this->download($zipFile = $this->makeFilename(), $version)
58+
->extract($zipFile, $directory)
59+
->prepareWritableDirectories($directory, $output)
60+
->cleanUp($zipFile);
61+
62+
$composer = $this->findComposer();
63+
64+
$commands = [
65+
$composer.' install --no-scripts',
66+
$composer.' run-script post-root-package-install',
67+
$composer.' run-script post-install-cmd',
68+
$composer.' run-script post-create-project-cmd',
69+
];
70+
71+
if ($input->getOption('dev')) {
72+
unset($commands[2]);
73+
74+
$commands[] = $composer.' run-script post-autoload-dump';
75+
}
76+
77+
if ($input->getOption('no-ansi')) {
78+
$commands = array_map(function ($value) {
79+
return $value.' --no-ansi';
80+
}, $commands);
81+
}
82+
83+
$process = new Process(implode(' && ', $commands), $directory, null, null, null);
84+
85+
if ('\\' !== DIRECTORY_SEPARATOR && file_exists('/dev/tty') && is_readable('/dev/tty')) {
86+
$process->setTty(true);
87+
}
88+
89+
$process->run(function ($type, $line) use ($output) {
90+
$output->write($line);
91+
});
92+
93+
$output->writeln('<comment>BotMan Studio ready! Build an amazing chatbot!</comment>');
94+
}
95+
96+
/**
97+
* Verify that the application does not already exist.
98+
*
99+
* @param string $directory
100+
* @return void
101+
*/
102+
protected function verifyApplicationDoesntExist($directory)
103+
{
104+
if ((is_dir($directory) || is_file($directory)) && $directory != getcwd()) {
105+
throw new RuntimeException('Application already exists!');
106+
}
107+
}
108+
109+
/**
110+
* Generate a random temporary filename.
111+
*
112+
* @return string
113+
*/
114+
protected function makeFilename()
115+
{
116+
return getcwd().'/botman_'.md5(time().uniqid()).'.zip';
117+
}
118+
119+
/**
120+
* Download the temporary Zip to the given file.
121+
*
122+
* @param string $zipFile
123+
* @param string $version
124+
* @return $this
125+
*/
126+
protected function download($zipFile, $version = 'master')
127+
{
128+
switch ($version) {
129+
case 'develop':
130+
$filename = 'latest-develop.zip';
131+
break;
132+
case 'master':
133+
$filename = 'latest.zip';
134+
break;
135+
}
136+
137+
$response = (new Client)->get('http://botman.io/studio/'.$filename);
138+
139+
file_put_contents($zipFile, $response->getBody());
140+
141+
return $this;
142+
}
143+
144+
/**
145+
* Extract the Zip file into the given directory.
146+
*
147+
* @param string $zipFile
148+
* @param string $directory
149+
* @return $this
150+
*/
151+
protected function extract($zipFile, $directory)
152+
{
153+
$archive = new ZipArchive;
154+
155+
$archive->open($zipFile);
156+
157+
$archive->extractTo($directory);
158+
159+
$archive->close();
160+
161+
return $this;
162+
}
163+
164+
/**
165+
* Clean-up the Zip file.
166+
*
167+
* @param string $zipFile
168+
* @return $this
169+
*/
170+
protected function cleanUp($zipFile)
171+
{
172+
@chmod($zipFile, 0777);
173+
174+
@unlink($zipFile);
175+
176+
return $this;
177+
}
178+
179+
/**
180+
* Make sure the storage and bootstrap cache directories are writable.
181+
*
182+
* @param string $appDirectory
183+
* @param \Symfony\Component\Console\Output\OutputInterface $output
184+
* @return $this
185+
*/
186+
protected function prepareWritableDirectories($appDirectory, OutputInterface $output)
187+
{
188+
$filesystem = new Filesystem;
189+
190+
try {
191+
$filesystem->chmod($appDirectory.DIRECTORY_SEPARATOR."bootstrap/cache", 0755, 0000, true);
192+
$filesystem->chmod($appDirectory.DIRECTORY_SEPARATOR."storage", 0755, 0000, true);
193+
} catch (IOExceptionInterface $e) {
194+
$output->writeln('<comment>You should verify that the "storage" and "bootstrap/cache" directories are writable.</comment>');
195+
}
196+
197+
return $this;
198+
}
199+
200+
/**
201+
* Get the version that should be downloaded.
202+
*
203+
* @param \Symfony\Component\Console\Input\InputInterface $input
204+
* @return string
205+
*/
206+
protected function getVersion(InputInterface $input)
207+
{
208+
if ($input->getOption('dev')) {
209+
return 'develop';
210+
}
211+
212+
return 'master';
213+
}
214+
215+
/**
216+
* Get the composer command for the environment.
217+
*
218+
* @return string
219+
*/
220+
protected function findComposer()
221+
{
222+
if (file_exists(getcwd().'/composer.phar')) {
223+
return '"'.PHP_BINARY.'" composer.phar';
224+
}
225+
226+
return 'composer';
227+
}
228+
}

‎zipper.sh

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#!/usr/bin/env bash
2+
wget https://github.com/botman/studio/archive/master.zip
3+
unzip master.zip -d working
4+
cd working/studio-master
5+
zip -ry ../../latest.zip .
6+
cd ../..
7+
rm -rf working
8+
rm master.zip

0 commit comments

Comments
 (0)
Please sign in to comment.