Example #1
0
 /**
  * Deletes this class' data to the XDG
  * home directory
  * @return boolean
  */
 public function delete()
 {
     $xdg = new \XdgBaseDir\Xdg();
     $savePath = $xdg->getHomeConfigDir() . '/git-deployer';
     $saveFile = $savePath . '/appinstance.ser';
     if (!file_exists($saveFile)) {
         return true;
     }
     return unlink($saveFile);
 }
Example #2
0
 protected function execute(InputInterface $input, OutputInterface $output)
 {
     $repository = $input->getArgument('repository');
     $revision = $input->getArgument('revision');
     $configuration = $input->getOption('configuration');
     $bag = $input->getOption('bag');
     $force = $input->getOption('force-redeploy');
     // -> Check that the revision matches what we expect
     preg_match('#^(tag|branch|rev):(.*)#iu', $revision, $matches);
     if (count($matches) < 3) {
         throw new \Exception('You must correctly specify the tag/branch/revision you want to deploy!' . "\n" . 'Check "help deploy" for an explanation.');
     } else {
         $type = $matches[1];
         $version = $matches[2];
     }
     // -> Get logged-in service
     $instance = \GitDeployer\AppInstance::getInstance();
     $appService = $instance->service();
     $appService->setInstances($input, $output, $this->getHelperSet());
     // .. and storage
     $storage = $instance->storage();
     $hasBeenFound = false;
     $this->showMessage('INIT', 'Getting repository...', $output);
     foreach ($appService->getProjects() as $key => $project) {
         if ($project->name() == $repository) {
             $hasBeenFound = true;
             $status = $storage->getDeploymentStatus($project);
             // -> Check if we have already been added to Git-Deployer yet
             if (!$status->added()) {
                 throw new \Exception('This repository is not yet added to Git-Deployer!' . "\n" . 'Please add it first via the add command.');
             }
             // -> Check we are not deploying the same version again. Ask
             // if we do, so the user can decide
             if ($status->isDeployd()) {
                 if ($status->getDeployedVersion() == $revision && !$force) {
                     $helper = $this->getHelper('question');
                     $question = new ConfirmationQuestion('Version ' . $status->getDeployedVersion() . ' was already deployed on ' . $status->deployedWhen() . '. Continue anyway? (y/[n]) ', false);
                     if (!$helper->ask($input, $output, $question)) {
                         break;
                     }
                 }
             }
             // -> Now clone it to a temp directory, if it doesn't exist already
             $tmpDir = sys_get_temp_dir() . '/git-deploy-' . strtolower($project->name());
             if (\Gitonomy\Git\Admin::isValidRepository($tmpDir)) {
                 $this->showMessage('GIT', 'Pulling latest changes from repository...', $output);
                 $repository = \Gitonomy\Git\Admin::init($tmpDir, false);
                 $repository->run('pull');
             } else {
                 $this->showMessage('GIT', 'Cloning repository...', $output);
                 $repository = \Gitonomy\Git\Admin::cloneTo($tmpDir, $project->url(), false);
             }
             // -> Check out the correct branch/revision/tag
             $this->showMessage('GIT', 'Checking out ' . $revision . '...', $output);
             $wc = $repository->getWorkingCopy();
             $wc->checkout($version);
             // -> Open .deployerfile and parse it
             $this->showMessage('DEPLOY', 'Checking .deployerfile...', $output);
             if (file_exists($tmpDir . '/.deployerfile')) {
                 $deployerfile = json_decode(file_get_contents($tmpDir . '/.deployerfile'));
             } else {
                 throw new \Exception('This repository has no .deployerfile!' . "\n" . 'Please add one first!');
             }
             if ($deployerfile == null) {
                 throw new \Exception('Could not parse .deployerfile: ' . json_last_error_msg() . "\n" . 'Please check that your JSON is valid!');
             }
             // -> Load the correct deployer from the .deployerfile, and fire it up with
             // the correct configuration options
             if (!isset($deployerfile->type)) {
                 throw new \Exception('Could not parse .deployerfile: ' . "\n" . 'Please specify a deployer via the "type" option!');
             }
             if (!isset($deployerfile->configurations) || isset($deployerfile->configurations) && !is_object($deployerfile->configurations)) {
                 throw new \Exception('Could not parse .deployerfile: ' . "\n" . 'Please specify at least one deployment configuration in the "configurations" option!');
             }
             // -> Get available configurations, and if not set, ask the user
             // which configuration to use
             $configs = get_object_vars($deployerfile->configurations);
             if ($configuration == null && count(get_object_vars($deployerfile->configurations)) > 1) {
                 // If no configuration has been specified via command line,
                 // ask the user which one to use
                 $confignames = array();
                 foreach ($configs as $name => $values) {
                     $confignames[] = $name;
                 }
                 // -> Get storage service to use
                 $question = new ChoiceQuestion('Which deployment configuration would you like to use?', $confignames);
                 $question->setValidator(function ($answer) use($configs, $confignames) {
                     if (!isset($configs[$confignames[$answer]])) {
                         throw new \RuntimeException('Please select a correct value!');
                     }
                     return $confignames[$answer];
                 });
                 $configuration = $helper->ask($input, $output, $question);
             } elseif ($configuration != null) {
                 // Try to use the current specified configuration
                 if (!isset($configs[$configuration])) {
                     throw new \Exception('The configuration "' . $configuration . '" was not found in this .deployefile!');
                 }
             } else {
                 foreach ($configs as $name => $values) {
                     $configuration = $name;
                 }
             }
             // -> Merge the current configuration inheritance chain, if any
             if (!isset($deployerfile->inheritance)) {
                 $mergedConfig = json_decode(json_encode($configs[$configuration]), true);
             } else {
                 $chain = $deployerfile->inheritance;
                 $minChainFound = false;
                 $smallerChain = array();
                 foreach ($chain as $key) {
                     if ($key == $configuration) {
                         $minChainFound = true;
                         $smallerChain[] = $key;
                     } else {
                         if ($minChainFound) {
                             $smallerChain[] = $key;
                         }
                     }
                 }
                 if (count($smallerChain) > 1) {
                     $mergedConfig = array();
                     foreach (array_reverse($smallerChain) as $configmerge) {
                         $mergedConfig = array_replace_recursive($mergedConfig, json_decode(json_encode($configs[$configmerge]), true));
                     }
                 } else {
                     $mergedConfig = json_decode(json_encode($configs[$smallerChain[0]]), true);
                 }
             }
             // -> Check if we have saved parameter bags, and offer the user
             // to choose one if so, or use the one provided from the command line
             $xdg = new \XdgBaseDir\Xdg();
             $bagPath = $xdg->getHomeConfigDir() . '/git-deployer';
             if ($bag != null) {
                 if (!file_exists($bagPath . '/' . $project->name() . '-' . $bag . '.bag')) {
                     throw new \Exception('This parameter bag has not been found!' . "\n" . 'Please check your naming!');
                 } else {
                     $answers = unserialize(file_get_contents($bagPath . '/' . $project->name() . '-' . $bag . '.bag'));
                 }
             } else {
                 $availableBags = array();
                 if (file_exists($bagPath)) {
                     $dh = opendir($bagPath);
                     while (($file = readdir($dh)) !== false) {
                         $fileInfo = pathinfo($file);
                         if ($fileInfo['extension'] == 'bag') {
                             if (stristr($fileInfo['filename'], $project->name())) {
                                 $availableBags[] = str_replace($project->name() . '-', '', $fileInfo['filename']);
                             }
                         }
                     }
                     closedir($dh);
                 }
                 if (count($availableBags) > 0) {
                     array_unshift($availableBags, "Don't use a bag");
                     $helper = $this->getHelper('question');
                     $question = new ChoiceQuestion('One or more parameter bags have been found. Which one do you want to use?', $availableBags);
                     $question->setValidator(function ($answer) use($availableBags) {
                         if ($answer == 0) {
                             return false;
                         }
                         if (!isset($availableBags[$answer])) {
                             throw new \RuntimeException('Please select a correct value!');
                         }
                         return $availableBags[$answer];
                     });
                     $parameterBag = $helper->ask($input, $output, $question);
                     if ($parameterBag) {
                         $answers = unserialize(file_get_contents($bagPath . '/' . $project->name() . '-' . $parameterBag . '.bag'));
                     } else {
                         $answers = array();
                     }
                 } else {
                     $answers = array();
                 }
             }
             // -> Replace placeholders in our config using parameter bags
             $bagModified = false;
             if (isset($deployerfile->parameters)) {
                 foreach ($deployerfile->parameters as $key => $questionhelp) {
                     if (!isset($answers[$key])) {
                         $helper = $this->getHelper('question');
                         $question = new Question($questionhelp . ' ');
                         $questionanswer = $helper->ask($input, $output, $question);
                         if ($questionanswer == null) {
                             $answers[$key] = '';
                         } else {
                             $answers[$key] = $questionanswer;
                         }
                         $bagModified = true;
                     }
                 }
                 // -> Ask the user to save this parameter bag
                 if ($bagModified) {
                     $helper = $this->getHelper('question');
                     $question = new ConfirmationQuestion('Do you want to save these answers in a parameter bag for next time? ([y]/n) ', true);
                     if ($helper->ask($input, $output, $question)) {
                         $question = new Question('Please provide a name for the new (or existing, will overwrite) parameter bag: ');
                         $question->setValidator(function ($answer) {
                             if (strlen($answer) < 1) {
                                 throw new \RuntimeException('Please provide a name for this parameter bag!');
                             } else {
                                 if (!preg_match('#\\w+#iu', $answer)) {
                                     throw new \RuntimeException('The name provided for this parameter bag is invalid!');
                                 }
                             }
                             return $answer;
                         });
                         $bagname = $helper->ask($input, $output, $question);
                         // -> Save this bag!
                         $xdg = new \XdgBaseDir\Xdg();
                         $savePath = $xdg->getHomeConfigDir() . '/git-deployer';
                         $saveFile = $savePath . '/' . $project->name() . '-' . $bagname . '.bag';
                         if (!file_exists($savePath)) {
                             mkdir($savePath);
                         }
                         file_put_contents($saveFile, serialize($answers));
                     }
                 }
                 // -> Now traverse the array to replace the values, and as such
                 // get our merged config ready to pass it into the deployer
                 $replacedConfig = $this->replacePlaceholders($mergedConfig, $answers);
             }
             // -> Execute the requested deployer with our merged configuration array
             $deployer = \GitDeployer\Deployers\BaseDeployer::createServiceInstance(ucwords($deployerfile->type), $input, $output, $this->getHelperSet());
             list($statusok, $trace) = $deployer->deploy($project, $tmpDir, $replacedConfig);
             // -> Check if the deployment went well, return any errors,
             // or update the deployment status for the project otherwise
             if ($statusok) {
                 $status->deployedWhen(date('c'));
                 $status->deployedType($type);
                 $status->deployedString($version);
                 $storage->setDeploymentStatus($project, $status);
             } else {
                 $output->writeln($trace);
                 throw new \Exception('Deployment did not completely finish! See trace above.');
             }
             // -> Finish up!
             $this->showMessage('FINISH', '<info>Done!</info>', $output);
             break;
         }
     }
     if (!$hasBeenFound) {
         throw new \Exception('Project "' . $repository . '" could not be found! Please check your spelling!');
     }
 }
Example #3
0
 /**
  * Configures the storage service. In our case, we just
  * want the file name for the state file
  * @return boolean
  */
 public function configure()
 {
     $helper = $this->helpers->get('question');
     // -> Get file path from the user
     $xdg = new \XdgBaseDir\Xdg();
     $savePath = $xdg->getHomeConfigDir() . '/git-deployer';
     if (strlen($this->path) > 3) {
         $defText = '[' . $this->path . '] ';
     } else {
         $this->path = $savePath . '/localstorage.json';
         $defText = '[' . $savePath . '/localstorage.json] ';
     }
     $question = new Question('Please enter the file path for your local storage: ' . $defText, $this->path);
     $question->setValidator(function ($answer) {
         if (strlen($answer) < 4) {
             throw new \RuntimeException('The file path can not be empty!');
         }
         return $answer;
     });
     $this->path = $helper->ask($this->input, $this->output, $question);
     // -> Create file, if it does not exist yet
     if (@file_put_contents($this->path, json_encode(array()))) {
         return true;
     } else {
         throw new \Exception('Could not save file to path: "' . $this->path . '"! ' . "\n" . 'Error was: ' . error_get_last()['message']);
     }
 }