From 25c6f3e882c5c308c4659129fa3c7599058227f1 Mon Sep 17 00:00:00 2001 From: Stephan Maximilian Huber Date: Mon, 26 Nov 2018 18:01:43 +0100 Subject: [PATCH 01/20] Update readme.md --- readme.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/readme.md b/readme.md index fa6ae1b5..edceacc4 100644 --- a/readme.md +++ b/readme.md @@ -16,10 +16,10 @@ Phabalicious is the successor of the python tool [fabalicious](https://github.co ## Add it via composer.json -* run `composer require factorial.io/phabalicious` +* run `composer require factorial-io/phabalicious` * then you can run phabalicious via `./vendor/factorial-io/fabablicious/bin/phab` (or create a symbolic link) -## Running pha +## Running phab * Run `phab list` to get a list of all available commands. * run `phab help ` to get some help for a given command. From 6a0424dae557a712be45414ea252e398405e2509 Mon Sep 17 00:00:00 2001 From: Stephan Maximilian Huber Date: Mon, 26 Nov 2018 18:19:06 +0100 Subject: [PATCH 02/20] First version of circleci --- .circleci/config.yml | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 .circleci/config.yml diff --git a/.circleci/config.yml b/.circleci/config.yml new file mode 100644 index 00000000..a6d6f930 --- /dev/null +++ b/.circleci/config.yml @@ -0,0 +1,37 @@ +# PHP CircleCI 2.0 configuration file +# +# Check https://circleci.com/docs/2.0/language-php/ for more details +# +version: 2 +jobs: + build: + docker: + # specify the version you desire here + - image: circleci/php:7.1-browsers + + # Specify service dependencies here if necessary + # CircleCI maintains a library of pre-built images + # documented at https://circleci.com/docs/2.0/circleci-images/ + # - image: circleci/mysql:9.4 + + working_directory: ~/repo + + steps: + - checkout + + # Download and cache dependencies + - restore_cache: + keys: + - v1-dependencies-{{ checksum "composer.json" }} + # fallback to using the latest cache if no exact match is found + - v1-dependencies- + + - run: composer install -n --prefer-dist + + - save_cache: + paths: + - ./vendor + key: v1-dependencies-{{ checksum "composer.json" }} + + # run tests! + - run: phpunit From 73ae490f7614f626304318aa60b91da80d57c684 Mon Sep 17 00:00:00 2001 From: Stephan Maximilian Huber Date: Mon, 26 Nov 2018 18:30:33 +0100 Subject: [PATCH 03/20] Next try with circle-ci --- .circleci/config.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index a6d6f930..0da41d07 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -7,7 +7,7 @@ jobs: build: docker: # specify the version you desire here - - image: circleci/php:7.1-browsers + - image: factorial/phabalicious-test-runner # Specify service dependencies here if necessary # CircleCI maintains a library of pre-built images @@ -26,7 +26,7 @@ jobs: # fallback to using the latest cache if no exact match is found - v1-dependencies- - - run: composer install -n --prefer-dist + - run: php /composer.phar install - save_cache: paths: @@ -34,4 +34,4 @@ jobs: key: v1-dependencies-{{ checksum "composer.json" }} # run tests! - - run: phpunit + - run: cd tests; ../vendor/bin/phpunit --exclude-group docker . From d31f6d47d0cdc72eb3361bd479efc4cfdf02b874 Mon Sep 17 00:00:00 2001 From: Stephan Maximilian Huber Date: Mon, 26 Nov 2018 19:37:22 +0100 Subject: [PATCH 04/20] Set version --- bin/phab | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/phab b/bin/phab index 61ff551e..e7b5f917 100755 --- a/bin/phab +++ b/bin/phab @@ -45,7 +45,7 @@ $output = $container->get(ConsoleOutput::class); /** @var Application $application */ $application = $container->get(Application::class); -$application->setVersion('3.0.0'); +$application->setVersion('3.0.0-alpha.1'); $application->setName('phabalicious'); $application->setDefaultCommand('list'); From 73fc59ddf3cf0722a6bf60e1103cfa5b80117a89 Mon Sep 17 00:00:00 2001 From: Stephan Maximilian Huber Date: Mon, 26 Nov 2018 19:38:28 +0100 Subject: [PATCH 05/20] Build-script for releases --- build/create-release.sh | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 build/create-release.sh diff --git a/build/create-release.sh b/build/create-release.sh new file mode 100644 index 00000000..cabb9ac4 --- /dev/null +++ b/build/create-release.sh @@ -0,0 +1,27 @@ +GH_USER=factorial-io +GH_PATH=`cat ~/.ghtoken` +GH_REPO=phabalicious +GH_TARGET=master +ASSETS_PATH=./ +VERSION=`git describe --tags | sed 's/-[0-9]-g[a-z0-9]\{7\}//'` +echo "Releasing ${VERSION} ..." +cd .. +composer build-phar +cd build + +res=`curl --user "$GH_USER:$GH_PATH" -X POST https://api.github.com/repos/${GH_USER}/${GH_REPO}/releases \ +-d " +{ + \"tag_name\": \"v$VERSION\", + \"target_commitish\": \"$GH_TARGET\", + \"name\": \"v$VERSION\", + \"body\": \"new version $VERSION\", + \"draft\": false, + \"prerelease\": false +}"` +echo Create release result: ${res} +rel_id=`echo ${res} | python -c 'import json,sys;print(json.load(sys.stdin)["id"])'` +file_name=phabalicious-${VERSION}.phar + +curl --user "$GH_USER:$GH_PATH" -X POST https://uploads.github.com/repos/${GH_USER}/${GH_REPO}/releases/${rel_id}/assets?name=${file_name}\ + --header 'Content-Type: text/javascript ' --upload-file ${ASSETS_PATH}/phabalicious.phar From 92b9bdd4538bd195cfc2e33074bc35dec1d28b33 Mon Sep 17 00:00:00 2001 From: Shibin Das Date: Tue, 27 Nov 2018 16:04:45 +0100 Subject: [PATCH 06/20] Update 'readme.md' Added necessary step to get Build from source working. --- readme.md | 1 + 1 file changed, 1 insertion(+) diff --git a/readme.md b/readme.md index edceacc4..8f554e28 100644 --- a/readme.md +++ b/readme.md @@ -11,6 +11,7 @@ Phabalicious is the successor of the python tool [fabalicious](https://github.co ## Build from source * Clone the repository +* run `composer install` * run `composer build-phar` * run `composer install-phar` this will copy the app to /usr/local/bin and make it executable. From 814f92537e2e9868bd08ab74f0c24884a79c843f Mon Sep 17 00:00:00 2001 From: Stephan Maximilian Huber Date: Tue, 27 Nov 2018 20:31:48 +0100 Subject: [PATCH 07/20] Add test-case for app:scaffold --- tests/AppScaffoldCommandTest.php | 77 +++++++++++++++++++ .../scaffold-tests/scaffold-drupal-8.yml | 2 - .../scaffold-tests/ssh-keys/docker-root-key | 27 ------- .../ssh-keys/docker-root-key.pub | 1 - .../scaffold-tests/ssh-keys/known_hosts | 2 - 5 files changed, 77 insertions(+), 32 deletions(-) create mode 100644 tests/AppScaffoldCommandTest.php delete mode 100644 tests/assets/scaffold-tests/ssh-keys/docker-root-key delete mode 100644 tests/assets/scaffold-tests/ssh-keys/docker-root-key.pub delete mode 100644 tests/assets/scaffold-tests/ssh-keys/known_hosts diff --git a/tests/AppScaffoldCommandTest.php b/tests/AppScaffoldCommandTest.php new file mode 100644 index 00000000..1ac52825 --- /dev/null +++ b/tests/AppScaffoldCommandTest.php @@ -0,0 +1,77 @@ +application = new Application(); + $this->application->setVersion('3.0.0'); + $logger = $this->getMockBuilder(LoggerInterface::class)->getMock(); + + $configuration = new ConfigurationService($this->application, $logger); + $method_factory = new MethodFactory($configuration, $logger); + $method_factory->addMethod(new ScriptMethod($logger)); + + $this->application->add(new AppScaffoldCommand($configuration, $method_factory)); + } + + public function testAppScaffolder() + { + $command = $this->application->find('app:scaffold'); + $commandTester = new CommandTester($command); + $commandTester->execute(array( + '--short-name' => 'TST', + '--name' => 'Test', + '--output' => '/tmp', + '--override' => true, + 'scaffold-url' => getcwd() . '/assets/scaffold-tests/scaffold-drupal-commerce.yml' + )); + + // the output of the command in the console + $output = $commandTester->getDisplay(); + + $this->testFileContent('/tmp/test/.fabfile.yaml', 'name: Test'); + $this->testFileContent('/tmp/test/.fabfile.yaml', 'key: tst'); + $this->testFileContent('/tmp/test/.fabfile.yaml', 'host: test.test'); + $this->testFileContent( + '/tmp/test/web/modules/custom/tst_deploy/tst_deploy.info.yml', + 'name: Test deployment module' + ); + $this->testFileContent( + '/tmp/test/web/modules/custom/tst_deploy/tst_deploy.info.yml', + 'name: Test deployment module' + ); + $this->testFileContent( + '/tmp/test/web/modules/custom/tst_deploy/tst_deploy.install', + 'function tst_deploy_install()' + ); + } + + private function testFileContent($filename, $needle) + { + + $haystack = file_get_contents($filename); + $this->assertContains($needle, $haystack); + } +} diff --git a/tests/assets/scaffold-tests/scaffold-drupal-8.yml b/tests/assets/scaffold-tests/scaffold-drupal-8.yml index ba1402c9..4b35509a 100644 --- a/tests/assets/scaffold-tests/scaffold-drupal-8.yml +++ b/tests/assets/scaffold-tests/scaffold-drupal-8.yml @@ -18,11 +18,9 @@ sshKeys: scaffold: - rm -rf %rootFolder% - composer create-project %composerProject% %rootFolder% --stability dev --no-interaction - - cd %rootFolder%; composer require drupal/coffee - cd %rootFolder%; composer require drupal/devel - copy_assets(%rootFolder%) - copy_assets(%rootFolder%/web/modules/custom/%shortName%_deploy, deployModuleAssets) - - copy_assets(%rootFolder%/ssh-keys, sshKeys) - cd %rootFolder%; git init . - cd %rootFolder%; git add . - cd %rootFolder%; git commit -m "Initial commit by phabalicious" \ No newline at end of file diff --git a/tests/assets/scaffold-tests/ssh-keys/docker-root-key b/tests/assets/scaffold-tests/ssh-keys/docker-root-key deleted file mode 100644 index 9a71d707..00000000 --- a/tests/assets/scaffold-tests/ssh-keys/docker-root-key +++ /dev/null @@ -1,27 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -MIIEpQIBAAKCAQEA5srq1zzi2/PQIkmPGGD2ThyN98yJG1g4tBj+AUH7m6oW2P7M -U6WNWdZF1ajcKN1zQ25GjOw4jfn/8VkC93ANgeRBX/NFQoiYkjBJgBv+/WGD06Fx -8TeKu2zTK3TdYwcLVSHyQEfEma604XTjWI8VGb/yuj6iP0IIxD2g5j9TChD9HBxG -bwwC8WYsLsW8OnRTLKOvGRTIZnjFTJREkBlmhs3lAswDb4Od62N90jOclTmcaSN1 -Fuo0MHeaBF1wsjHlsX3yMvc5yyuSExjwDWjlhs16Pnz56upapmZPk0lh7AjM7MKq -QKjuQZmquPD4Ebp/zeicS3P8Wvdod8pDd4DqDwIDAQABAoIBAQCBCX8X7IDifYUn -Rn1tIflUXv65R3B5C3BYsYiC54Nn20d+96cCNZO8YOMWvJyrdHVXhDaJ4CEWsGp7 -ZEsWUV4b+6TZoshclMbJJZpSuFRvErCECMYOGgHFHOlMaMDG909Mv/gUHIw9aMLV -M2dRQl6H0RxDKXXJbIA+SD7HvSwOebVXqu/RC6pU6hK9pVUq0r7X3ZAD53jp+PBg -oj4S8sUu4Rh8yb9hNMWLZkmvkNm69gr0Yhj6UOpP1s+f1ztvB4uAhWu5bgWzqJsG -8bc5tyDTksb0OsXfIeJMnDg/lte9cF0GFEfp6WlC5m5Dkx1ffnWGfdzzLMDhI7pF -C6361nAxAoGBAPXTN1ri7Q/lVXRU+CiNAZhKaw3XVfbGKSH6w19MQ7BanWvti5QX -At1IGX9KrX9zQ6YtUU/zcsEvB4dr/qaRu8sszGoYLsiizcgrReUeR70WP5nNlAaA -50RfF7IESkfiWAOvnUgsK462di5QtyU+47jNA5cf8MeKu/jE4AvUnxu9AoGBAPBY -apNn0pO/OYkrOTEG3LtXLDVuPTaV1RP5I4bz4Az9UmPUsdMwvBASx/Qe2R5ZgVRa -YvO9sBBH5V21rgH9On2rqGfSKrhvteXa0wN5+iQ3BBlRePhgDQ3D+IyuNGK1q4PY -fTe59pEwAjVBov3wrC4wDtFEURWrEtlJqAirVTO7AoGBAL3KMsSiyvAo2U8Vgvqb -0w1m9zwacq4x0/P+DPT4hpITg9Kd9dOB6J47WiQi3cy2ixYzisG1bXWk/6UYReUI -QvrcPX3z6brRpxrR/gak2DIuiTAPvic/Qk5RNJQmJ8tT/yvpW/8qyv5F9PxRKPVC -lsJI1mrJKDaG8BViuq+nmqfpAoGBANtsXSBmUOGCW0zXoUcZNLv0QfAlzMzgzb+G -XOEAFTTGsUljDVX50Df8bYB6CU6j+GbCfkR4kRzMBqMfEtXOEnBZH05pmYb4teA7 -fxpVagFWGO/kacSYLFK871XAVSMpKIUeSHNv26OBaQKmAeBEsW0Zgu2aqUxW+sZV -cIs5oHexAoGASkK64OrWItZD8R06J3ZAnThumcvJZCSwY53hSBJIcjcL/e8dazTd -wjLqqBDGsKQMTuzqNs0Wj4lvygdNGsB5zFQxGuoocaxyCC2+fvLNzK3maAva+gsX -jLwzoboZiTv0qqDw9ywERvy1AahA0MDGRoFMuarGqXRrkOQNPDx6/NM= ------END RSA PRIVATE KEY----- diff --git a/tests/assets/scaffold-tests/ssh-keys/docker-root-key.pub b/tests/assets/scaffold-tests/ssh-keys/docker-root-key.pub deleted file mode 100644 index 57014ce8..00000000 --- a/tests/assets/scaffold-tests/ssh-keys/docker-root-key.pub +++ /dev/null @@ -1 +0,0 @@ -ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDmyurXPOLb89AiSY8YYPZOHI33zIkbWDi0GP4BQfubqhbY/sxTpY1Z1kXVqNwo3XNDbkaM7DiN+f/xWQL3cA2B5EFf80VCiJiSMEmAG/79YYPToXHxN4q7bNMrdN1jBwtVIfJAR8SZrrThdONYjxUZv/K6PqI/QgjEPaDmP1MKEP0cHEZvDALxZiwuxbw6dFMso68ZFMhmeMVMlESQGWaGzeUCzANvg53rY33SM5yVOZxpI3UW6jQwd5oEXXCyMeWxffIy9znLK5ITGPANaOWGzXo+fPnq6lqmZk+TSWHsCMzswqpAqO5Bmaq48PgRun/N6JxLc/xa92h3ykN3gOoP docker@docker.local diff --git a/tests/assets/scaffold-tests/ssh-keys/known_hosts b/tests/assets/scaffold-tests/ssh-keys/known_hosts deleted file mode 100644 index bd1d53a5..00000000 --- a/tests/assets/scaffold-tests/ssh-keys/known_hosts +++ /dev/null @@ -1,2 +0,0 @@ -[source.factorial.io]:2222 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCfp3kjMalh/c10bjVYF00IotFIwPQrr8iOhBjfRbe5lS43Gd3+XkTcKdUnmPYvF6wt6YxvUYcn0YYfzncpA0FzFw8461gcBoIVRvC+kV+LOsi/jy7lkfSoCCThLWW0EE8iP0FaorzVl4SrJtHcRiv9v0RY8CzZ8LeADsWu8bhY3eHdcg4F4tBvggrRxja7HbSszisp9ls6fgi+KhowBW7FN0E1cFl8HOZ6K9K0+Qg3PM/3ivpWQ66IGXDRAPHK/bMwME09wAl7o8Qb67SnNKYxqaKunB+bJisez6j5ETuzwZtiKxQ8Hh3Ke33pHRi8xqWmmc4N0EK3ENkPdZ6P7w/9 -github.com,192.30.252.128 ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ== From ecda056b9de9a3fd50401ca4b6745f5611efddb7 Mon Sep 17 00:00:00 2001 From: Stephan Maximilian Huber Date: Tue, 27 Nov 2018 20:53:01 +0100 Subject: [PATCH 08/20] Check if container is available before running waitForServices or copySSHKeys --- Changelog.md | 2 ++ src/Method/DockerMethod.php | 22 +++++++++++++++++++++- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/Changelog.md b/Changelog.md index ec30632c..22d7204b 100644 --- a/Changelog.md +++ b/Changelog.md @@ -66,6 +66,8 @@ Most notably the handling of arguments and options has changed a lot. Fabric gav docker: service: web + The `name` will be discarded, if a `service`-entry is set. + ### Changed diff --git a/src/Method/DockerMethod.php b/src/Method/DockerMethod.php index f1718ed5..14fbc44e 100644 --- a/src/Method/DockerMethod.php +++ b/src/Method/DockerMethod.php @@ -70,6 +70,13 @@ public function validateConfig(array $config, ValidationErrorBagInterface $error } } + public function alterConfig(ConfigurationService $configuration_service, array &$data) + { + if (!empty($data['docker']['service'])) { + unset($data['docker']['name']); + } + } + /** * @param HostConfig $host_config * @param TaskContextInterface $context @@ -165,6 +172,9 @@ public function getInternalTasks() /** * @param HostConfig $hostconfig * @param TaskContextInterface $context + * @throws ValidationFailedException + * @throws \Phabalicious\Exception\MismatchedVersionException + * @throws \Phabalicious\Exception\MissingDockerHostConfigException */ public function waitForServices(HostConfig $hostconfig, TaskContextInterface $context) { @@ -177,6 +187,13 @@ public function waitForServices(HostConfig $hostconfig, TaskContextInterface $co $container_name = $this->getDockerContainerName($hostconfig, $context); $shell = $docker_config->shell(); + if (!$this->isContainerRunning($docker_config, $container_name)) { + throw new \RuntimeException(sprintf( + 'Docker container %s not running, check your `host.docker.name` configuration!', + $container_name + )); + } + while ($tries < $max_tries) { $error_log_level = new ScopedErrorLogLevel($shell, LogLevel::NOTICE); $result = $shell->run(sprintf('#!docker exec %s #!supervisorctl status', $container_name), true, false); @@ -251,7 +268,10 @@ private function copySSHKeys(HostConfig $hostconfig, TaskContextInterface $conte $shell = $docker_config->shell(); $container_name = $this->getDockerContainerName($hostconfig, $context); if (!$this->isContainerRunning($docker_config, $container_name)) { - throw new \RuntimeException(sprintf('Docker container %s not running', $container_name)); + throw new \RuntimeException(sprintf( + 'Docker container %s not running, check your `host.docker.name` configuration!', + $container_name + )); } $shell->run(sprintf('#!docker exec %s mkdir -p /root/.ssh', $container_name)); From b99cf016122784c7d09613dfa5d3b038f557c8ae Mon Sep 17 00:00:00 2001 From: Stephan Maximilian Huber Date: Tue, 27 Nov 2018 21:05:28 +0100 Subject: [PATCH 09/20] Fix test --- tests/AppScaffoldCommandTest.php | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/tests/AppScaffoldCommandTest.php b/tests/AppScaffoldCommandTest.php index 1ac52825..b2a8ced4 100644 --- a/tests/AppScaffoldCommandTest.php +++ b/tests/AppScaffoldCommandTest.php @@ -51,24 +51,24 @@ public function testAppScaffolder() // the output of the command in the console $output = $commandTester->getDisplay(); - $this->testFileContent('/tmp/test/.fabfile.yaml', 'name: Test'); - $this->testFileContent('/tmp/test/.fabfile.yaml', 'key: tst'); - $this->testFileContent('/tmp/test/.fabfile.yaml', 'host: test.test'); - $this->testFileContent( + $this->checkFileContent('/tmp/test/.fabfile.yaml', 'name: Test'); + $this->checkFileContent('/tmp/test/.fabfile.yaml', 'key: tst'); + $this->checkFileContent('/tmp/test/.fabfile.yaml', 'host: test.test'); + $this->checkFileContent( '/tmp/test/web/modules/custom/tst_deploy/tst_deploy.info.yml', 'name: Test deployment module' ); - $this->testFileContent( + $this->checkFileContent( '/tmp/test/web/modules/custom/tst_deploy/tst_deploy.info.yml', 'name: Test deployment module' ); - $this->testFileContent( + $this->checkFileContent( '/tmp/test/web/modules/custom/tst_deploy/tst_deploy.install', 'function tst_deploy_install()' ); } - private function testFileContent($filename, $needle) + private function checkFileContent($filename, $needle) { $haystack = file_get_contents($filename); From 70c2ce9b472bc1c8b2e098945c9754ef9d52525f Mon Sep 17 00:00:00 2001 From: Stephan Maximilian Huber Date: Tue, 27 Nov 2018 21:21:54 +0100 Subject: [PATCH 10/20] Harden test --- tests/AppScaffoldCommandTest.php | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/tests/AppScaffoldCommandTest.php b/tests/AppScaffoldCommandTest.php index b2a8ced4..2e1c8fda 100644 --- a/tests/AppScaffoldCommandTest.php +++ b/tests/AppScaffoldCommandTest.php @@ -38,12 +38,17 @@ public function setup() public function testAppScaffolder() { + $target_folder = getcwd() . '/tmp'; + if (!is_dir($target_folder)) { + mkdir($target_folder); + } + $command = $this->application->find('app:scaffold'); $commandTester = new CommandTester($command); $commandTester->execute(array( '--short-name' => 'TST', '--name' => 'Test', - '--output' => '/tmp', + '--output' => $target_folder, '--override' => true, 'scaffold-url' => getcwd() . '/assets/scaffold-tests/scaffold-drupal-commerce.yml' )); @@ -51,21 +56,22 @@ public function testAppScaffolder() // the output of the command in the console $output = $commandTester->getDisplay(); - $this->checkFileContent('/tmp/test/.fabfile.yaml', 'name: Test'); - $this->checkFileContent('/tmp/test/.fabfile.yaml', 'key: tst'); - $this->checkFileContent('/tmp/test/.fabfile.yaml', 'host: test.test'); + $this->checkFileContent($target_folder . '/test/.fabfile.yaml', 'name: Test'); + $this->checkFileContent($target_folder . '/test/.fabfile.yaml', 'key: tst'); + $this->checkFileContent($target_folder . '/test/.fabfile.yaml', 'host: test.test'); $this->checkFileContent( - '/tmp/test/web/modules/custom/tst_deploy/tst_deploy.info.yml', + $target_folder . '/test/web/modules/custom/tst_deploy/tst_deploy.info.yml', 'name: Test deployment module' ); $this->checkFileContent( - '/tmp/test/web/modules/custom/tst_deploy/tst_deploy.info.yml', + $target_folder . '/test/web/modules/custom/tst_deploy/tst_deploy.info.yml', 'name: Test deployment module' ); $this->checkFileContent( - '/tmp/test/web/modules/custom/tst_deploy/tst_deploy.install', + $target_folder . '/test/web/modules/custom/tst_deploy/tst_deploy.install', 'function tst_deploy_install()' ); + shell_exec(sprintf('rm -rf %s', $target_folder)); } private function checkFileContent($filename, $needle) From 379432cf1e790ff85343da1b4116dd6c78e85d1a Mon Sep 17 00:00:00 2001 From: Stephan Maximilian Huber Date: Tue, 27 Nov 2018 21:34:11 +0100 Subject: [PATCH 11/20] Disable scaffold-test for now on circle ci --- tests/AppScaffoldCommandTest.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/AppScaffoldCommandTest.php b/tests/AppScaffoldCommandTest.php index 2e1c8fda..f1cc8fe2 100644 --- a/tests/AppScaffoldCommandTest.php +++ b/tests/AppScaffoldCommandTest.php @@ -36,6 +36,9 @@ public function setup() $this->application->add(new AppScaffoldCommand($configuration, $method_factory)); } + /** + * @group docker + */ public function testAppScaffolder() { $target_folder = getcwd() . '/tmp'; From 2a7ec204ee40993cb21bf80f42463393a2e45213 Mon Sep 17 00:00:00 2001 From: Stephan Maximilian Huber Date: Wed, 28 Nov 2018 22:05:04 +0100 Subject: [PATCH 12/20] Fix copySSHKeys for remote instances. Fixes #2 --- src/Configuration/ConfigurationService.php | 4 ++++ src/Method/DockerMethod.php | 12 ++++++++---- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/Configuration/ConfigurationService.php b/src/Configuration/ConfigurationService.php index ab973410..209d841f 100644 --- a/src/Configuration/ConfigurationService.php +++ b/src/Configuration/ConfigurationService.php @@ -528,6 +528,9 @@ public function getDockerConfig(string $config_name) $data = $this->dockerHosts[$config_name]; $data = $this->resolveInheritance($data, $this->dockerHosts); + $data = $this->applyDefaults($data, [ + 'tmpFolder' => '/tmp', + ]); if (!empty($data['inheritOnly'])) { return $data; } @@ -597,6 +600,7 @@ private function validateDockerConfig(array $data, $config_name) $validation->deprecate(['runLocally']); $validation->hasKey('shellProvider', 'The name of the shell-provider to use'); $validation->hasKey('rootFolder', 'The rootFolder to start with'); + $validation->hasKey('tmpFolder', 'The rootFolder to use'); if ($errors->hasErrors()) { throw new ValidationFailedException($errors); diff --git a/src/Method/DockerMethod.php b/src/Method/DockerMethod.php index 14fbc44e..3006319a 100644 --- a/src/Method/DockerMethod.php +++ b/src/Method/DockerMethod.php @@ -264,6 +264,8 @@ private function copySSHKeys(HostConfig $hostconfig, TaskContextInterface $conte } if (count($files) > 0) { $docker_config = $this->getDockerConfig($hostconfig, $context); + $root_folder = $docker_config['rootFolder'] . '/' . $hostconfig['docker']['projectFolder']; + /** @var ShellProviderInterface $shell */ $shell = $docker_config->shell(); $container_name = $this->getDockerContainerName($hostconfig, $context); @@ -284,15 +286,17 @@ private function copySSHKeys(HostConfig $hostconfig, TaskContextInterface $conte $data['source'] = $temp_file; $temp_files[] = $temp_file; } elseif ($data['source'][0] !== '/') { - $data['source'] = realpath( + $data['source'] = $context->getConfigurationService()->getFabfilePath() . '/' . - $data['source'] - ); + $data['source']; } + $temp_file = $docker_config['tmpFolder'] . '/' . basename($data['source']); + $shell->putFile($data['source'], $temp_file, $context); - $shell->run(sprintf('#!docker cp %s %s:%s', $data['source'], $container_name, $dest)); + $shell->run(sprintf('#!docker cp %s %s:%s', $temp_file, $container_name, $dest)); $shell->run(sprintf('#!docker exec %s #!chmod %s %s', $container_name, $data['permissions'], $dest)); + $shell->run(sprintf('rm %s', $temp_file)); } $shell->run(sprintf('#!docker exec %s #!chmod 700 /root/.ssh', $container_name)); $shell->run(sprintf('#!docker exec %s #!chown -R root /root/.ssh', $container_name)); From c5e181dd6e2f2a023e008fffd313eca9e23f427b Mon Sep 17 00:00:00 2001 From: Stephan Maximilian Huber Date: Sun, 2 Dec 2018 14:15:20 +0100 Subject: [PATCH 13/20] Remove duplicate command output --- src/ShellProvider/LocalShellProvider.php | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/ShellProvider/LocalShellProvider.php b/src/ShellProvider/LocalShellProvider.php index 7436507e..ba9579c9 100644 --- a/src/ShellProvider/LocalShellProvider.php +++ b/src/ShellProvider/LocalShellProvider.php @@ -154,13 +154,7 @@ public function run(string $command, $capture_output = false, $throw_exception_o } while (empty($exit_code)); $exit_code = intval(str_replace(self::RESULT_IDENTIFIER, '', $exit_code), 10); - foreach ($lines as $line) { - if (!$capture_output && $this->output) { - $this->output->writeln($line); - } elseif ($capture_output) { - $this->logger->debug($line); - } - } + $cr = new CommandResult($exit_code, $lines); if ($cr->failed() && !$capture_output && $throw_exception_on_error) { $cr->throwException(sprintf('`%s` failed!', $command)); From 59ea68b0a6e6fad706b8d1fc285ce945797ff2cd Mon Sep 17 00:00:00 2001 From: Stephan Maximilian Huber Date: Sun, 2 Dec 2018 14:15:35 +0100 Subject: [PATCH 14/20] Fix failing copySSHKeys command --- src/Method/DockerMethod.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Method/DockerMethod.php b/src/Method/DockerMethod.php index 3006319a..6120849d 100644 --- a/src/Method/DockerMethod.php +++ b/src/Method/DockerMethod.php @@ -291,7 +291,7 @@ private function copySSHKeys(HostConfig $hostconfig, TaskContextInterface $conte '/' . $data['source']; } - $temp_file = $docker_config['tmpFolder'] . '/' . basename($data['source']); + $temp_file = $docker_config['tmpFolder'] . '/' . 'phab.tmp.' . basename($data['source']); $shell->putFile($data['source'], $temp_file, $context); $shell->run(sprintf('#!docker cp %s %s:%s', $temp_file, $container_name, $dest)); From ba6d48ff395da0c11c3df2ea4fae18257dc37711 Mon Sep 17 00:00:00 2001 From: Stephan Maximilian Huber Date: Sun, 2 Dec 2018 16:35:43 +0100 Subject: [PATCH 15/20] Refactor starting an interactive shell --- src/Command/BaseCommand.php | 28 +++++++++++++++++++++++++++- src/Command/ShellCommand.php | 19 ++----------------- 2 files changed, 29 insertions(+), 18 deletions(-) diff --git a/src/Command/BaseCommand.php b/src/Command/BaseCommand.php index 4c8afa79..23093cb1 100644 --- a/src/Command/BaseCommand.php +++ b/src/Command/BaseCommand.php @@ -10,6 +10,7 @@ use Phabalicious\Exception\MismatchedVersionException; use Phabalicious\Exception\ValidationFailedException; use Phabalicious\Exception\MissingHostConfigException; +use Phabalicious\ShellProvider\ShellProviderInterface; use Psr\Log\NullLogger; use Stecman\Component\Symfony\Console\BashCompletion\Completion\CompletionAwareInterface; use Stecman\Component\Symfony\Console\BashCompletion\CompletionContext; @@ -17,6 +18,7 @@ use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Process\Process; abstract class BaseCommand extends BaseOptionsCommand { @@ -175,4 +177,28 @@ public function runCommand(string $command, array $args, InputInterface $origina return $cmd->run($input, $output); } -} \ No newline at end of file + /** + * @param ShellProviderInterface $shell + * @param array $command + * @return Process + */ + protected function startInteractiveShell(ShellProviderInterface $shell, array $command = []) + { + /** @var Process $process */ + $process = $shell->createShellProcess($command, ['tty' => true]); + $stdin = fopen('php://stdin', 'r'); + $process->setInput($stdin); + $process->setTimeout(0); + $process->setTty(true); + $process->start(); + $process->wait(function ($type, $buffer) { + if ($type == Process::ERR) { + fwrite(STDERR, $buffer); + } else { + fwrite(STDOUT, $buffer); + } + }); + + return $process; + } +} diff --git a/src/Command/ShellCommand.php b/src/Command/ShellCommand.php index 229dbff2..4e447a17 100644 --- a/src/Command/ShellCommand.php +++ b/src/Command/ShellCommand.php @@ -52,22 +52,7 @@ protected function execute(InputInterface $input, OutputInterface $output) $output->writeln('Starting shell on `' . $host_config['configName'] . '`'); - /** @var Process $process */ - $process = $shell->createShellProcess([], ['tty' => true]); - $stdin = fopen('php://stdin', 'r'); - $process->setInput($stdin); - $process->setTimeout(0); - $process->setTty(true); - $process->start(); - $process->wait(function ($type, $buffer) { - if ($type == Process::ERR) { - fwrite(STDERR, $buffer); - } else { - fwrite(STDOUT, $buffer); - } - }); - + $process = $this->startInteractiveShell($shell); return $process->getExitCode(); } - -} \ No newline at end of file +} From 6a1bf8a1c6ec008908bfca585cbc3ed91228dc64 Mon Sep 17 00:00:00 2001 From: Stephan Maximilian Huber Date: Sun, 2 Dec 2018 16:36:45 +0100 Subject: [PATCH 16/20] Code-style --- src/ShellProvider/LocalShellProvider.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/ShellProvider/LocalShellProvider.php b/src/ShellProvider/LocalShellProvider.php index ba9579c9..daeba8c5 100644 --- a/src/ShellProvider/LocalShellProvider.php +++ b/src/ShellProvider/LocalShellProvider.php @@ -229,5 +229,4 @@ public function createTunnelProcess(HostConfig $target_config, array $prefix = [ { throw new \InvalidArgumentException('Local shells cannot handle tunnels!'); } - -} \ No newline at end of file +} From ba86008215c425d6c7110611cbebf769404948e1 Mon Sep 17 00:00:00 2001 From: Stephan Maximilian Huber Date: Sun, 2 Dec 2018 16:37:01 +0100 Subject: [PATCH 17/20] Add tty-option to ssh-shell-provider --- src/ShellProvider/ShellProviderInterface.php | 2 +- src/ShellProvider/SshShellProvider.php | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/ShellProvider/ShellProviderInterface.php b/src/ShellProvider/ShellProviderInterface.php index d8311de0..8884622e 100644 --- a/src/ShellProvider/ShellProviderInterface.php +++ b/src/ShellProvider/ShellProviderInterface.php @@ -61,7 +61,7 @@ public function runProcess(array $cmd, TaskContextInterface $context, $interacti public function getShellCommand(array $options = []): array; - public function createShellProcess(array $command = []): Process; + public function createShellProcess(array $command = [], array $options = []): Process; public function createTunnelProcess(HostConfig $target_config, array $prefix = []); diff --git a/src/ShellProvider/SshShellProvider.php b/src/ShellProvider/SshShellProvider.php index a9a7b4f5..2d5f496f 100644 --- a/src/ShellProvider/SshShellProvider.php +++ b/src/ShellProvider/SshShellProvider.php @@ -96,6 +96,9 @@ public function getShellCommand(array $options = []): array $this->hostConfig['port'], ]; $this->addCommandOptions($command); + if (!empty($options['tty'])) { + $command[] = '-t'; + } $command[] = $this->hostConfig['user'] . '@' . $this->hostConfig['host']; return $command; From ab5135298d3ff79d730f37b0fb78e57e05cca506 Mon Sep 17 00:00:00 2001 From: Stephan Maximilian Huber Date: Sun, 2 Dec 2018 16:37:16 +0100 Subject: [PATCH 18/20] Run drush command in interactive shell (fixes #3) --- src/Command/DrushCommand.php | 22 ++++++++++++---------- src/Method/DrushMethod.php | 13 ++++++------- 2 files changed, 18 insertions(+), 17 deletions(-) diff --git a/src/Command/DrushCommand.php b/src/Command/DrushCommand.php index b9dbe074..7c2dfed0 100644 --- a/src/Command/DrushCommand.php +++ b/src/Command/DrushCommand.php @@ -2,10 +2,7 @@ namespace Phabalicious\Command; -use Phabalicious\Configuration\HostConfig; -use Phabalicious\Exception\EarlyTaskExitException; use Phabalicious\Method\TaskContext; -use Phabalicious\Method\TaskContextInterface; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; @@ -49,14 +46,19 @@ protected function execute(InputInterface $input, OutputInterface $output) $context = new TaskContext($this, $input, $output); $context->set('command', implode(' ', $input->getArgument('drush'))); - try { - $this->getMethods()->runTask('drush', $this->getHostConfig(), $context); - } catch (EarlyTaskExitException $e) { - return 1; - } + // Allow methods to override the used shellProvider: + $host_config = $this->getHostConfig(); + $this->getMethods()->runTask('drush', $host_config, $context); + $shell = $context->getResult('shell', $host_config->shell()); + $command = $context->getResult('command'); - return $context->getResult('exitCode', 0); - } + if (!$command) { + throw new \RuntimeException('No command-arguments returned for drush-command!'); + } + $output->writeln('Starting drush on `' . $host_config['configName'] . '`'); + $process = $this->startInteractiveShell($shell, $command); + return $process->getExitCode(); + } } diff --git a/src/Method/DrushMethod.php b/src/Method/DrushMethod.php index 8ea75ac2..6cf8b5a6 100644 --- a/src/Method/DrushMethod.php +++ b/src/Method/DrushMethod.php @@ -11,7 +11,6 @@ use Phabalicious\Validation\ValidationErrorBag; use Phabalicious\Validation\ValidationErrorBagInterface; use Phabalicious\Validation\ValidationService; -use webignition\ReadableDuration\ReadableDuration; class DrushMethod extends BaseMethod implements MethodInterface { @@ -234,8 +233,12 @@ public function drush(HostConfig $host_config, TaskContextInterface $context) /** @var ShellProviderInterface $shell */ $shell = $this->getShell($host_config, $context); $shell->cd($host_config['siteFolder']); - $result = $shell->run('#!drush ' . $command); - $context->setResult('exitCode', $result->getExitCode()); + $context->setResult('shell', $shell); + $command = sprintf('cd %s; #!drush %s', $host_config['siteFolder'], $command); + $command = $shell->expandCommand($command); + $context->setResult('command', [ + $command + ]); } private function handleModules( @@ -399,7 +402,6 @@ public function listBackups(HostConfig $host_config, TaskContextInterface $conte if ($tokens) { $result[] = $tokens; } - } $existing = $context->getResult('files', []); @@ -612,8 +614,5 @@ private function setupConfigurationManagement(HostConfig $host_config, TaskConte } $shell->cd($cwd); - - - } } From 13f2f2cdc90610a579fc9f5ce10a136207c0c005 Mon Sep 17 00:00:00 2001 From: Stephan Maximilian Huber Date: Sun, 2 Dec 2018 16:38:34 +0100 Subject: [PATCH 19/20] Fix function declaration --- src/ShellProvider/LocalShellProvider.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ShellProvider/LocalShellProvider.php b/src/ShellProvider/LocalShellProvider.php index daeba8c5..19845e52 100644 --- a/src/ShellProvider/LocalShellProvider.php +++ b/src/ShellProvider/LocalShellProvider.php @@ -54,7 +54,7 @@ public function validateConfig(array $config, ValidationErrorBagInterface $error ); } - public function createShellProcess(array $command = [], $options = []): Process + public function createShellProcess(array $command = [], array $options = []): Process { $shell_command = $this->getShellCommand($options); if (count($command) > 0) { From 5100c1082dd41adfeb4df138a176de4afd9d4775 Mon Sep 17 00:00:00 2001 From: Stephan Maximilian Huber Date: Sun, 2 Dec 2018 16:40:41 +0100 Subject: [PATCH 20/20] Bump version number --- bin/phab | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/phab b/bin/phab index e7b5f917..176ec14c 100755 --- a/bin/phab +++ b/bin/phab @@ -45,7 +45,7 @@ $output = $container->get(ConsoleOutput::class); /** @var Application $application */ $application = $container->get(Application::class); -$application->setVersion('3.0.0-alpha.1'); +$application->setVersion('3.0.0-alpha.2'); $application->setName('phabalicious'); $application->setDefaultCommand('list');