From cffa43a155adbe7b50eed799a78df3b5aecfefe5 Mon Sep 17 00:00:00 2001 From: Alejandro Celaya Date: Sun, 14 Aug 2016 09:09:23 +0200 Subject: [PATCH 01/19] Created installation script and installation command --- bin/install | 11 ++++ config/params/.gitignore | 2 + .../src/Command/Install/InstallCommand.php | 59 +++++++++++++++++++ 3 files changed, 72 insertions(+) create mode 100755 bin/install create mode 100644 config/params/.gitignore create mode 100644 module/CLI/src/Command/Install/InstallCommand.php diff --git a/bin/install b/bin/install new file mode 100755 index 00000000..651ae8e3 --- /dev/null +++ b/bin/install @@ -0,0 +1,11 @@ +#!/usr/bin/env php +add(new InstallCommand()); +$app->setDefaultCommand('shlink:install'); +$app->run(); diff --git a/config/params/.gitignore b/config/params/.gitignore new file mode 100644 index 00000000..d6b7ef32 --- /dev/null +++ b/config/params/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/module/CLI/src/Command/Install/InstallCommand.php b/module/CLI/src/Command/Install/InstallCommand.php new file mode 100644 index 00000000..2e3b0af3 --- /dev/null +++ b/module/CLI/src/Command/Install/InstallCommand.php @@ -0,0 +1,59 @@ +setName('shlink:install') + ->setDescription('Installs Shlink'); + } + + public function execute(InputInterface $input, OutputInterface $output) + { + $this->input = $input; + $this->output = $output; + $params = []; + + $output->writeln([ + 'Welcome to Shlink!!', + 'This will guide you through the installation process.', + ]); + + $params['DB_NAME'] = $this->ask('Database name', 'shlink'); + } + + /** + * @param string $text + * @param string|null $default + * @return string + */ + protected function ask($text, $default = null) + { + /** @var QuestionHelper $questionHelper */ + $questionHelper = $this->getHelper('question'); + + if (isset($default)) { + $text .= ' (defaults to ' . $default . ')'; + } + return $questionHelper->ask($this->input, $this->output, new Question( + ' ' . $text . ': ', + $default + )); + } +} From 56af58fcb82e85bcd60b3ffba3680356c123c9d9 Mon Sep 17 00:00:00 2001 From: Alejandro Celaya Date: Sun, 14 Aug 2016 09:11:46 +0200 Subject: [PATCH 02/19] Created installation script and installation command --- module/CLI/src/Command/Install/InstallCommand.php | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/module/CLI/src/Command/Install/InstallCommand.php b/module/CLI/src/Command/Install/InstallCommand.php index 2e3b0af3..b4b0d3e1 100644 --- a/module/CLI/src/Command/Install/InstallCommand.php +++ b/module/CLI/src/Command/Install/InstallCommand.php @@ -36,6 +36,8 @@ class InstallCommand extends Command ]); $params['DB_NAME'] = $this->ask('Database name', 'shlink'); + $params['DB_USER'] = $this->ask('Database username'); + $params['DB_PASSWORD'] = $this->ask('Database password'); } /** @@ -51,9 +53,14 @@ class InstallCommand extends Command if (isset($default)) { $text .= ' (defaults to ' . $default . ')'; } - return $questionHelper->ask($this->input, $this->output, new Question( - ' ' . $text . ': ', - $default - )); + $value = ''; + while (empty($value) && empty($default)) { + $value = $questionHelper->ask($this->input, $this->output, new Question( + ' ' . $text . ': ', + $default + )); + } + + return $value; } } From 566ee7ef6f395e6b3b812e34edf7334d7ce14ae5 Mon Sep 17 00:00:00 2001 From: Alejandro Celaya Date: Sun, 14 Aug 2016 10:30:43 +0200 Subject: [PATCH 03/19] Finished custom config command --- bin/install | 5 +- .../src/Command/Install/InstallCommand.php | 206 +++++++++++++++++- module/Rest/config/rest.config.php | 9 - 3 files changed, 198 insertions(+), 22 deletions(-) delete mode 100644 module/Rest/config/rest.config.php diff --git a/bin/install b/bin/install index 651ae8e3..b1ce8a1e 100755 --- a/bin/install +++ b/bin/install @@ -2,10 +2,13 @@ add(new InstallCommand()); +$app->add(new InstallCommand(new PhpArray())); $app->setDefaultCommand('shlink:install'); $app->run(); diff --git a/module/CLI/src/Command/Install/InstallCommand.php b/module/CLI/src/Command/Install/InstallCommand.php index b4b0d3e1..8d1c533e 100644 --- a/module/CLI/src/Command/Install/InstallCommand.php +++ b/module/CLI/src/Command/Install/InstallCommand.php @@ -1,14 +1,27 @@ 'pdo_mysql', + 'PostgreSQL' => 'pdo_pgsql', + 'SQLite' => 'pdo_sqlite', + ]; + const SUPPORTED_LANGUAGES = ['en', 'es']; + /** * @var InputInterface */ @@ -17,6 +30,20 @@ class InstallCommand extends Command * @var OutputInterface */ private $output; + /** + * @var QuestionHelper + */ + private $questionHelper; + /** + * @var WriterInterface + */ + private $configWriter; + + public function __construct(WriterInterface $configWriter) + { + parent::__construct(null); + $this->configWriter = $configWriter; + } public function configure() { @@ -28,6 +55,7 @@ class InstallCommand extends Command { $this->input = $input; $this->output = $output; + $this->questionHelper = $this->getHelper('question'); $params = []; $output->writeln([ @@ -35,32 +63,186 @@ class InstallCommand extends Command 'This will guide you through the installation process.', ]); - $params['DB_NAME'] = $this->ask('Database name', 'shlink'); - $params['DB_USER'] = $this->ask('Database username'); - $params['DB_PASSWORD'] = $this->ask('Database password'); + // Check if a cached config file exists and drop it if so + if (file_exists('data/cache/app_config.php')) { + $output->write('Deleting old cached config...'); + if (unlink('data/cache/app_config.php')) { + $output->writeln(' Success'); + } else { + $output->writeln( + ' Failed! You will have to manually delete the data/cache/app_config.php file to get' + . ' new config applied.' + ); + } + } + + // Ask for custom config params + $params['DATABASE'] = $this->askDatabase(); + $params['URL_SHORTENER'] = $this->askUrlShortener(); + $params['LANGUAGE'] = $this->askLanguage(); + $params['APP'] = $this->askApplication(); + + // Generate config params files + $config = $this->buildAppConfig($params); + $this->configWriter->toFile('config/params/generated_config.php', $config); + $output->writeln('Custom configuration properly generated!'); + } + + protected function askDatabase() + { + $params = []; + $this->printTitle('DATABASE'); + + // Select database type + $databases = array_keys(self::DATABASE_DRIVERS); + $dbType = $this->questionHelper->ask($this->input, $this->output, new ChoiceQuestion( + 'Select database type (defaults to ' . $databases[0] . '):', + $databases, + 0 + )); + $params['DRIVER'] = self::DATABASE_DRIVERS[$dbType]; + + // Ask for connection params if database is not SQLite + if ($params['DRIVER'] !== self::DATABASE_DRIVERS['SQLite']) { + $params['NAME'] = $this->ask('Database name', 'shlink'); + $params['USER'] = $this->ask('Database username'); + $params['PASSWORD'] = $this->ask('Database password'); + } + + return $params; + } + + protected function askUrlShortener() + { + $this->printTitle('URL SHORTENER'); + + // Ask for URL shortener params + return [ + 'SCHEMA' => $this->questionHelper->ask($this->input, $this->output, new ChoiceQuestion( + 'Select schema for generated short URLs (defaults to http):', + ['http', 'https'], + 0 + )), + 'HOSTNAME' => $this->ask('Hostname for generated URLs'), + 'CHARS' => $this->ask( + 'Character set for generated short codes (leave empty to autogenerate one)', + null, + true + ) ?: str_shuffle(UrlShortener::DEFAULT_CHARS) + ]; + } + + protected function askLanguage() + { + $this->printTitle('LANGUAGE'); + + return [ + 'DEFAULT' => $this->questionHelper->ask($this->input, $this->output, new ChoiceQuestion( + 'Select default language for the application in general (defaults to ' + . self::SUPPORTED_LANGUAGES[0] . '):', + self::SUPPORTED_LANGUAGES, + 0 + )), + 'CLI' => $this->questionHelper->ask($this->input, $this->output, new ChoiceQuestion( + 'Select default language for CLI executions (defaults to ' + . self::SUPPORTED_LANGUAGES[0] . '):', + self::SUPPORTED_LANGUAGES, + 0 + )), + ]; + } + + protected function askApplication() + { + $this->printTitle('APPLICATION'); + + return [ + 'SECRET' => $this->ask( + 'Define a secret string that will be used to sign API tokens (leave empty to autogenerate one)', + null, + true + ) ?: $this->generateRandomString(32), + ]; + } + + /** + * @param string $text + */ + protected function printTitle($text) + { + $text = trim($text); + $length = strlen($text) + 4; + $header = str_repeat('*', $length); + + $this->output->writeln([ + '', + '' . $header . '', + '* ' . strtoupper($text) . ' *', + '' . $header . '', + ]); } /** * @param string $text * @param string|null $default + * @param bool $allowEmpty * @return string */ - protected function ask($text, $default = null) + protected function ask($text, $default = null, $allowEmpty = false) { - /** @var QuestionHelper $questionHelper */ - $questionHelper = $this->getHelper('question'); - if (isset($default)) { $text .= ' (defaults to ' . $default . ')'; } - $value = ''; - while (empty($value) && empty($default)) { - $value = $questionHelper->ask($this->input, $this->output, new Question( - ' ' . $text . ': ', + do { + $value = $this->questionHelper->ask($this->input, $this->output, new Question( + '' . $text . ': ', $default )); - } + if (empty($value) && ! $allowEmpty) { + $this->output->writeln('Value can\'t be empty'); + } + } while (empty($value) && empty($default) && ! $allowEmpty); return $value; } + + /** + * @param array $params + * @return array + */ + protected function buildAppConfig(array $params) + { + // Build simple config + $config = [ + 'app_options' => [ + 'secret_key' => $params['APP']['SECRET'], + ], + 'entity_manager' => [ + 'connection' => [ + 'driver' => $params['DATABASE']['DRIVER'], + ], + ], + 'translator' => [ + 'locale' => $params['LANGUAGE']['DEFAULT'], + ], + 'url_shortener' => [ + 'domain' => [ + 'schema' => $params['URL_SHORTENER']['SCHEMA'], + 'hostname' => $params['URL_SHORTENER']['HOSTNAME'], + ], + 'shortcode_chars' => $params['URL_SHORTENER']['CHARS'], + ], + ]; + + // Build dynamic database config + if ($params['DATABASE']['DRIVER'] === 'pdo_sqlite') { + $config['entity_manager']['connection']['path'] = 'data/database.sqlite'; + } else { + $config['entity_manager']['connection']['user'] = $params['DATABASE']['USER']; + $config['entity_manager']['connection']['password'] = $params['DATABASE']['PASSWORD']; + $config['entity_manager']['connection']['dbname'] = $params['DATABASE']['NAME']; + } + + return $config; + } } diff --git a/module/Rest/config/rest.config.php b/module/Rest/config/rest.config.php deleted file mode 100644 index 223c864f..00000000 --- a/module/Rest/config/rest.config.php +++ /dev/null @@ -1,9 +0,0 @@ - [ - 'username' => env('REST_USER'), - 'password' => env('REST_PASSWORD'), - ], - -]; From fe708333b1ef9b64b189d03fd653faee5be81412 Mon Sep 17 00:00:00 2001 From: Alejandro Celaya Date: Sun, 14 Aug 2016 10:43:16 +0200 Subject: [PATCH 04/19] Fixed path while generating config file --- module/CLI/src/Command/Install/InstallCommand.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module/CLI/src/Command/Install/InstallCommand.php b/module/CLI/src/Command/Install/InstallCommand.php index 8d1c533e..68bba5b8 100644 --- a/module/CLI/src/Command/Install/InstallCommand.php +++ b/module/CLI/src/Command/Install/InstallCommand.php @@ -84,7 +84,7 @@ class InstallCommand extends Command // Generate config params files $config = $this->buildAppConfig($params); - $this->configWriter->toFile('config/params/generated_config.php', $config); + $this->configWriter->toFile(__DIR__ . '/../../../../../config/params/generated_config.php', $config, false); $output->writeln('Custom configuration properly generated!'); } From 9a42d706042136ec901bf44eeeff1c3bfc120482 Mon Sep 17 00:00:00 2001 From: Alejandro Celaya Date: Sun, 14 Aug 2016 18:15:10 +0200 Subject: [PATCH 05/19] Added custom config params to merged confg --- config/config.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/config/config.php b/config/config.php index d722185a..16e483e3 100644 --- a/config/config.php +++ b/config/config.php @@ -4,8 +4,7 @@ use Shlinkio\Shlink\CLI; use Shlinkio\Shlink\Common; use Shlinkio\Shlink\Core; use Shlinkio\Shlink\Rest; -use Zend\Expressive\ConfigManager\ConfigManager; -use Zend\Expressive\ConfigManager\ZendConfigProvider; +use Zend\Expressive\ConfigManager; /** * Configuration files are loaded in a specific order. First ``global.php``, then ``*.global.php``. @@ -16,11 +15,12 @@ use Zend\Expressive\ConfigManager\ZendConfigProvider; * Obviously, if you use closures in your config you can't cache it. */ -return (new ConfigManager([ +return (new ConfigManager\ConfigManager([ ErrorHandlerProvider::class, Common\ConfigProvider::class, Core\ConfigProvider::class, CLI\ConfigProvider::class, Rest\ConfigProvider::class, - new ZendConfigProvider('config/autoload/{{,*.}global,{,*.}local}.php'), + new ConfigManager\ZendConfigProvider('config/autoload/{{,*.}global,{,*.}local}.php'), + new ConfigManager\PhpFileProvider('config/params/generated_config.php'), ], 'data/cache/app_config.php'))->getMergedConfig(); From a608f7d0f4019b11f2645060a0f10c59415bb5d7 Mon Sep 17 00:00:00 2001 From: Alejandro Celaya Date: Sun, 14 Aug 2016 21:28:21 +0200 Subject: [PATCH 06/19] Minor name change --- config/config.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/config/config.php b/config/config.php index 16e483e3..19f84598 100644 --- a/config/config.php +++ b/config/config.php @@ -1,5 +1,5 @@ Date: Sun, 14 Aug 2016 22:56:22 +0200 Subject: [PATCH 07/19] Improved config loading by using only one config provider object --- config/config.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/config/config.php b/config/config.php index 19f84598..5eec4734 100644 --- a/config/config.php +++ b/config/config.php @@ -21,6 +21,5 @@ return (new ConfigManager\ConfigManager([ Core\ConfigProvider::class, CLI\ConfigProvider::class, Rest\ConfigProvider::class, - new ConfigManager\ZendConfigProvider('config/autoload/{{,*.}global,{,*.}local}.php'), - new ConfigManager\PhpFileProvider('config/params/generated_config.php'), + new ConfigManager\ZendConfigProvider('config/{autoload/{{,*.}global,{,*.}local},params/generated_config}.php'), ], 'data/cache/app_config.php'))->getMergedConfig(); From 25380e47273454aa0448316e9a25c796243c3099 Mon Sep 17 00:00:00 2001 From: Alejandro Celaya Date: Sun, 14 Aug 2016 23:08:26 +0200 Subject: [PATCH 08/19] Moved console Application creation to factory --- bin/cli | 8 +------- config/autoload/app_options.global.php | 2 +- module/CLI/config/cli.config.php | 1 + module/CLI/src/Factory/ApplicationFactory.php | 7 ++++++- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/bin/cli b/bin/cli index abbeed47..66086b23 100755 --- a/bin/cli +++ b/bin/cli @@ -2,16 +2,10 @@ get('translator'); -$translator->setLocale(env('CLI_LOCALE', 'en')); - -/** @var Application $app */ +/** @var CliApp $app */ $app = $container->get(CliApp::class); $app->run(); diff --git a/config/autoload/app_options.global.php b/config/autoload/app_options.global.php index 4db642ce..e3f8fbdd 100644 --- a/config/autoload/app_options.global.php +++ b/config/autoload/app_options.global.php @@ -3,7 +3,7 @@ return [ 'app_options' => [ 'name' => 'Shlink', - 'version' => '1.1.0', + 'version' => '1.2.0', 'secret_key' => env('SECRET_KEY'), ], diff --git a/module/CLI/config/cli.config.php b/module/CLI/config/cli.config.php index 1244e259..31c4e460 100644 --- a/module/CLI/config/cli.config.php +++ b/module/CLI/config/cli.config.php @@ -4,6 +4,7 @@ use Shlinkio\Shlink\CLI\Command; return [ 'cli' => [ + 'locale' => env('CLI_LOCALE', 'en'), 'commands' => [ Command\Shortcode\GenerateShortcodeCommand::class, Command\Shortcode\ResolveUrlCommand::class, diff --git a/module/CLI/src/Factory/ApplicationFactory.php b/module/CLI/src/Factory/ApplicationFactory.php index a8e24bf3..d13cce7c 100644 --- a/module/CLI/src/Factory/ApplicationFactory.php +++ b/module/CLI/src/Factory/ApplicationFactory.php @@ -3,7 +3,9 @@ namespace Shlinkio\Shlink\CLI\Factory; use Interop\Container\ContainerInterface; use Interop\Container\Exception\ContainerException; +use Shlinkio\Shlink\Core\Options\AppOptions; use Symfony\Component\Console\Application as CliApp; +use Zend\I18n\Translator\Translator; use Zend\ServiceManager\Exception\ServiceNotCreatedException; use Zend\ServiceManager\Exception\ServiceNotFoundException; use Zend\ServiceManager\Factory\FactoryInterface; @@ -25,9 +27,12 @@ class ApplicationFactory implements FactoryInterface public function __invoke(ContainerInterface $container, $requestedName, array $options = null) { $config = $container->get('config')['cli']; - $app = new CliApp('Shlink', '1.0.0'); + $appOptions = $container->get(AppOptions::class); + $translator = $container->get(Translator::class); + $translator->setLocale($config['locale']); $commands = isset($config['commands']) ? $config['commands'] : []; + $app = new CliApp($appOptions->getName(), $appOptions->getVersion()); foreach ($commands as $command) { if (! $container->has($command)) { continue; From 2617ef15474ab71f6be2682db8a6462d1c1cdbb1 Mon Sep 17 00:00:00 2001 From: Alejandro Celaya Date: Sun, 14 Aug 2016 23:10:07 +0200 Subject: [PATCH 09/19] Added cli locale to installation generated config file --- module/CLI/src/Command/Install/InstallCommand.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/module/CLI/src/Command/Install/InstallCommand.php b/module/CLI/src/Command/Install/InstallCommand.php index 68bba5b8..39fdebe6 100644 --- a/module/CLI/src/Command/Install/InstallCommand.php +++ b/module/CLI/src/Command/Install/InstallCommand.php @@ -225,6 +225,9 @@ class InstallCommand extends Command 'translator' => [ 'locale' => $params['LANGUAGE']['DEFAULT'], ], + 'cli' => [ + 'locale' => $params['LANGUAGE']['CLI'], + ], 'url_shortener' => [ 'domain' => [ 'schema' => $params['URL_SHORTENER']['SCHEMA'], From 1f3e31d1002b9467655f9a15554c7349bcd265f5 Mon Sep 17 00:00:00 2001 From: Alejandro Celaya Date: Sun, 14 Aug 2016 23:25:04 +0200 Subject: [PATCH 10/19] Fixed working directory and paths in InstallCommand --- bin/install | 2 +- module/CLI/src/Command/Install/InstallCommand.php | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/bin/install b/bin/install index b1ce8a1e..c47036a9 100755 --- a/bin/install +++ b/bin/install @@ -4,7 +4,7 @@ use Shlinkio\Shlink\CLI\Command\Install\InstallCommand; use Symfony\Component\Console\Application; use Zend\Config\Writer\PhpArray; -chdir(dirname(__DIR__) . '/..'); +chdir(dirname(__DIR__)); require __DIR__ . '/../vendor/autoload.php'; diff --git a/module/CLI/src/Command/Install/InstallCommand.php b/module/CLI/src/Command/Install/InstallCommand.php index 39fdebe6..785a004f 100644 --- a/module/CLI/src/Command/Install/InstallCommand.php +++ b/module/CLI/src/Command/Install/InstallCommand.php @@ -60,7 +60,7 @@ class InstallCommand extends Command $output->writeln([ 'Welcome to Shlink!!', - 'This will guide you through the installation process.', + 'This process will guide you through the installation.', ]); // Check if a cached config file exists and drop it if so @@ -84,7 +84,7 @@ class InstallCommand extends Command // Generate config params files $config = $this->buildAppConfig($params); - $this->configWriter->toFile(__DIR__ . '/../../../../../config/params/generated_config.php', $config, false); + $this->configWriter->toFile('config/params/generated_config.php', $config, false); $output->writeln('Custom configuration properly generated!'); } From 4bbdccf9819f427176a1eb22ab070d2b77b55cf2 Mon Sep 17 00:00:00 2001 From: Alejandro Celaya Date: Sun, 14 Aug 2016 23:40:54 +0200 Subject: [PATCH 11/19] Added symfony process to run initialization commands --- .gitignore | 1 + composer.json | 1 + .../CLI/src/Command/Install/InstallCommand.php | 18 +++++++++++++++++- 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 9695be68..aebab397 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ build composer.lock vendor/ .env +data/database.sqlite diff --git a/composer.json b/composer.json index b8dc3f63..88c74604 100644 --- a/composer.json +++ b/composer.json @@ -27,6 +27,7 @@ "doctrine/orm": "^2.5", "guzzlehttp/guzzle": "^6.2", "symfony/console": "^3.0", + "symfony/process": "^3.0", "firebase/php-jwt": "^4.0", "monolog/monolog": "^1.21", "theorchard/monolog-cascade": "^0.4", diff --git a/module/CLI/src/Command/Install/InstallCommand.php b/module/CLI/src/Command/Install/InstallCommand.php index 785a004f..bb19514f 100644 --- a/module/CLI/src/Command/Install/InstallCommand.php +++ b/module/CLI/src/Command/Install/InstallCommand.php @@ -4,6 +4,7 @@ namespace Shlinkio\Shlink\CLI\Command\Install; use Shlinkio\Shlink\Common\Util\StringUtilsTrait; use Shlinkio\Shlink\Core\Service\UrlShortener; use Symfony\Component\Console\Command\Command; +use Symfony\Component\Console\Helper\ProcessHelper; use Symfony\Component\Console\Helper\QuestionHelper; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; @@ -34,6 +35,10 @@ class InstallCommand extends Command * @var QuestionHelper */ private $questionHelper; + /** + * @var ProcessHelper + */ + private $processHelper; /** * @var WriterInterface */ @@ -56,6 +61,7 @@ class InstallCommand extends Command $this->input = $input; $this->output = $output; $this->questionHelper = $this->getHelper('question'); + $this->processHelper = $this->getHelper('process'); $params = []; $output->writeln([ @@ -85,7 +91,17 @@ class InstallCommand extends Command // Generate config params files $config = $this->buildAppConfig($params); $this->configWriter->toFile('config/params/generated_config.php', $config, false); - $output->writeln('Custom configuration properly generated!'); + $output->writeln(['Custom configuration properly generated!', '']); + + // Generate database + $output->write('Initializing database...'); + $this->processHelper->run($output, 'php vendor/bin/doctrine.php orm:schema-tool:create'); + $output->writeln(' Success!'); + + // Generate proxies + $output->write('Generating proxies...'); + $this->processHelper->run($output, 'php vendor/bin/doctrine.php orm:generate-proxies'); + $output->writeln(' Success!'); } protected function askDatabase() From 804d99ebf72223d1fd463d11493aea1854116667 Mon Sep 17 00:00:00 2001 From: Alejandro Celaya Date: Mon, 15 Aug 2016 09:21:14 +0200 Subject: [PATCH 12/19] Created CLI scripts for Windows OS --- bin/cli | 9 +-------- bin/cli.php | 10 ++++++++++ bin/install | 12 +----------- bin/install.php | 14 ++++++++++++++ 4 files changed, 26 insertions(+), 19 deletions(-) create mode 100644 bin/cli.php create mode 100755 bin/install.php diff --git a/bin/cli b/bin/cli index 66086b23..6f752583 100755 --- a/bin/cli +++ b/bin/cli @@ -1,11 +1,4 @@ #!/usr/bin/env php get(CliApp::class); -$app->run(); +include 'cli.php'; diff --git a/bin/cli.php b/bin/cli.php new file mode 100644 index 00000000..d15f1eef --- /dev/null +++ b/bin/cli.php @@ -0,0 +1,10 @@ +get(CliApp::class); +$app->run(); diff --git a/bin/install b/bin/install index c47036a9..fde1f4a7 100755 --- a/bin/install +++ b/bin/install @@ -1,14 +1,4 @@ #!/usr/bin/env php add(new InstallCommand(new PhpArray())); -$app->setDefaultCommand('shlink:install'); -$app->run(); +include 'install.php'; diff --git a/bin/install.php b/bin/install.php new file mode 100755 index 00000000..c47036a9 --- /dev/null +++ b/bin/install.php @@ -0,0 +1,14 @@ +#!/usr/bin/env php +add(new InstallCommand(new PhpArray())); +$app->setDefaultCommand('shlink:install'); +$app->run(); From 9e4fb682650957e498a5d0b0912c75c9394ccba0 Mon Sep 17 00:00:00 2001 From: Alejandro Celaya Date: Mon, 15 Aug 2016 09:45:09 +0200 Subject: [PATCH 13/19] Created build script --- build.sh | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 build.sh diff --git a/build.sh b/build.sh new file mode 100644 index 00000000..6b309efc --- /dev/null +++ b/build.sh @@ -0,0 +1,33 @@ +#!/usr/bin/env bash + +builtcontent=$(readlink -f '../shlink_build_tmp') +projectdir=$(pwd) + +# Copy project content to temp dir +echo 'Copying project files...' +rm -rf "${builtcontent}" +mkdir "${builtcontent}" +cp -R "${projectdir}"/* "${builtcontent}" +cd ${builtcontent} + +# Install dependencies +rm -r vendor +rm composer.lock +composer self-update +composer install --no-dev --optimize-autoloader + +# Delete development files +echo 'Deleting dev files...' +rm build.sh +rm CHANGELOG.md +rm composer.* +rm LICENSE +rm php* +rm README.md +rm -r build +rm data/database.sqlite +rm data/{cache,log,proxies}/{*,.gitignore} +rm config/params/{*,.gitignore} +rm config/autoload/{*.local.php{,.dist},.gitignore} + +# Compressing file From 00c56ca5945ee86e2dd2bdbb6a0bcd7d1d1571b2 Mon Sep 17 00:00:00 2001 From: Alejandro Celaya Date: Mon, 15 Aug 2016 09:52:44 +0200 Subject: [PATCH 14/19] Fixed tests --- build.sh | 3 ++- module/CLI/test/Factory/ApplicationFactoryTest.php | 6 +++++- module/Rest/test/ConfigProviderTest.php | 1 - 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/build.sh b/build.sh index 6b309efc..11dc2ae8 100644 --- a/build.sh +++ b/build.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +set -e builtcontent=$(readlink -f '../shlink_build_tmp') projectdir=$(pwd) @@ -28,6 +29,6 @@ rm -r build rm data/database.sqlite rm data/{cache,log,proxies}/{*,.gitignore} rm config/params/{*,.gitignore} -rm config/autoload/{*.local.php{,.dist},.gitignore} +rm config/autoload/{{,*.}local.php{,.dist},.gitignore} # Compressing file diff --git a/module/CLI/test/Factory/ApplicationFactoryTest.php b/module/CLI/test/Factory/ApplicationFactoryTest.php index 1c486e55..9f1206a8 100644 --- a/module/CLI/test/Factory/ApplicationFactoryTest.php +++ b/module/CLI/test/Factory/ApplicationFactoryTest.php @@ -3,8 +3,10 @@ namespace ShlinkioTest\Shlink\CLI\Factory; use PHPUnit_Framework_TestCase as TestCase; use Shlinkio\Shlink\CLI\Factory\ApplicationFactory; +use Shlinkio\Shlink\Core\Options\AppOptions; use Symfony\Component\Console\Application; use Symfony\Component\Console\Command\Command; +use Zend\I18n\Translator\Translator; use Zend\ServiceManager\ServiceManager; class ApplicationFactoryTest extends TestCase @@ -53,8 +55,10 @@ class ApplicationFactoryTest extends TestCase { return new ServiceManager(['services' => [ 'config' => [ - 'cli' => $config, + 'cli' => array_merge($config, ['locale' => 'en']), ], + AppOptions::class => new AppOptions(), + Translator::class => Translator::factory([]), ]]); } } diff --git a/module/Rest/test/ConfigProviderTest.php b/module/Rest/test/ConfigProviderTest.php index 6801a82b..0270183f 100644 --- a/module/Rest/test/ConfigProviderTest.php +++ b/module/Rest/test/ConfigProviderTest.php @@ -25,7 +25,6 @@ class ConfigProviderTest extends TestCase $this->assertArrayHasKey('error_handler', $config); $this->assertArrayHasKey('middleware_pipeline', $config); - $this->assertArrayHasKey('rest', $config); $this->assertArrayHasKey('routes', $config); $this->assertArrayHasKey('dependencies', $config); $this->assertArrayHasKey('translator', $config); From 0d9f9646878ddbcb04761bb0977ab7af5fb2fd0c Mon Sep 17 00:00:00 2001 From: Alejandro Celaya Date: Mon, 15 Aug 2016 10:03:17 +0200 Subject: [PATCH 15/19] Fixed bug on build script --- build.sh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/build.sh b/build.sh index 11dc2ae8..d3b80309 100644 --- a/build.sh +++ b/build.sh @@ -9,7 +9,7 @@ echo 'Copying project files...' rm -rf "${builtcontent}" mkdir "${builtcontent}" cp -R "${projectdir}"/* "${builtcontent}" -cd ${builtcontent} +cd "${builtcontent}" # Install dependencies rm -r vendor @@ -26,9 +26,9 @@ rm LICENSE rm php* rm README.md rm -r build -rm data/database.sqlite -rm data/{cache,log,proxies}/{*,.gitignore} -rm config/params/{*,.gitignore} -rm config/autoload/{{,*.}local.php{,.dist},.gitignore} +rm -f data/database.sqlite +rm -f data/{cache,log,proxies}/{*,.gitignore} +rm -f config/params/{*,.gitignore} +rm -f config/autoload/{{,*.}local.php{,.dist},.gitignore} # Compressing file From f852f9d398d15859e5f5f34ec81efa3aee5eec7b Mon Sep 17 00:00:00 2001 From: Alejandro Celaya Date: Mon, 15 Aug 2016 10:03:39 +0200 Subject: [PATCH 16/19] Created htaccess --- public/.htaccess | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 public/.htaccess diff --git a/public/.htaccess b/public/.htaccess new file mode 100644 index 00000000..a5c40815 --- /dev/null +++ b/public/.htaccess @@ -0,0 +1,17 @@ +RewriteEngine On +# The following rule tells Apache that if the requested filename +# exists, simply serve it. +RewriteCond %{REQUEST_FILENAME} -s [OR] +RewriteCond %{REQUEST_FILENAME} -l [OR] +RewriteCond %{REQUEST_FILENAME} -d +RewriteRule ^.*$ - [NC,L] + +# The following rewrites all other queries to index.php. The +# condition ensures that if you are using Apache aliases to do +# mass virtual hosting, the base path will be prepended to +# allow proper resolution of the index.php file; it will work +# in non-aliased environments as well, providing a safe, one-size +# fits all solution. +RewriteCond %{REQUEST_URI}::$1 ^(/.+)(.+)::\2$ +RewriteRule ^(.*) - [E=BASE:%1] +RewriteRule ^(.*)$ %{ENV:BASE}index.php [NC,L] From d5516c72697cd899fac147cc3f93981ea5918c07 Mon Sep 17 00:00:00 2001 From: Alejandro Celaya Date: Mon, 15 Aug 2016 10:18:13 +0200 Subject: [PATCH 17/19] Finished build script to compress dist project file --- build.sh | 10 ++++++++++ 1 file changed, 10 insertions(+) mode change 100644 => 100755 build.sh diff --git a/build.sh b/build.sh old mode 100644 new mode 100755 index d3b80309..6dc1afcc --- a/build.sh +++ b/build.sh @@ -1,6 +1,13 @@ #!/usr/bin/env bash set -e +if [ "$#" -ne 1 ]; then + echo "Usage:" >&2 + echo " $0 {version}" >&2 + exit 1 +fi + +version=$1 builtcontent=$(readlink -f '../shlink_build_tmp') projectdir=$(pwd) @@ -32,3 +39,6 @@ rm -f config/params/{*,.gitignore} rm -f config/autoload/{{,*.}local.php{,.dist},.gitignore} # Compressing file +rm -f "${projectdir}"/build/Shlink_${version}.dist.zip +zip -r "${projectdir}"/build/Shlink_${version}.dist.zip "${builtcontent}" +rm -rf "${builtcontent}" From 5bbc7de4afa6643dadcf3c9a41cff63b5ca83909 Mon Sep 17 00:00:00 2001 From: Alejandro Celaya Date: Mon, 15 Aug 2016 11:01:55 +0200 Subject: [PATCH 18/19] Fixed namespace in some tests --- .../Command/{ => Shortcode}/GenerateShortcodeCommandTest.php | 2 +- .../CLI/test/Command/{ => Shortcode}/GetVisitsCommandTest.php | 2 +- .../test/Command/{ => Shortcode}/ListShortcodesCommandTest.php | 2 +- .../CLI/test/Command/{ => Shortcode}/ResolveUrlCommandTest.php | 2 +- .../CLI/test/Command/{ => Visit}/ProcessVisitsCommandTest.php | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) rename module/CLI/test/Command/{ => Shortcode}/GenerateShortcodeCommandTest.php (97%) rename module/CLI/test/Command/{ => Shortcode}/GetVisitsCommandTest.php (98%) rename module/CLI/test/Command/{ => Shortcode}/ListShortcodesCommandTest.php (98%) rename module/CLI/test/Command/{ => Shortcode}/ResolveUrlCommandTest.php (98%) rename module/CLI/test/Command/{ => Visit}/ProcessVisitsCommandTest.php (98%) diff --git a/module/CLI/test/Command/GenerateShortcodeCommandTest.php b/module/CLI/test/Command/Shortcode/GenerateShortcodeCommandTest.php similarity index 97% rename from module/CLI/test/Command/GenerateShortcodeCommandTest.php rename to module/CLI/test/Command/Shortcode/GenerateShortcodeCommandTest.php index 011dcb32..43367f31 100644 --- a/module/CLI/test/Command/GenerateShortcodeCommandTest.php +++ b/module/CLI/test/Command/Shortcode/GenerateShortcodeCommandTest.php @@ -1,5 +1,5 @@ Date: Mon, 15 Aug 2016 11:34:35 +0200 Subject: [PATCH 19/19] Added InstallCommandTest --- .../Command/Install/InstallCommandTest.php | 101 ++++++++++++++++++ 1 file changed, 101 insertions(+) create mode 100644 module/CLI/test/Command/Install/InstallCommandTest.php diff --git a/module/CLI/test/Command/Install/InstallCommandTest.php b/module/CLI/test/Command/Install/InstallCommandTest.php new file mode 100644 index 00000000..6fb2ee79 --- /dev/null +++ b/module/CLI/test/Command/Install/InstallCommandTest.php @@ -0,0 +1,101 @@ +prophesize(ProcessHelper::class); + $processHelper->getName()->willReturn('process'); + $processHelper->setHelperSet(Argument::any())->willReturn(null); + $processHelper->run(Argument::cetera())->willReturn(null); + + $app = new Application(); + $helperSet = $app->getHelperSet(); + $helperSet->set($processHelper->reveal()); + $app->setHelperSet($helperSet); + + $this->configWriter = $this->prophesize(WriterInterface::class); + $command = new InstallCommand($this->configWriter->reveal()); + $app->add($command); + + $questionHelper = $command->getHelper('question'); + $questionHelper->setInputStream($this->createInputStream()); + $this->commandTester = new CommandTester($command); + } + + protected function createInputStream() + { + $stream = fopen('php://memory', 'r+', false); + fputs($stream, <<configWriter->toFile(Argument::any(), [ + 'app_options' => [ + 'secret_key' => 'my_secret', + ], + 'entity_manager' => [ + 'connection' => [ + 'driver' => 'pdo_mysql', + 'dbname' => 'shlink_db', + 'user' => 'alejandro', + 'password' => '1234', + ], + ], + 'translator' => [ + 'locale' => 'en', + ], + 'cli' => [ + 'locale' => 'es', + ], + 'url_shortener' => [ + 'domain' => [ + 'schema' => 'http', + 'hostname' => 'doma.in', + ], + 'shortcode_chars' => 'abc123BCA', + ], + ], false)->shouldBeCalledTimes(1); + $this->commandTester->execute([ + 'command' => 'shlink:install', + ]); + } +}