diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..d3fcea6
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,33 @@
+/vendor/
+composer.lock
+
+
+.idea
+
+### OSX ###
+*.DS_Store
+.AppleDouble
+.LSOverride
+
+# Icon must end with two \r
+Icon
+
+# Thumbnails
+._*
+
+# Files that might appear in the root of a volume
+.DocumentRevisions-V100
+.fseventsd
+.Spotlight-V100
+.TemporaryItems
+.Trashes
+.VolumeIcon.icns
+.com.apple.timemachine.donotpresent
+
+# Directories potentially created on remote AFP share
+.AppleDB
+.AppleDesktop
+Network Trash Folder
+Temporary Items
+.apdisk
+
diff --git a/README.md b/README.md
index 495109a..c872a89 100644
--- a/README.md
+++ b/README.md
@@ -1,35 +1,51 @@
-
+
+
+
-
-
-
+
+
ContinuousPHP© is the first and only PHP-centric PaaS to build, package, test and deploy applications in the same workflow.
# ContinuousPHP\Cli
-CLI for ContinuousPHP platform. Manage project and build easily from your favorite terminal.
+CLI for the ContinuousPHP platform. Manage projects and build easily from your favorite terminal.
-## Installation
+## Installation as Phar ( Recommended )
-With [Composer](https://getcomposer.org/), to include this library into your dependencies, you need to require [`continuousphp/cli`](https://packagist.org/packages/continuousphp/cli):
+Download the latest version of continuousphpcli as a Phar:
```sh
-$ composer require continuousphp/cli '~0.0'
+$ curl -LSs https://continuousphp.github.io/cli/phar-installer.php | php
```
-## Usage
+The command will check your PHP settings, warn you of any issues, and then download it to the current directory.
+From there, you may place it anywhere you want to make it easier to access (such as `/usr/local/bin`) and chmod it to 755.
+You can even rename it to just `continuousphpcli` to avoid having to type the .phar extension every time.
+
+## Documentation
+
+You can find Markdown documentation into `docs` subfolder or on web version at https://continuousphp.github.io/cli/doc
+Thanks to open an issue if you see something missing in our documentation.
+
+## Credit
+
+This project was made based on Open-Source project, thanks to them!
+
+ * [Box](https://github.com/box-project/box2) - PHAR builder
+ * [Symfony\Console](https://github.com/symfony/console) - PHP Console Service
+ * [Hoa\Console](https://github.com/hoaproject/Console) - PHP Console library
## Contributing
1. Fork it :clap:
2. Create your feature branch: `git checkout -b feat/my-new-feature`
-3. Write your Unit and Functional testing
+3. Write your Unit and Functional tests
4. Commit your changes: `git commit -am 'Add some feature'`
5. Push to the branch: `git push origin feat/my-new-feature`
-6. Submit a pull request with the detail of your implementation
+6. Submit a pull request with the details of your implementation
7. Take a drink during our review and merge :beers:
diff --git a/bin/continuousphp b/bin/continuousphp
new file mode 100755
index 0000000..05e96a7
--- /dev/null
+++ b/bin/continuousphp
@@ -0,0 +1,20 @@
+#!/usr/bin/env php
+create()
+ ->run()
+;
diff --git a/box.json b/box.json
new file mode 100644
index 0000000..7700554
--- /dev/null
+++ b/box.json
@@ -0,0 +1,30 @@
+{
+ "files": [
+ "constants.php"
+ ],
+ "directories": [
+ "src"
+ ],
+ "finder": [
+ {
+ "name": "*.php",
+ "exclude": [
+ "phpunit",
+ "phpunit-test-case",
+ "Tester",
+ "Tests",
+ "Test",
+ "tests",
+ "yaml"
+ ],
+ "in": "vendor"
+ }
+ ],
+ "git-version": "git-version",
+ "replacements": {
+ "my-custom-place-holder": "custom-value-dev-master"
+ },
+ "main": "bin/continuousphp",
+ "output": "continuousphp-@git-version@.phar",
+ "stub": true
+}
\ No newline at end of file
diff --git a/composer.json b/composer.json
new file mode 100644
index 0000000..8cc0075
--- /dev/null
+++ b/composer.json
@@ -0,0 +1,35 @@
+{
+ "name": "continuousphp/cli",
+ "description": "The command line interface to ContinuousPHP Platform",
+ "type": "library",
+ "license": "Apache-2.0",
+ "authors": [
+ {
+ "name": "Pierre Tomasina",
+ "email": "pierre.tomasina@continuousphp.com"
+ }
+ ],
+ "require": {
+ "continuousphp/sdk": "dev-feat/entities",
+ "symfony/console": "^3.3",
+ "hoa/console": "~3.0"
+ },
+ "autoload": {
+ "psr-4": {
+ "Continuous\\Cli\\": "src/"
+ },
+ "files": ["constants.php"]
+ },
+ "autoload-dev": {
+ "psr-4": {
+ "Continuous\\Cli\\Tests\\": "tests/"
+ }
+ },
+ "bin": ["bin/continuousphp"],
+ "repositories": [
+ {
+ "type": "vcs",
+ "url": "https://github.com/Pierozi/guzzle-services.git"
+ }
+ ]
+}
diff --git a/constants.php b/constants.php
new file mode 100644
index 0000000..d9cdb0a
--- /dev/null
+++ b/constants.php
@@ -0,0 +1,8 @@
+"continuousphpcli.phar","sha1"=>sha1_file("../'$PHAR_NAME'"),"url"=>"https://github.com/continuousphp/cli/releases/download/'$TAG'/continuousphpcli.phar","version"=>substr("'$TAG'",1)]; file_put_contents("manifest.json", json_encode($x)); print_r($x);'
+
+git config user.email "info@continuousphp.com"
+git config user.name "${CPHP_BUILT_BY}"
+
+git add -A doc
+git add manifest.json
+
+git commit -m "Update doc to tag $TAG"
+git push origin gh-pages
\ No newline at end of file
diff --git a/docs/index.md b/docs/index.md
new file mode 100644
index 0000000..b043f72
--- /dev/null
+++ b/docs/index.md
@@ -0,0 +1,38 @@
+# What is ContinuousPHP
+
+ContinuousPHP is the first and only PHP-centric PaaS to build, package, test and deploy applications in the same workflow.
+
+The ContinuousPHP CLI is a command line interface for the ContinuousPHP Platform.
+
+## Installation
+
+We recommend using the php installer script to install the latest version
+of continuousphpcli PHAR.
+
+ $ curl -LSs https://continuousphp.github.io/cli/phar-installer.php | php
+ # Move the phar in your user bin directory
+ $ mv continuousphpcli.phar /usr/local/bin/continuousphpcli
+
+The command will check your PHP settings, warn you of any issues, and then download it to the current directory.
+From there, you may place it anywhere you want to make it easier to access (such as `/usr/local/bin`) and chmod it to 755.
+You can even rename it to just `continuousphpcli` to avoid having to type the .phar extension every time.
+
+## Configuration
+
+By default, some of the continuousphp API requests do not require to be authenticated.
+But you will certainly need to authenticate for commands that require permissions, like starting or stopping a build.
+
+The cli implements a profile system to easily use different continuousphp accounts.
+
+Each profile must be configured with the continuousphp user token. You can find a personal token
+on your credentials page at https://app.continuousphp.com/credentials
+
+Configure a new profile in interactive mode with this command:
+
+ $ continuousphpcli configure
+ > Profile name [default]: myProfileName
+ > User Token: XXXXXXXXXX
+ < Profile myUserAccount saved in /home/user/.continuousphp/credentials
+
+If you choose `default` as the profile name, the continuousphpcli will automatically use this credential.
+Otherwise, you must specify the option `--profile myProfileName` on each command.
\ No newline at end of file
diff --git a/mkdocs.yml b/mkdocs.yml
new file mode 100644
index 0000000..d72fa8c
--- /dev/null
+++ b/mkdocs.yml
@@ -0,0 +1,2 @@
+site_name: ContinuousPHP Cli
+theme: 'material'
diff --git a/src/ApplicationFactory.php b/src/ApplicationFactory.php
new file mode 100644
index 0000000..d0485e4
--- /dev/null
+++ b/src/ApplicationFactory.php
@@ -0,0 +1,50 @@
+add(new ConfigureCommand());
+ $application->add(new CompanyListCommand());
+ $application->add(new RepositoryListCommand());
+ $application->add(new ProjectListCommand());
+ $application->add(new BuildListCommand());
+ $application->add(new BuildStartCommand());
+ $application->add(new BuildStopCommand());
+
+ return $application;
+ }
+
+ /**
+ * Return the current version of continuousphp cli.
+ *
+ * @return string
+ */
+ public static function getVersion()
+ {
+ return constant(__NAMESPACE__ . '\\' . 'version');
+ }
+}
\ No newline at end of file
diff --git a/src/Command/Build/BuildListCommand.php b/src/Command/Build/BuildListCommand.php
new file mode 100644
index 0000000..6258975
--- /dev/null
+++ b/src/Command/Build/BuildListCommand.php
@@ -0,0 +1,114 @@
+setName('build:list')
+ ->setDescription('List of builds for specific project.')
+ ->setHelp('This command help you to list the builds of specific project and pipeline.')
+ ->addArgument('provider', InputArgument::REQUIRED, 'The repository provider')
+ ->addArgument('repository', InputArgument::REQUIRED, 'The repository name')
+ ;
+
+ $this
+ ->addOption(
+ 'ref',
+ 'r',
+ InputOption::VALUE_OPTIONAL,
+ 'the pipeline ref'
+ )
+ ->addOption(
+ 'state',
+ 's',
+ InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY,
+ 'the build status',
+ Build::STATE
+ )
+ ->addOption(
+ 'noPr',
+ null,
+ InputOption::VALUE_NONE,
+ 'remove the PullRequest of result'
+ )
+ ;
+ }
+
+ /**
+ * @param InputInterface $input
+ * @param OutputInterface $output
+ */
+ protected function execute(InputInterface $input, OutputInterface $output)
+ {
+ parent::execute($input, $output);
+
+ $this->showLoader($output, 'Loading builds...');
+ $ref = $input->getOption('ref');
+ $state = $input->getOption('state');
+
+ $params = [
+ 'provider' => static::mapProviderToSdk($input->getArgument('provider')),
+ 'repository' => $input->getArgument('repository'),
+ 'state' => $state,
+ ];
+
+ if ($ref) {
+ $params['pipeline_id'] = $ref;
+ }
+
+ if (true === $input->getOption('noPr')) {
+ $params['exclude_pull_requests'] = '1';
+ }
+
+ /** @var Collection $collection */
+ $collection = $this->continuousClient->getBuilds($params);
+ $rows = [];
+
+ $this->hideLoader($output);
+
+ foreach ($collection as $id => $build) {
+
+ $created = \DateTimeImmutable::createFromFormat('Y-m-d*H:i:sP', $build->get('created'));
+
+ $launchUser = $build->getLaunchUser();
+ $result = $build->get('result');
+ $resultOutput = "$result>";
+
+ $successActivities = array_filter($build->get('activities'), function($item) {
+ return true === $item['result'];
+ });
+
+ $rows[] = [
+ $id,
+ $build->get('ref'),
+ $build->get('pullRequestNumber') ? $build->get('pullRequestNumber') : "-",
+ $build->get('state'),
+ $resultOutput,
+ $build->getDuration()->format('%H:%I:%S'),
+ count($successActivities) . '/' . count($build->get('activities')),
+ round($build->get('codeCoverage')) . "%",
+ $launchUser->displayName(),
+ $created->format('d/m/Y H:i:s'),
+ ];
+ }
+
+ $table = new Table($output);
+ $table
+ ->setHeaders(['ID', 'Ref', 'PR', 'State', 'Result', 'Duration', 'Activities Success', 'Code Coverage', 'Launch by', 'date'])
+ ->setRows($rows)
+ ->render()
+ ;
+ }
+}
\ No newline at end of file
diff --git a/src/Command/Build/BuildStartCommand.php b/src/Command/Build/BuildStartCommand.php
new file mode 100644
index 0000000..9ef8113
--- /dev/null
+++ b/src/Command/Build/BuildStartCommand.php
@@ -0,0 +1,69 @@
+setName('build:start')
+ ->setDescription('start a build for specific project.')
+ ->setHelp('This command help you to start build for specific pipeline project.')
+ ->addArgument('provider', InputArgument::REQUIRED, 'The repository provider')
+ ->addArgument('repository', InputArgument::REQUIRED, 'The repository name')
+ ->addArgument('ref', InputArgument::REQUIRED, 'The git reference')
+ ;
+
+ $this
+ ->addOption(
+ 'pull-request',
+ 'pr',
+ InputOption::VALUE_OPTIONAL,
+ 'the PR id you want build'
+ )
+ ;
+
+ $this
+ ->addOption(
+ 'attach',
+ 'a',
+ InputOption::VALUE_NONE,
+ 'attach the log'
+ )
+ ;
+ }
+
+ /**
+ * @param InputInterface $input
+ * @param OutputInterface $output
+ */
+ protected function execute(InputInterface $input, OutputInterface $output)
+ {
+ parent::execute($input, $output);
+
+ $this->showLoader($output, 'Starting builds...');
+
+ $params = [
+ 'provider' => static::mapProviderToSdk($input->getArgument('provider')),
+ 'repository' => $input->getArgument('repository'),
+ 'ref' => $input->getArgument('ref'),
+ ];
+
+ if ($pr = $input->getOption('pull-request')) {
+ $params['pull_request'] = $pr;
+ }
+
+ /** @var Build $build */
+ $build = $this->continuousClient->startBuild($params);
+
+ $output->writeln('Build started with ID ' . $build->get('buildId'));
+ }
+}
\ No newline at end of file
diff --git a/src/Command/Build/BuildStopCommand.php b/src/Command/Build/BuildStopCommand.php
new file mode 100644
index 0000000..b62695e
--- /dev/null
+++ b/src/Command/Build/BuildStopCommand.php
@@ -0,0 +1,45 @@
+setName('build:stop')
+ ->setDescription('stop a build.')
+ ->setHelp('This command help you to stop build for specific pipeline project.')
+ ->addArgument('provider', InputArgument::REQUIRED, 'The repository provider')
+ ->addArgument('repository', InputArgument::REQUIRED, 'The repository name')
+ ->addArgument('build-id', InputArgument::REQUIRED, 'The build id you want to stop')
+ ;
+ }
+
+ /**
+ * @param InputInterface $input
+ * @param OutputInterface $output
+ */
+ protected function execute(InputInterface $input, OutputInterface $output)
+ {
+ parent::execute($input, $output);
+
+ $this->showLoader($output, 'stopping builds...');
+
+ $params = [
+ 'provider' => static::mapProviderToSdk($input->getArgument('provider')),
+ 'repository' => $input->getArgument('repository'),
+ 'buildId' => $input->getArgument('build-id'),
+ ];
+
+ $result = $this->continuousClient->cancelBuild($params);
+ var_dump($result);
+
+ $output->writeln('Build has been cancelled.');
+ }
+}
\ No newline at end of file
diff --git a/src/Command/CommandAbstract.php b/src/Command/CommandAbstract.php
new file mode 100644
index 0000000..a8b7193
--- /dev/null
+++ b/src/Command/CommandAbstract.php
@@ -0,0 +1,120 @@
+addTokenOption();
+ }
+
+ public static function mapProviderToSdk($provider)
+ {
+ if (in_array(strtolower(trim($provider)), ['github', 'git hub']))
+ {
+ return 'git-hub';
+ }
+
+ if (in_array(strtolower(trim($provider)), ['bb']))
+ {
+ return 'bitbucket';
+ }
+
+ return $provider;
+ }
+
+ protected function addTokenOption()
+ {
+ $this
+ ->addOption(
+ 'token',
+ null,
+ InputOption::VALUE_OPTIONAL,
+ 'The token of the continuousphp user',
+ null
+ )
+ ->addOption(
+ 'profile',
+ null,
+ InputOption::VALUE_OPTIONAL,
+ 'The profile of the configured credentials. See route configure',
+ null
+ );
+ }
+
+ /**
+ * @param InputInterface $input
+ * @param OutputInterface $output
+ */
+ protected function execute(InputInterface $input, OutputInterface $output)
+ {
+ $token = $input->getOption('token');
+ $profile = $input->getOption('profile');
+
+ if (null === $token && false === ($token = getenv('CPHP_TOKEN'))) {
+
+ $profile = empty($profile) ? 'default' : $profile;
+ $token = ConfigureCommand::getToken($profile);
+
+ if (null === $token) {
+ $output->writeln("WARNING : ContinuousPHP Token was not found");
+ }
+ }
+
+ $this->continuousClient = \Continuous\Sdk\Service::factory([
+ 'token' => $token
+ ]);
+ }
+
+ protected function showLoader($output, $message = '')
+ {
+ $this->loader = new ProgressBar($output, 1);
+
+ if ($message) {
+ $this->loader->setFormatDefinition('custom', ' %current%/%max% -- %message%');
+ $this->loader->setFormat('custom');
+ $this->loader->setMessage($message);
+
+ $this->loader->start();
+ $this->loader->advance();
+ } else {
+ $this->loader->start();
+ }
+ }
+
+ protected function hideLoader($output)
+ {
+ $this->loader->finish();
+ $this->loader = null;
+
+ $output->writeln("\n");
+ }
+}
\ No newline at end of file
diff --git a/src/Command/Company/CompanyListCommand.php b/src/Command/Company/CompanyListCommand.php
new file mode 100644
index 0000000..7802197
--- /dev/null
+++ b/src/Command/Company/CompanyListCommand.php
@@ -0,0 +1,71 @@
+setName('company:list')
+ ->setDescription('List Companies.')
+ ->setHelp('This command related to companies declared on continuous.')
+ ;
+
+ $this
+ ->addOption(
+ 'filter-name',
+ null,
+ InputOption::VALUE_OPTIONAL,
+ 'filter apply on name of companies result'
+ );
+ }
+
+ /**
+ * @param InputInterface $input
+ * @param OutputInterface $output
+ */
+ protected function execute(InputInterface $input, OutputInterface $output)
+ {
+ parent::execute($input, $output);
+
+ $filterName = $input->getOption('filter-name');
+
+ $collection = $this->continuousClient->getCompanies();
+ $rows = [];
+
+ foreach ($collection as $id => $company) {
+ $name = $company->get('name');
+
+ if (null !== $filterName && false === strpos(strtolower($name), $filterName)) {
+ continue;
+ }
+
+ $rows[] = [
+ $id,
+ $name,
+ $company->get('website'),
+ $company->get('email'),
+ $company->get('vat'),
+ $company->get('currency'),
+ ];
+ }
+
+ $table = new Table($output);
+ $table
+ ->setHeaders(['ID', 'Name', 'Website', 'Email', 'Vat', 'Currency'])
+ ->setRows($rows)
+ ->render()
+ ;
+ }
+}
\ No newline at end of file
diff --git a/src/Command/ConfigureCommand.php b/src/Command/ConfigureCommand.php
new file mode 100644
index 0000000..e68b8ce
--- /dev/null
+++ b/src/Command/ConfigureCommand.php
@@ -0,0 +1,136 @@
+setName('configure')
+ ->setDescription('Configure cphp profile.')
+ ->setHelp('This command help you to create multiple profile corresponding to cphp user token. Can be found at https://app.continuousphp.com/credentials')
+ ;
+
+ $this
+ ->addOption(
+ 'profile',
+ null,
+ InputOption::VALUE_OPTIONAL,
+ 'Profile name'
+ );
+ }
+
+ /**
+ * @param InputInterface $input
+ * @param OutputInterface $output
+ */
+ protected function execute(InputInterface $input, OutputInterface $output)
+ {
+ parent::execute($input, $output);
+
+ $this->obtainProfileToken($input, $output, $profile, $token);
+ $path = $this->saveProfile($profile, $token);
+
+ $output->writeln("Profile $profile saved in $path");
+ }
+
+ protected function obtainProfileToken(InputInterface $input, OutputInterface $output, & $profile, & $token)
+ {
+ $profile = $input->getOption('profile');
+ $token = $input->getOption('token');
+
+ if (true === $input->getOption('no-interaction')) {
+ if (!$profile && !$token) {
+ $output->writeln(
+ "ERROR : no-interaction was specified. You must declare profile and token as option"
+ );
+ }
+
+ return;
+ }
+
+ $helper = $this->getHelper('question');
+
+ if (null === $profile) {
+ $profile = $helper->ask(
+ $input, $output,
+ new Question('Profile name [default]: ', 'default')
+ );
+ }
+
+ if (null === $token) {
+ $token = $helper->ask(
+ $input, $output,
+ new Question('User Token: ')
+ );
+ }
+ }
+
+ protected function saveProfile($profile, $token)
+ {
+ $profiles = self::getProfiles();
+ $profiles[$profile] = [
+ 'token' => $token
+ ];
+
+ $path = static::getCredentialsPath();
+ $pathDir = dirname($path);
+
+ if (!file_exists($pathDir)) {
+ mkdir($pathDir);
+ }
+
+ $handle = fopen($path, 'w+');
+
+ if (false === is_resource($handle)) {
+ throw new \Exception("Error during opening/creating credentials file at $path");
+ }
+
+ foreach ($profiles as $name => $profile) {
+ fwrite($handle, "[$name]\n");
+
+ foreach ($profile as $k => $v) {
+ fwrite($handle, "$k = $v\n");
+ }
+ }
+
+ fclose($handle);
+
+ return $path;
+ }
+
+ protected static function getCredentialsPath()
+ {
+ $home = getenv('HOME');
+
+ if (empty($home)) {
+ $home = '~';
+ }
+
+ return "{$home}/.continuousphp/credentials";
+ }
+
+ public static function getProfiles()
+ {
+ $path = static::getCredentialsPath();
+
+ if (false === file_exists($path)) {
+ return [];
+ }
+
+ return parse_ini_file($path, true);
+ }
+
+ public static function getToken($profile)
+ {
+ $profiles = static::getProfiles();
+
+ return !empty($profiles[$profile]) ? $profiles[$profile]['token'] : null;
+ }
+}
\ No newline at end of file
diff --git a/src/Command/Project/ProjectListCommand.php b/src/Command/Project/ProjectListCommand.php
new file mode 100644
index 0000000..05eca41
--- /dev/null
+++ b/src/Command/Project/ProjectListCommand.php
@@ -0,0 +1,71 @@
+setName('project:list')
+ ->setDescription('List of project configured.')
+ ->setHelp('This command help you to find the repository already configured on ContinuousPHP.')
+ ;
+
+ $this
+ ->addOption(
+ 'filter-name',
+ null,
+ InputOption::VALUE_OPTIONAL,
+ 'filter apply on name of repositories result'
+ );
+ }
+
+ /**
+ * @param InputInterface $input
+ * @param OutputInterface $output
+ */
+ protected function execute(InputInterface $input, OutputInterface $output)
+ {
+ parent::execute($input, $output);
+
+ $filterName = $input->getOption('filter-name');
+ $this->showLoader($output, 'Loading projects from providers (github, bitbucket, gitlab)...');
+
+ /** @var Collection $collection */
+ $collection = $this->continuousClient->getProjects();
+ $rows = [];
+
+ $this->hideLoader($output);
+
+ foreach ($collection as $id => $project) {
+ $name = $project->get('name');
+
+ if (null !== $filterName && false === strpos(strtolower($name), $filterName)) {
+ continue;
+ }
+
+ $rows[] = [
+ $project->getProvider()->get('name'),
+ $name,
+ $project->get('canSeeSettings') ? 'Yes' : "No",
+ $project->get('canEditSettings') ? 'Yes' : "No",
+ $project->get('canBuild') ? 'Yes' : "No",
+ ];
+ }
+
+ $table = new Table($output);
+ $table
+ ->setHeaders(['Provider', 'Name', 'View settings', 'Edit settings', 'Run build'])
+ ->setRows($rows)
+ ->render()
+ ;
+ }
+}
\ No newline at end of file
diff --git a/src/Command/Repository/RepositoryListCommand.php b/src/Command/Repository/RepositoryListCommand.php
new file mode 100644
index 0000000..d4bee46
--- /dev/null
+++ b/src/Command/Repository/RepositoryListCommand.php
@@ -0,0 +1,73 @@
+setName('repo:list')
+ ->setDescription('List of repositories not yet configured.')
+ ->setHelp('This command help you to find the repository that you can configure on ContinuousPHP and has not yet be initialized.')
+ ;
+
+ $this
+ ->addOption(
+ 'filter-name',
+ null,
+ InputOption::VALUE_OPTIONAL,
+ 'filter apply on name of repositories result'
+ );
+ }
+
+ /**
+ * @param InputInterface $input
+ * @param OutputInterface $output
+ */
+ protected function execute(InputInterface $input, OutputInterface $output)
+ {
+ parent::execute($input, $output);
+
+ $filterName = $input->getOption('filter-name');
+ $this->showLoader($output, 'Loading repositories from providers (github, bitbucket, gitlab)...');
+
+ /** @var Collection $collection */
+ $collection = $this->continuousClient->getRepositories();
+ $rows = [];
+
+ $this->hideLoader($output);
+
+ foreach ($collection as $id => $repository) {
+ $name = $repository->get('name');
+
+ if (null !== $filterName && false === strpos(strtolower($name), $filterName)) {
+ continue;
+ }
+
+ $rows[] = [
+ $repository->getProvider()->get('name'),
+ $repository->get('isPrivate') ? 'Yes' : "No",
+ $id,
+ $name,
+ $repository->get('owner'),
+ $repository->get('htmlUrl'),
+ $repository->get('description'),
+ ];
+ }
+
+ $table = new Table($output);
+ $table
+ ->setHeaders(['Provider', 'Private', 'ID', 'Name', 'Owner', 'Url', 'Description'])
+ ->setRows($rows)
+ ->render()
+ ;
+ }
+}
\ No newline at end of file