diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e42655d --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/Libraries/ \ No newline at end of file diff --git a/Classes/Command/AbstractCommand.php b/Classes/Command/AbstractCommand.php new file mode 100644 index 0000000..0a290f9 --- /dev/null +++ b/Classes/Command/AbstractCommand.php @@ -0,0 +1,41 @@ +configuration = \Symfony\Component\Yaml\Yaml::parse(file_get_contents(__DIR__ . '/../../Configuration/Rosemary.yaml')); + } + + public function output($text, array $arguments = array()) { + if ($arguments !== array()) { + $text = vsprintf($text, $arguments); + } + $this->output->write($text); + } + + public function outputLine($text = '', array $arguments = array()) { + return $this->output($text . PHP_EOL, $arguments); + } + + public function quit($exitCode = 0) { + die($exitCode); + } + +} \ No newline at end of file diff --git a/Classes/Command/CreateCommand.php b/Classes/Command/CreateCommand.php new file mode 100644 index 0000000..24d1c18 --- /dev/null +++ b/Classes/Command/CreateCommand.php @@ -0,0 +1,251 @@ +setName('create') + ->setDescription('Create blank project') + ->addArgument('name', \Symfony\Component\Console\Input\InputArgument::REQUIRED, 'Set the name of the installation') + ->addArgument('source', \Symfony\Component\Console\Input\InputArgument::REQUIRED, 'Set the source fof the installation. Can be a packagist package "vendor/package" or a git reposirory "git@github.com:user/vendor-package.git"'); + } + + protected function execute(\Symfony\Component\Console\Input\InputInterface $input, \Symfony\Component\Console\Output\OutputInterface $output) { + $this->input = $input; + $this->output = $output; + + try { + $this->validateArgumentSource($input->getArgument('source')); + $this->validateArgumentName($input->getArgument('name')); + } catch (Exception $e) { + die('Error on validate arguments'); + } + + try { + $this->task_createDirectories(); + $this->task_cloneSource(); + $this->task_createDatabase(); + $this->task_updateSettings(); + $this->task_setfilepermissions(); + $this->task_createVhost(); + } catch (Exception $e) { + + } + } + /******************************************************************************************************************* + * + ******************************************************************************************************************/ + + /** + * @param $source + * @return bool + */ + protected function validateArgumentSource($source) { + $this->installationSource = $source; + + if (preg_match('*((git|ssh|http(s)?)|(git@[\w\.]+))(:(//)?)([\w\.@\:/\-~]+)(\.git)(/)?*i', $source)) { + $this->installationType = 'git'; + } else { + $this->installationType = 'composer'; + } + + return TRUE; + } + + /** + * @param $name + * @return bool + */ + protected function validateArgumentName($name) { + $this->installationName = $name; + return TRUE; + } + + + /******************************************************************************************************************* + * + ******************************************************************************************************************/ + + /** + * + */ + private function task_createDirectories() { + $this->output->writeln(vsprintf('Creating directory structure at: %s', array($this->configuration['locations']['document_root'] . strtolower($this->installationName)))); + + $baseDir = $this->configuration['locations']['document_root'] . strtolower($this->installationName) . '/'; + + if (!mkdir($baseDir, 0777)) { + $this->outputLine('Failed to create folders...'); + $this->quit(1); + } + + if (!mkdir($baseDir . 'logs/', 0777, TRUE)) { + $this->outputLine('Failed to create folders...'); + $this->quit(1); + } + + if (!mkdir($baseDir . 'sync/', 0777, TRUE)) { + $this->outputLine('Failed to create folders...'); + $this->quit(1); + } + + #if (!mkdir($baseDir . 'flow/Data/Logs/', 0777, TRUE)) { + # die('Failed to create folders...'); + #} + } + + private function task_cloneSource() { + $this->outputLine('Cloning base package'); + if ($this->installationType == 'composer') { + $this->outputLine(' Running composer: php /path/to/composer.phar create-project %s %s', array( + $this->installationSource, + $this->configuration['locations']['document_root'] . $this->installationName + )); + + chdir($this->configuration['locations']['document_root'] . strtolower($this->installationName) . '/'); + system(vsprintf( + 'composer --verbose --no-progress --no-interaction --keep-vcs create-project %s flow', + array( + $this->installationSource + ) + )); + + } else { + $this->outputLine(' Running git: git clone %s flow', array( + $this->installationSource, + )); + + chdir($this->configuration['locations']['document_root'] . strtolower($this->installationName) . '/'); + system(vsprintf( + 'git clone %s flow', + array( + $this->installationSource + ) + )); + + chdir($this->configuration['locations']['document_root'] . strtolower($this->installationName) . '/flow/'); + system(vsprintf( + 'composer --verbose --no-progress --no-interaction install', + array() + )); + } + } + + private function task_createDatabase() { + + $this->outputLine('Create database: %s', array( + strtolower($this->installationName) + )); + + $this->outputLine(' Running: mysql -h %s -u %s %s -e "CREATE DATABASE %s DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci;"', array( + $this->configuration['database_root']['host'], + $this->configuration['database_root']['username'], + ($this->configuration['database_root']['password'] != '') ? '-p' . $this->configuration['database_root']['password'] : '', + strtolower($this->installationName) + )); + + system(vsprintf( + 'mysql -h %s -u %s %s -e "DROP DATABASE IF EXISTS %s; CREATE DATABASE %s DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci;"', + array( + $this->configuration['database_root']['host'], + $this->configuration['database_root']['username'], + ($this->configuration['database_root']['password'] != '') ? '-p' . $this->configuration['database_root']['password'] : '', + strtolower($this->installationName), + strtolower($this->installationName) + ) + )); + } + + private function task_updateSettings() { + $this->outputLine('Updating Configuration/Settings.yaml'); + $fileContent = array( + '# #', + '# Example Settings #', + '# #', + '# This file contains settings for various parts of the application. #', + '# Copy this file to Settings.yaml, and adjust as necessary. #', + '# #', + '# Please refer to the default settings file(s) or the manuals for #', + '# possible configuration options. #', + '# #', + '', + '', + 'TYPO3:', + ' FLOW3:', + ' persistence:', + ' backendOptions:', + ' driver: pdo_mysql', + ' host: ' . $this->configuration['database']['host'], + ' dbname: ' . strtolower($this->installationName), + ' user: ' . $this->configuration['database']['username'], + ' password: ' . $this->configuration['database']['password'], + ); + file_put_contents($this->configuration['locations']['document_root'] . $this->installationName . '/' . $this->configuration['locations']['flow_dir'] . 'Configuration/Settings.yaml', implode("\n", $fileContent)); + + } + + private function task_setfilepermissions() { + $this->outputLine('Adjust file permissions for CLI and web server access'); + $this->outputLine( + 'Running: sudo ./flow flow:core:setfilepermissions %s %s %s', + array( + $this->configuration['permissions']['owner'], + $this->configuration['permissions']['group'], + $this->configuration['permissions']['group'] + ) + ); + + chdir($this->configuration['locations']['document_root'] . $this->installationName . '/' . $this->configuration['locations']['flow_dir']); + system(vsprintf( + 'sudo ./flow flow:core:setfilepermissions %s %s %s', + array( + $this->configuration['permissions']['owner'], + $this->configuration['permissions']['group'], + $this->configuration['permissions']['group'] + ) + )); + } + + private function task_createVhost() { + $this->outputLine('Creating virtual host: "%s"', array($this->configuration['locations']['apache_sites'] . '20-' . strtolower($this->installationName) . '.conf')); + + $fileContent = array( + '', + ' ServerName ' . strtolower($this->installationName) . '.dev', + '', + ' ## Vhost docroot', + ' DocumentRoot "' . $this->configuration['locations']['document_root'] . $this->installationName . '/' . $this->configuration['locations']['flow_dir'] . '/Web"', + '', + ' configuration['locations']['document_root'] . $this->installationName . '/' . $this->configuration['locations']['flow_dir'] . '/Web">', + ' AllowOverride All', + ' Order allow,deny', + ' Allow from all', + ' ', + '', + ' ## Load additional static includes', + '', + ' ## Logging', + ' ErrorLog "' . $this->configuration['locations']['document_root'] . $this->installationName . '/logs/error.log"', + ' ServerSignature Off', + ' CustomLog "' . $this->configuration['locations']['document_root'] . $this->installationName . '/logs/access.log" combined', + '' + ); + + file_put_contents($this->configuration['locations']['apache_sites'] . '/20-' . strtolower($this->installationName) . '.conf', implode("\n", $fileContent)); + + } + +} \ No newline at end of file diff --git a/Classes/Command/DeleteCommand.php b/Classes/Command/DeleteCommand.php new file mode 100644 index 0000000..f18ae00 --- /dev/null +++ b/Classes/Command/DeleteCommand.php @@ -0,0 +1,34 @@ +setName('delete') + ->setDescription('Delete an existing project') + ->addArgument('name', \Symfony\Component\Console\Input\InputArgument::REQUIRED, 'Set the name of the installation'); + } + + protected function execute(\Symfony\Component\Console\Input\InputInterface $input, \Symfony\Component\Console\Output\OutputInterface $output) { + $this->input = $input; + $this->output = $output; + + + } + /******************************************************************************************************************* + * + ******************************************************************************************************************/ + + + +} \ No newline at end of file diff --git a/Classes/Command/SynchronizeCommand.php b/Classes/Command/SynchronizeCommand.php new file mode 100644 index 0000000..58ed928 --- /dev/null +++ b/Classes/Command/SynchronizeCommand.php @@ -0,0 +1,32 @@ +setName('sync') + ->setDescription('Synchronize data from moc-files to local project') + ->addArgument('name', \Symfony\Component\Console\Input\InputArgument::REQUIRED, 'Set the name of the installation'); + } + + protected function execute(\Symfony\Component\Console\Input\InputInterface $input, \Symfony\Component\Console\Output\OutputInterface $output) { + $this->input = $input; + $this->output = $output; + } + /******************************************************************************************************************* + * + ******************************************************************************************************************/ + + + +} \ No newline at end of file diff --git a/Configuration/Rosemary.yaml b/Configuration/Rosemary.yaml new file mode 100644 index 0000000..0f9ceef --- /dev/null +++ b/Configuration/Rosemary.yaml @@ -0,0 +1,20 @@ + +locations: + document_root: /Users/langeland/temp/vanilla-test/document_root/ + flow_dir: flow/ + apache_sites: /Users/langeland/temp/vanilla-test/apache_sites/ + +database_root: + host: localhost + username: root + +permissions: + file_modes: 766 + owner: vagrant + group: www-data + +database: + host: localhost + database: typo3_%s + username: typo3 + password: joh316 diff --git a/application.php b/application.php new file mode 100755 index 0000000..fcb18e7 --- /dev/null +++ b/application.php @@ -0,0 +1,11 @@ +#!/usr/bin/env php +add(new Rosemary\Command\CreateCommand()); +$application->add(new Rosemary\Command\SynchronizeCommand()); +$application->add(new Rosemary\Command\DeleteCommand()); +$application->run(); diff --git a/compile.php b/compile.php new file mode 100755 index 0000000..4d96198 --- /dev/null +++ b/compile.php @@ -0,0 +1,10 @@ +#!/usr/bin/env php +buildFromDirectory(__DIR__ . '/'); +$phar->setStub(""); + + +chmod('../rosemary.phar', 0755); \ No newline at end of file diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..7fff6fb --- /dev/null +++ b/composer.json @@ -0,0 +1,24 @@ +{ + "name": "langeland/rosemary", + "description": "Generate API for the TYPO3 projects", + "license": "LGPL-3.0+", + "config": { + "vendor-dir": "Libraries", + "bin-dir": "bin" + }, + "autoload": { + "psr-4": { + "Rosemary\\": "Classes/" + } + }, + "require": { + "symfony/console": "~2.6", + "symfony/yaml": "~2.6" + }, + "require-dev": { + }, + "suggest": { + }, + "scripts": { + } +} \ No newline at end of file diff --git a/composer.lock b/composer.lock new file mode 100644 index 0000000..8e3590b --- /dev/null +++ b/composer.lock @@ -0,0 +1,122 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", + "This file is @generated automatically" + ], + "hash": "e4718532a4ffa02b041043e82d85211f", + "packages": [ + { + "name": "symfony/console", + "version": "v2.6.3", + "target-dir": "Symfony/Component/Console", + "source": { + "type": "git", + "url": "https://github.com/symfony/Console.git", + "reference": "6ac6491ff60c0e5a941db3ccdc75a07adbb61476" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/Console/zipball/6ac6491ff60c0e5a941db3ccdc75a07adbb61476", + "reference": "6ac6491ff60c0e5a941db3ccdc75a07adbb61476", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "psr/log": "~1.0", + "symfony/event-dispatcher": "~2.1", + "symfony/process": "~2.1" + }, + "suggest": { + "psr/log": "For using the console logger", + "symfony/event-dispatcher": "", + "symfony/process": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.6-dev" + } + }, + "autoload": { + "psr-0": { + "Symfony\\Component\\Console\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Symfony Community", + "homepage": "http://symfony.com/contributors" + }, + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + } + ], + "description": "Symfony Console Component", + "homepage": "http://symfony.com", + "time": "2015-01-06 17:50:02" + }, + { + "name": "symfony/yaml", + "version": "v2.6.3", + "target-dir": "Symfony/Component/Yaml", + "source": { + "type": "git", + "url": "https://github.com/symfony/Yaml.git", + "reference": "82462a90848a52c2533aa6b598b107d68076b018" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/Yaml/zipball/82462a90848a52c2533aa6b598b107d68076b018", + "reference": "82462a90848a52c2533aa6b598b107d68076b018", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.6-dev" + } + }, + "autoload": { + "psr-0": { + "Symfony\\Component\\Yaml\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Symfony Community", + "homepage": "http://symfony.com/contributors" + }, + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + } + ], + "description": "Symfony Yaml Component", + "homepage": "http://symfony.com", + "time": "2015-01-03 15:33:07" + } + ], + "packages-dev": [], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": [], + "prefer-stable": false, + "prefer-lowest": false, + "platform": [], + "platform-dev": [] +}