Esempio n. 1
0
 protected function execute(InputInterface $input, OutputInterface $output)
 {
     $cwd = getcwd() . '/' . $input->getOption('working-dir');
     $timeout = (int) $input->getOption('timeout');
     /** @var FormatterHelper $formatter */
     $formatter = $this->getHelperSet()->get('formatter');
     /** @var Config $config */
     $config = new Config($cwd);
     try {
         if (!$config->read()) {
             $output->writeln('<fg=red>No previous config found, please run grenade:config</fg=red>');
             return -1;
         }
         $output->writeln('<fg=yellow>Previous config found.</fg=yellow>');
         $output->writeln('<fg=yellow>Loading existing config...</fg=yellow> <fg=green>done</fg=green>');
     } catch (GrenadeRuntimeException $e) {
         $output->writeln('<fg=red>failed</fg=red>');
         $output->writeln('<fg=red>An error occured while parsing .grenade.json file.</fg=red>');
         return -1;
     }
     if (!file_exists($cwd . '/repositories')) {
         $output->writeln('<fg=yellow>Repositories folder does not exist, repositories should already be cloned.</fg=yellow>');
         mkdir($cwd . '/repositories', 0755, true);
     }
     if (!file_exists($cwd . '/bundles')) {
         mkdir($cwd . '/bundles', 0755, true);
     }
     /** @var GitSubtreeProgressBarHelper $progressBarHelper */
     $progressBarHelper = new GitSubtreeProgressBarHelper($output);
     foreach ($config->walkProjects() as $projectName => $projectRemote) {
         $repositoryPath = $cwd . '/repositories/' . $projectName;
         $originalGit = new Git($repositoryPath, $timeout);
         $bundleGit = new Git(null, $timeout);
         if (!file_exists($repositoryPath)) {
             $output->writeln(sprintf('<fg=green>Cloning <fg=cyan>%s</fg=cyan> repository.</fg=green>', $projectName));
             $originalGit->setWorkingDirectory($cwd . '/repositories/');
             $process = $originalGit->cloneRepository($projectRemote, $projectName);
             if (!$process->isSuccessful()) {
                 throw new CommandFailureException($process);
             }
             $originalGit->setWorkingDirectory($repositoryPath);
         } else {
             $output->writeln(sprintf('<fg=green>Fetching <fg=cyan>%s</fg=cyan> repository.</fg=green>', $projectName));
             $process = $originalGit->fetch();
             if (!$process->isSuccessful()) {
                 throw new CommandFailureException($process);
             }
         }
         foreach ($config->walkBundles($projectName) as $repositoryAlias => $repositoryConfig) {
             $output->writeln(sprintf('<fg=green>Analyzing bundle <fg=cyan>%s</fg=cyan>...</fg=green>', $repositoryConfig['name']));
             foreach ($originalGit->branchList(false, true, 'origin') as $branchAlias => $branchName) {
                 try {
                     $process = $originalGit->revParse()->verify($branchName);
                     if ($process->isSuccessful() && $config->compareBundleBranchHead($projectName, $repositoryAlias, $branchName, $process->getOutput())) {
                         $output->writeln(sprintf('  <fg=green>Branch <fg=cyan>%s</fg=cyan> up to date, skipping...</fg=green>', $branchName));
                         continue;
                     }
                     $output->writeln(sprintf('  <fg=green>Exporting branch <fg=cyan>%s</fg=cyan>...</fg=green>', $branchName));
                     $process = $originalGit->revParse()->verify($this->derivedBranch($repositoryAlias, $branchAlias));
                     $bundleRepositoryPath = $cwd . '/bundles/' . $repositoryAlias;
                     if (!$process->isSuccessful() || !file_exists($bundleRepositoryPath)) {
                         $output->writeln(sprintf('  <fg=green>Splitting into a new <fg=cyan>%s</fg=cyan> branch.</fg=green>', $this->derivedBranch($repositoryAlias, $branchAlias)));
                         $progressBarHelper->reset();
                         $process = $originalGit->subtree()->split($this->derivedBranch($repositoryAlias, $branchAlias), $repositoryConfig['path'], null, 'origin/' . $branchAlias, false, null, $progressBarHelper);
                         $progressBarHelper->finish();
                         if ($progressBarHelper->updatesCount() <= 0) {
                             $output->writeln(sprintf('  <fg=green>Fast-forward update for branch <fg=cyan>%s</fg=cyan>.</fg=green>', $branchAlias));
                         } else {
                             if (!$process->isSuccessful()) {
                                 throw new CommandFailureException($process);
                             }
                         }
                         $bundleGit->setWorkingDirectory($bundleRepositoryPath);
                         if (!file_exists($bundleRepositoryPath)) {
                             $output->writeln(sprintf('  <fg=green>Initializing git repository for <fg=cyan>%s</fg=cyan> bundle.</fg=green>', $repositoryConfig['name']));
                             mkdir($bundleRepositoryPath, 0755, true);
                             $bundleGit->init();
                         }
                         $output->writeln(sprintf('  <fg=green>Pulling branch <fg=cyan>%s</fg=cyan> in the bundle repository.</fg=green>', $this->derivedBranch($repositoryAlias, $branchAlias)));
                         $bundleGit->pull($repositoryPath, $this->derivedBranch($repositoryAlias, $branchAlias));
                     } else {
                         $output->writeln(sprintf('  <fg=green>Updating the <fg=cyan>%s</fg=cyan> bundle\'s code into the <fg=cyan>%s</fg=cyan> branch.</fg=green>', $repositoryConfig['name'], $this->derivedBranch($repositoryAlias, $branchAlias)));
                         $progressBarHelper->reset();
                         $process = $originalGit->subtree()->push($bundleRepositoryPath, $this->derivedBranch($repositoryAlias, $branchAlias), $repositoryConfig['path'], $progressBarHelper);
                         $progressBarHelper->finish();
                         if (!$process->isSuccessful()) {
                             throw new CommandFailureException($process);
                         }
                     }
                     $process = $originalGit->revParse()->verify($branchName);
                     if ($process->isSuccessful()) {
                         $config->updateBundleBranch($projectName, $repositoryAlias, $branchName, $process->getOutput());
                     }
                 } catch (CommandFailureException $e) {
                     $output->writeln($formatter->formatBlock(['An error occurred while exporting subtrees.', $e->__toString()], 'error'));
                 } catch (RuntimeException $e) {
                     $output->writeln($formatter->formatBlock(['An error occurred while exporting subtrees.', $e->__toString()], 'error'));
                 }
             }
         }
     }
     $config->save();
     return 0;
 }
Esempio n. 2
0
 protected function execute(InputInterface $input, OutputInterface $output)
 {
     $cwd = getcwd() . '/' . $input->getOption('working-dir');
     $timeout = (int) $input->getOption('timeout');
     /** @var QuestionHelper $question */
     $question = $this->getHelperSet()->get('question');
     /** @var Config $config */
     $config = new Config($cwd);
     try {
         if (!$config->read()) {
             $output->writeln('<fg=red>No previous config found, initializing.</fg=red>');
         } else {
             $output->writeln('<fg=yellow>Previous config found.</fg=yellow>');
             $output->writeln('<fg=yellow>Loading existing config...</fg=yellow> <fg=green>done</fg=green>');
         }
     } catch (GrenadeRuntimeException $e) {
         $output->writeln('<fg=red>failed</fg=red>');
         $output->writeln('<fg=red>An error occured while parsing .grenade.json file.</fg=red>');
         return -1;
     }
     $github = new Client();
     /** @var Repo $repoApi */
     $repoApi = $github->api('repo');
     /** @var CurrentUser $userApi */
     $userApi = $github->api('me');
     /** @var Organization $orgsApi */
     $orgsApi = $github->api('organization');
     /** @var Git $git */
     $git = new Git(null, $timeout);
     $failures = 0;
     $githubUsername = $question->ask($input, $output, new Question('<fg=green>Your Github account:</fg=green> '));
     while (true) {
         $githubPassword = $question->ask($input, $output, (new Question('<fg=green>Your Github password:</fg=green> '))->setHidden(true));
         $github->authenticate($githubUsername, $githubPassword, Client::AUTH_HTTP_PASSWORD);
         try {
             $userApi->emails()->all();
             break;
         } catch (\Github\Exception\RuntimeException $e) {
             $output->writeln(sprintf('<fg=red>%s</fg=red>', $e->getMessage()));
         }
         if (++$failures >= 3) {
             $output->writeln('<fg=red>Too many connection failures, please check your credentials.</fg=red>');
             return -1;
         }
     }
     if (!file_exists($cwd . '/bundles')) {
         $output->writeln('<fg=red>Bundles folder does not exist, some repositories should exist.</fg=red>');
         return -1;
     }
     foreach ($config->walkProjects() as $projectAlias => $projectConfig) {
         foreach ($config->walkBundles($projectAlias) as $bundleAlias => $bundleRepository) {
             $output->writeln(sprintf('<fg=green>Uploading <fg=cyan>%s</fg=cyan>.</fg=green>', $bundleAlias));
             $bundleRepositoryPath = $cwd . '/bundles/' . $bundleAlias;
             if (($organization = $config->getBundleRemoteOrganization($projectAlias, $bundleAlias)) !== null) {
                 $repositoriesList = $orgsApi->repositories($organization);
             } else {
                 $repositoriesList = $userApi->repositories();
             }
             $repositoryInfo = null;
             foreach ($repositoriesList as $remoteRepositoryInfo) {
                 if ($remoteRepositoryInfo['name'] == $bundleAlias) {
                     $repositoryInfo = $remoteRepositoryInfo;
                     break;
                 }
             }
             $git->setWorkingDirectory($bundleRepositoryPath);
             if ($repositoryInfo === null) {
                 $output->writeln(sprintf('<fg=green>Creating a new repository <fg=cyan>%s</fg=cyan>.</fg=green>', $bundleAlias));
                 $repositoryInfo = $repoApi->create($bundleAlias, sprintf('[READONLY] %s mirror repository', $config->getBundleName($projectAlias, $bundleAlias)), '', true, $organization);
                 if (isset($repositoryInfo['ssh_url'])) {
                     $git->remote()->add('origin', $repositoryInfo['ssh_url']);
                 }
             }
             if (!isset($repositoryInfo['ssh_url'])) {
                 throw new RuntimeException('The repository info has not returned a git URL.');
             }
             $git->pushToMirror('origin');
         }
     }
 }
Esempio n. 3
0
 protected function execute(InputInterface $input, OutputInterface $output)
 {
     $repository = $input->getArgument('project-repository');
     $projectAlias = $input->getArgument('alias') ? $input->getArgument('alias') : basename($repository, '.git');
     $cwd = $input->getOption('working-dir');
     if (strpos($cwd, '/') !== 0 && strpos($cwd, ':') === false) {
         $cwd = getcwd() . '/' . $cwd;
     }
     $timeout = max(1, (int) $input->getOption('timeout'));
     if (!file_exists($cwd . '/repositories')) {
         mkdir($cwd . '/repositories', 0755, true);
     }
     if (!file_exists($cwd . '/bundles')) {
         mkdir($cwd . '/bundles', 0755, true);
     }
     $repositoryPath = $cwd . '/repositories/' . $projectAlias;
     $git = new Git($repositoryPath, $timeout);
     if (!file_exists($repositoryPath)) {
         $output->writeln(sprintf('<fg=green>Cloning <fg=cyan>%s</fg=cyan> from <fg=cyan>%s</fg=cyan>...</fg=green> ', $projectAlias, $repository));
         $git->setWorkingDirectory($cwd . '/repositories/');
         $git->cloneRepository($repository, $projectAlias);
         $git->setWorkingDirectory($repositoryPath);
     } else {
         $output->writeln(sprintf('<fg=green>Fetching <fg=cyan>%s</fg=cyan>...</fg=green> ', $projectAlias));
         $git->fetch();
     }
     /** @var QuestionHelper $question */
     $question = $this->getHelperSet()->get('question');
     /** @var Config $config */
     $config = new Config($cwd);
     try {
         if (!$config->read()) {
             $output->writeln('<fg=red>No previous config found, initializing.</fg=red>');
         } else {
             $output->writeln('<fg=yellow>Previous config found.</fg=yellow>');
             $output->writeln('<fg=yellow>Loading existing config...</fg=yellow> <fg=green>done</fg=green>');
         }
     } catch (GrenadeRuntimeException $e) {
         $output->writeln('<fg=red>failed</fg=red>');
         $output->writeln('<fg=red>An error occured while parsing .grenade.json file.</fg=red>');
         return -1;
     }
     $config->addProject($projectAlias, $repository);
     $codePath = null;
     $bundlesAutocomplete = [];
     if (($count = $config->repositoriesCount($projectAlias)) > 0) {
         if ($count == 1) {
             $output->writeln(sprintf('<fg=green>Found <fg=cyan>%d</fg=cyan> registered bundle:</fg=green> ', $count));
         } else {
             $output->writeln(sprintf('<fg=green>Found <fg=cyan>%d</fg=cyan> registered bundles:</fg=green> ', $count));
         }
         foreach ($config->walkBundles($projectAlias) as $childRepository) {
             $output->writeln(sprintf('<fg=green>  - <fg=cyan>%s</fg=cyan></fg=green>', $childRepository['name']));
         }
     }
     while (true) {
         if ($codePath !== null) {
             $change = 'no' !== $question->ask($input, $output, (new Question('<fg=green>Would you like to change bundles code path? [<fg=yellow>no</fg=yellow>]</fg=green> ', 'no'))->setAutocompleterValues(['yes', 'no']));
             if ($change) {
                 $codePath = null;
             }
         }
         if ($codePath === null) {
             while (true) {
                 $codePath = $question->ask($input, $output, new Question('<fg=green>Enter bundles code path:</fg=green> '));
                 if (!file_exists($repositoryPath . '/' . $codePath)) {
                     $output->writeln(sprintf('<fg=red>Directory <fg=cyan>%s</fg=cyan> does not exist, please enter a valid path.</fg=red>', $codePath));
                     continue;
                 }
                 $bundlesAutocomplete = array_filter(scandir($repositoryPath . '/' . $codePath), function ($bundleName) use($repositoryPath, $codePath) {
                     if (strpos($bundleName, 'Bundle') === false || $bundleName === 'Bundle') {
                         return false;
                     }
                     $bundleBootstrapFiles = array_filter(scandir($repositoryPath . '/' . $codePath . '/' . $bundleName), function ($fileName) use($bundleName) {
                         return strpos($fileName, $bundleName . '.php') !== false;
                     });
                     if (count($bundleBootstrapFiles) <= 0) {
                         return false;
                     }
                     return true;
                 });
                 if (count($bundlesAutocomplete) <= 0) {
                     $output->writeln(sprintf('<fg=red>No bundles were found in path <fg=cyan>%s</fg=cyan></fg=red>', $codePath));
                     continue;
                 }
                 break;
             }
         }
         while (true) {
             $bundleName = $question->ask($input, $output, (new Question(sprintf('<fg=green>Enter the bundle name: </fg=green> ')))->setAutocompleterValues($bundlesAutocomplete));
             if (!file_exists($repositoryPath . '/' . $codePath . '/' . $bundleName)) {
                 $output->writeln(sprintf('<fg=red>Specified bundle <fg=cyan>%s</fg=cyan> does not exist</fg=red>', $bundleName));
                 continue;
             }
             $bundlesBootstrapFiles = array_filter(scandir($repositoryPath . '/' . $codePath . '/' . $bundleName), function ($item) use($bundleName) {
                 return strpos($item, $bundleName . '.php') !== false;
             });
             if (count($bundlesBootstrapFiles) <= 0) {
                 $output->writeln(sprintf('<fg=red>Specified bundle <fg=cyan>%s</fg=cyan> doesn\'t seem to be an actual Symfony2 bundle</fg=red>', $bundleName));
                 continue;
             }
             $bundleFullName = basename(current($bundlesBootstrapFiles), '.php');
             break;
         }
         $guessedBundleAlias = preg_replace_callback('/(^[A-Z]|[A-Z])/', function ($matches) {
             return (strlen($matches[1]) > 0 ? '-' : '') . strtolower($matches[1]);
         }, lcfirst($bundleFullName));
         $bundleAlias = $question->ask($input, $output, (new Question(sprintf('<fg=green>Enter a bundle alias: [<fg=yellow>%s</fg=yellow>]</fg=green> ', $guessedBundleAlias)))->setAutocompleterValues([$guessedBundleAlias]));
         if (empty($bundleAlias)) {
             $bundleAlias = $guessedBundleAlias;
         }
         $isOrganization = 'no' !== $question->ask($input, $output, (new Question('<fg=green>Is remote repository owned by an organization? [<fg=yellow>no</fg=yellow>]</fg=green> ', 'no'))->setAutocompleterValues(['yes', 'no']));
         if ($isOrganization) {
             $organizationName = $question->ask($input, $output, new Question('<fg=green>Enter organization name:</fg=green> '));
         } else {
             $organizationName = null;
         }
         $remoteRepository = $question->ask($input, $output, new Question(sprintf('<fg=green>Enter remote repository name: [<fg=yellow>%s</fg=yellow>]</fg=green> ', $bundleAlias)));
         $config->addBundle($projectAlias, $bundleAlias, $bundleFullName, $codePath . '/' . $bundleName);
         if ($organizationName !== null) {
             $config->setBundleRemoteOrganization($projectAlias, $bundleAlias, $organizationName);
         }
         if ($remoteRepository !== null) {
             $config->setBundleRemoteRepository($projectAlias, $bundleAlias, $remoteRepository);
         }
         $continue = 'no' !== $question->ask($input, $output, (new Question('<fg=green>Would you like to add another bundle? [<fg=yellow>no</fg=yellow>]</fg=green> ', 'no'))->setAutocompleterValues(['yes', 'no']));
         if (!$continue) {
             break;
         }
     }
     $config->save();
 }