diff --git a/.gitignore b/.gitignore index 28eb5fc..0d685da 100644 --- a/.gitignore +++ b/.gitignore @@ -2,7 +2,7 @@ /.mage/logs/*.log /composer.lock /vendor/ -/propel.yml +/propel.yaml /src/Gist/Model/Base/ /src/Gist/Model/Map/ /web/components/ diff --git a/app/config/propel.yaml.dist-mysql b/app/config/propel.yaml.dist-mysql new file mode 100644 index 0000000..fa13d75 --- /dev/null +++ b/app/config/propel.yaml.dist-mysql @@ -0,0 +1,32 @@ +propel: + database: + connections: + default: + adapter: mysql + classname: Propel\Runtime\Connection\ConnectionWrapper + dsn: "mysql:host=DATABASE_HOST;dbname=DATABASE_NAME" + user: "DATABASE_USERNAME" + password: "DATABASE_PASSWORD" + settings: + charset: utf8 + queries: + utf8: "SET NAMES utf8 COLLATE utf8_unicode_ci, COLLATION_CONNECTION = utf8_unicode_ci, COLLATION_DATABASE = utf8_unicode_ci, COLLATION_SERVER = utf8_unicode_ci" + + paths: + projectDir: src/ + schemaDir: src/ + outputDir: src/ + phpDir: src/ + phpConfDir: app/config/propel + sqlDir: app/propel/sql + migrationDir: app/propel/migration + + runtime: + defaultConnection: default + connections: [default] + + generator: + defaultConnection: default + connections: [default] + objectModel: + addClassLevelComment: false diff --git a/app/config/propel.yaml.dist-sqlite b/app/config/propel.yaml.dist-sqlite new file mode 100644 index 0000000..8580a0b --- /dev/null +++ b/app/config/propel.yaml.dist-sqlite @@ -0,0 +1,32 @@ +propel: + database: + connections: + default: + adapter: mysql + classname: Propel\Runtime\Connection\ConnectionWrapper + dsn: "sqlite:DATABASE_PATH" + user: ~ + password: ~ + settings: + charset: utf8 + queries: + utf8: "SET NAMES utf8 COLLATE utf8_unicode_ci, COLLATION_CONNECTION = utf8_unicode_ci, COLLATION_DATABASE = utf8_unicode_ci, COLLATION_SERVER = utf8_unicode_ci" + + paths: + projectDir: src/ + schemaDir: src/ + outputDir: src/ + phpDir: src/ + phpConfDir: app/config/propel + sqlDir: app/propel/sql + migrationDir: app/propel/migration + + runtime: + defaultConnection: default + connections: [default] + + generator: + defaultConnection: default + connections: [default] + objectModel: + addClassLevelComment: false diff --git a/composer.json b/composer.json index cc07da5..14cd8e1 100644 --- a/composer.json +++ b/composer.json @@ -15,6 +15,17 @@ "guzzlehttp/guzzle": "~6.0", "symfony/security": "^2.7" }, + "scripts": { + "gist-scripts": [ + "Gist\\Composer\\PostInstallHandler::execute" + ], + "post-install-cmd": [ + "@gist-scripts" + ], + "post-update-cmd": [ + "@gist-scripts" + ] + }, "autoload": { "psr-0": { "": "src/" diff --git a/propel-dist.yaml b/propel-dist.yaml index dd6f836..e88311b 100644 --- a/propel-dist.yaml +++ b/propel-dist.yaml @@ -4,9 +4,9 @@ propel: default: adapter: mysql classname: Propel\Runtime\Connection\ConnectionWrapper - dsn: "mysql:host=localhost;dbname=gist" - user: root - password: root + dsn: "mysql:host=DATABASE_HOST;dbname=DATABASE_NAME" + user: "DATABASE_USER" + password: "DATABASE_PASSWORD" settings: charset: utf8 queries: diff --git a/src/Gist/Composer/PostInstallHandler.php b/src/Gist/Composer/PostInstallHandler.php new file mode 100644 index 0000000..81650a0 --- /dev/null +++ b/src/Gist/Composer/PostInstallHandler.php @@ -0,0 +1,211 @@ + + */ +class PostInstallHandler +{ + public static function execute(Event $event) + { + $helper = new QuestionHelper(); + $input = new ArgvInput(); + $output = new ConsoleOutput(); + $filesystem = new Filesystem(); + + $output->writeln('+==============================+'); + $output->writeln('| GIST Setup |'); + $output->writeln('+==============================+'); + $output->writeln(''); + $output->writeln('1. Database'); + $output->writeln('==========='); + + $configure = true; + if ($filesystem->exists('propel.yaml')) { + $output->writeln('The configuration file exists.'); + $question = new ConfirmationQuestion('Your current configuration will not be merged. Do you want to override it? [y/N] ', false); + $configure = $helper->ask($input, $output, $question); + } else { + $configure = true; + } + + if ($configure) { + $choices = ['MySQL/MariaDB', 'SQLite', 'other']; + $question = new ChoiceQuestion('Which DBMS? ', $choices, 0); + $dbms = $helper->ask($input, $output, $question); + $substitutions = []; + + if ($dbms === 'MySQL/MariaDB') { + $templateName = 'propel.yaml.dist-mysql'; + + $question = new Question('Host: [127.0.0.1] ', '127.0.0.1'); + $substitutions['DATABASE_HOST'] = $helper->ask($input, $output, $question); + + $question = new Question('Database (it must exists!): [gist] ', 'gist'); + $substitutions['DATABASE_NAME'] = $helper->ask($input, $output, $question); + + $question = new Question('Username: [root] ', 'root'); + $substitutions['DATABASE_USERNAME'] = $helper->ask($input, $output, $question); + + $question = new Question('Password: [] ', ''); + $substitutions['DATABASE_PASSWORD'] = $helper->ask($input, $output, $question); + } elseif ($dbms === 'SQLite') { + $defaultPath = getcwd().'/app/data/gist.sqlite'; + $question = new Question("Ok! Where do you want me to save datas? [$defaultPath] ", $defaultPath); + $substitutions['DATABASE_PATH'] = $helper->ask($input, $output, $question); + $templateName = 'propel.yaml.dist-sqlite'; + } else { + $output->writeln('See README.md to perform the configuration.'); + + return; + } + + $template = file_get_contents('app/config/'.$templateName); + $content = str_replace( + array_keys($substitutions), + array_values($substitutions), + $template + ); + + $done = file_put_contents('propel.yaml', $content) !== false; + + if ($done) { + $output->writeln('Running migration...'); + + foreach (['config:convert', 'model:build --recursive', 'migration:diff --recursive', 'migration:migrate --recursive'] as $arg) { + $command = self::getPhp(true).' ./vendor/propel/propel/bin/propel '.$arg; + $process = new Process($command); + $process->run(); + + if (!$process->isSuccessful()) { + $output->writeln('An error occured while executing:'); + $output->writeln($command); + $output->writeln('To perform the configuration. See README.md.'); + + return; + } + } + + $output->writeln('Done!'); + } else { + $output->writeln('An error occured. See README.md to perform the configuration.'); + } + } + + $output->writeln(''); + $output->writeln('2. Application'); + $output->writeln('=============='); + + $configure = true; + if ($filesystem->exists('app/config/config.yml')) { + $output->writeln('The configuration file exists.'); + $question = new ConfirmationQuestion('Your current configuration will not be merged. Do you want to override it? [y/N] ', false); + $configure = $helper->ask($input, $output, $question); + } else { + $configure = true; + } + + if ($configure) { + $output->writeln(''); + $output->writeln(' 2.1 Security'); + $output->writeln('-------------'); + + $token = str_shuffle(sha1(microtime().uniqid())); + + $question = new ConfirmationQuestion('Registration enabled: [Y/n] ', true); + $enableRegistration = $helper->ask($input, $output, $question); + + $question = new ConfirmationQuestion('Login enabled: [Y/n] ', true); + $enableLogin = $helper->ask($input, $output, $question); + + $question = new ConfirmationQuestion('Login required to edit a gist: [y/N] ', false); + $loginRequiredToEditGist = $helper->ask($input, $output, $question); + + $question = new ConfirmationQuestion('Login required to view a gist: [y/N] ', false); + $loginRequiredToViewGist = $helper->ask($input, $output, $question); + + $question = new ConfirmationQuestion('Login required to view an embeded gist: [y/N] ', false); + $loginRequiredToViewEmbededGist = $helper->ask($input, $output, $question); + + $output->writeln(''); + $output->writeln(' 2.2 API'); + $output->writeln('--------'); + + $question = new ConfirmationQuestion('API enabled: [Y/n] ', true); + $apiEnabled = $helper->ask($input, $output, $question); + + if ($apiEnabled) { + $question = new ConfirmationQuestion('API key required: [y/N] ', false); + $apikeyRequired = $helper->ask($input, $output, $question); + } else { + $apikeyRequired = false; + } + + $question = new Question('[Client] API base URL: [https://gist.deblan.org/] ', 'https://gist.deblan.org/'); + $apiBaseUrl = $helper->ask($input, $output, $question); + + $question = new Question('[Client] API key: [] ', ''); + $apiClientApiKey = $helper->ask($input, $output, $question); + + $configuration = [ + 'security' => [ + 'token' => $token, + 'enable_registration' => $enableRegistration, + 'enable_login' => $enableLogin, + 'login_required_to_edit_gist' => $loginRequiredToEditGist, + 'login_required_to_view_gist' => $loginRequiredToViewGist, + 'login_required_to_view_embeded_gist' => $loginRequiredToViewEmbededGist, + ], + 'api' => [ + 'enabled' => $apiEnabled, + 'api_key_required' => $apikeyRequired, + 'base_url' => $apiBaseUrl, + 'client' => [ + 'api_key' => $apiClientApiKey, + ], + ], + 'data' => [ + 'path' => 'data/git', + ], + 'git' => [ + 'path' => '/usr/bin/git', + ], + 'theme' => [ + 'name' => 'dark', + ], + ]; + + $content = (new Yaml())->dump($configuration); + + $done = file_put_contents('app/config/config.yml', $content); + } + + $output->writeln(''); + $output->writeln('Configuration finished!'); + } + + protected static function getPhp($includeArgs = true) + { + $phpFinder = new PhpExecutableFinder(); + if (!$phpPath = $phpFinder->find($includeArgs)) { + throw new \RuntimeException('The php executable could not be found, add it to your PATH environment variable and try again'); + } + + return $phpPath; + } +}