/** * {@inheritdoc} */ protected function execute(InputInterface $input, OutputInterface $output) { $this->validateInput($input); $project = $this->getSelectedProject(); try { $domains = $project->getDomains(); } catch (ClientException $e) { $this->handleApiException($e, $project); return 1; } if (empty($domains)) { $this->stdErr->writeln('No domains found for ' . $this->api()->getProjectLabel($project) . '.'); $this->stdErr->writeln("\nAdd a domain to the project by running <info>" . self::$config->get('application.executable') . " domain:add [domain-name]</info>"); return 1; } $table = new Table($input, $output); $header = ['Name', 'SSL enabled', 'Creation date']; $rows = $this->buildDomainRows($domains); if ($table->formatIsMachineReadable()) { $table->render($rows, $header); return 0; } $this->stdErr->writeln("Your domains are: "); $table->render($rows, $header); $this->stdErr->writeln(''); $this->stdErr->writeln('To add a new domain, run: <info>' . self::$config->get('application.executable') . ' domain:add [domain-name]</info>'); $this->stdErr->writeln('To view a domain, run: <info>' . self::$config->get('application.executable') . ' domain:get [domain-name]</info>'); $this->stdErr->writeln('To delete a domain, run: <info>' . self::$config->get('application.executable') . ' domain:delete [domain-name]</info>'); return 0; }
/** * {@inheritdoc} */ protected function execute(InputInterface $input, OutputInterface $output) { $this->validateInput($input); $project = $this->getSelectedProject(); try { $domains = $project->getDomains(); } catch (ClientException $e) { $this->handleApiException($e, $project); return 1; } if (empty($domains)) { $this->stdErr->writeln("No domains found for <info>{$project->title}</info>"); $this->stdErr->writeln("\nAdd a domain to the project by running <info>platform domain:add [domain-name]</info>"); return 1; } $table = new Table($input, $output); $header = ['Name', 'SSL enabled', 'Creation date']; $rows = $this->buildDomainRows($domains); if ($table->formatIsMachineReadable()) { $table->render($rows, $header); return 0; } $this->stdErr->writeln("Your domains are: "); $table->render($rows, $header); $this->stdErr->writeln("\nAdd a new domain by running <info>platform domain:add [domain-name]</info>"); $this->stdErr->writeln("Delete a domain by running <info>platform domain:delete [domain-name]</info>"); return 0; }
protected function execute(InputInterface $input, OutputInterface $output) { $this->validateInput($input); $id = $input->getArgument('id'); if ($id) { $integration = $this->getSelectedProject()->getIntegration($id); if (!$integration) { $this->stdErr->writeln("Integration not found: <error>{$id}</error>"); return 1; } $results = [$integration]; } else { $results = $this->getSelectedProject()->getIntegrations(); if (!$results) { $this->stdErr->writeln('No integrations found'); return 1; } } $table = new Table($input, $output); $header = ['ID', 'Type', 'Details']; $rows = []; foreach ($results as $integration) { $data = $this->formatIntegrationData($integration); $rows[] = [$integration->id, $integration->type, $data]; } $table->render($rows, $header); return 0; }
protected function execute(InputInterface $input, OutputInterface $output) { $this->validateInput($input); $environment = $this->getSelectedEnvironment(); $startsAt = null; if ($input->getOption('start') && !($startsAt = strtotime($input->getOption('start')))) { $this->stdErr->writeln('Invalid date: <error>' . $input->getOption('start') . '</error>'); return 1; } $limit = (int) $input->getOption('limit'); $activities = $environment->getActivities($limit, $input->getOption('type'), $startsAt); if (!$activities) { $this->stdErr->writeln('No activities found'); return 1; } $table = new Table($input, $output); $rows = []; foreach ($activities as $activity) { $description = $activity->getDescription(); if (!$table->formatIsMachineReadable()) { $description = wordwrap($description, 40); } $rows[] = [$activity->id, date('Y-m-d H:i:s', strtotime($activity['created_at'])), $description, $activity->getCompletionPercent(), ActivityUtil::formatState($activity->state)]; } if (!$table->formatIsMachineReadable()) { $this->stdErr->writeln("Activities for the environment <info>" . $environment->id . "</info>"); } $headers = ['ID', 'Created', 'Description', '% Complete', 'State']; $table->render($rows, $headers); return 0; }
protected function execute(InputInterface $input, OutputInterface $output) { $this->validateInput($input); $environment = $this->getSelectedEnvironment(); $routes = $environment->getRoutes(); if (empty($routes)) { $this->stdErr->writeln("No routes found"); return 0; } $table = new Table($input, $output); $header = ['Route', 'Type', 'To', 'Cache', 'SSI']; $rows = []; foreach ($routes as $route) { $row = [$route->id, $route->type, $route->type == 'upstream' ? $route->upstream : $route->to]; if ($table->formatIsMachineReadable()) { $row[] = json_encode($route->cache); $row[] = json_encode($route->ssi); } else { $row[] = wordwrap(json_encode($route->cache), 30, "\n", true); $row[] = wordwrap(json_encode($route->ssi), 30, "\n", true); } $rows[] = $row; } if (!$table->formatIsMachineReadable()) { $this->stdErr->writeln("Routes for the environment <info>{$environment->id}</info>:"); } $table->render($rows, $header); return 0; }
protected function execute(InputInterface $input, OutputInterface $output) { $this->validateInput($input); if ($name = $input->getArgument('name')) { $variable = $this->getSelectedEnvironment()->getVariable($name); if (!$variable) { $this->stdErr->writeln("Variable not found: <error>{$name}</error>"); return 1; } if ($input->getOption('pipe')) { $output->writeln($variable->value); } else { $output->writeln(sprintf('<info>%s</info>: %s', $variable->name, $variable->value)); } return 0; } $results = $this->getSelectedEnvironment()->getVariables(); if (!$results) { $this->stdErr->writeln('No variables found'); return 1; } if ($input->getOption('pipe')) { throw new \InvalidArgumentException('Specify a variable name to use --pipe'); } $table = new Table($input, $output); $header = ['ID', 'Value', 'Inherited', 'JSON']; $rows = []; foreach ($results as $variable) { $rows[] = [new AdaptiveTableCell($variable->id, ['wrap' => false]), $variable->value, $variable->inherited ? 'Yes' : 'No', $variable->is_json ? 'Yes' : 'No']; } $table->render($rows, $header); return 0; }
protected function execute(InputInterface $input, OutputInterface $output) { $this->validateInput($input); $environment = $this->getSelectedEnvironment(); $startsAt = null; if ($input->getOption('start') && !($startsAt = strtotime($input->getOption('start')))) { $this->stdErr->writeln('Invalid date: <error>' . $input->getOption('start') . '</error>'); return 1; } $table = new Table($input, $output); if (!$table->formatIsMachineReadable()) { $this->stdErr->writeln("Finding snapshots for the environment <info>{$environment->id}</info>"); } $results = $environment->getActivities($input->getOption('limit'), 'environment.backup', $startsAt); if (!$results) { $this->stdErr->writeln('No snapshots found'); return 1; } $headers = ['Created', '% Complete', 'Snapshot name']; $rows = []; foreach ($results as $result) { $payload = $result->payload; $snapshot_name = !empty($payload['backup_name']) ? $payload['backup_name'] : 'N/A'; $rows[] = [date('Y-m-d H:i:s', strtotime($result->created_at)), $result->getCompletionPercent(), new AdaptiveTableCell($snapshot_name, ['wrap' => false])]; } $table->render($rows, $headers); return 0; }
protected function execute(InputInterface $input, OutputInterface $output) { $tunnels = $this->getTunnelInfo(); $allTunnelsCount = count($tunnels); if (!$allTunnelsCount) { $this->stdErr->writeln('No tunnels found.'); return 1; } // Filter tunnels according to the current project and environment, if // available. if (!$input->getOption('all')) { $tunnels = $this->filterTunnels($tunnels, $input); if (!count($tunnels)) { $this->stdErr->writeln('No tunnels found. Use --all to view all tunnels.'); return 1; } } $table = new Table($input, $output); $headers = ['Port', 'Project', 'Environment', 'App', 'Relationship']; $rows = []; foreach ($tunnels as $tunnel) { $rows[] = [$tunnel['localPort'], $tunnel['projectId'], $tunnel['environmentId'], $tunnel['appName'] ?: '[default]', $this->formatTunnelRelationship($tunnel)]; } $table->render($rows, $headers); if (!$table->formatIsMachineReadable()) { $this->stdErr->writeln(''); if (!$input->getOption('all') && count($tunnels) < $allTunnelsCount) { $this->stdErr->writeln('List all tunnels with: <info>platform tunnel:list --all</info>'); } $this->stdErr->writeln("View tunnel details with: <info>platform tunnel:info</info>"); $this->stdErr->writeln("Close tunnels with: <info>platform tunnel:close</info>"); } return 0; }
/** * {@inheritdoc} */ protected function execute(InputInterface $input, OutputInterface $output) { if (!($projectRoot = $this->getProjectRoot())) { throw new RootNotFoundException(); } $repository = $projectRoot . '/' . LocalProject::REPOSITORY_DIR; $apps = LocalApplication::getApplications($repository); $rows = []; foreach ($apps as $app) { $rows[] = [$app->getName(), $app->getRoot()]; } $table = new Table($input, $output); $table->render($rows, ['Name', 'Path']); }
/** * {@inheritdoc} */ protected function execute(InputInterface $input, OutputInterface $output) { if (!($projectRoot = $this->getProjectRoot())) { throw new RootNotFoundException(); } $apps = LocalApplication::getApplications($projectRoot, self::$config); $rows = []; foreach ($apps as $app) { $config = $app->getConfig(); $type = isset($config['type']) ? $config['type'] : null; $rows[] = [$app->getName(), $type, $app->getRoot()]; } $table = new Table($input, $output); $table->render($rows, ['Name', 'Type', 'Path']); }
protected function execute(InputInterface $input, OutputInterface $output) { $keys = $this->api()->getClient()->getSshKeys(); if (empty($keys)) { $this->stdErr->writeln("You do not yet have any SSH public keys in your " . self::$config->get('service.name') . " account"); } else { $table = new Table($input, $output); $headers = ['ID', 'Title', 'Fingerprint']; $rows = []; foreach ($keys as $key) { $rows[] = [$key['key_id'], $key['title'], $key['fingerprint']]; } if ($table->formatIsMachineReadable()) { $table->render($rows, $headers); return 0; } $this->stdErr->writeln("Your SSH keys are:"); $table->render($rows, $headers); } $this->stdErr->writeln(''); $this->stdErr->writeln("Add a new SSH key with: <info>" . self::$config->get('application.executable') . " ssh-key:add</info>"); $this->stdErr->writeln("Delete an SSH key with: <info>" . self::$config->get('application.executable') . " ssh-key:delete [id]</info>"); return !empty($keys) ? 0 : 1; }
protected function execute(InputInterface $input, OutputInterface $output) { $refresh = $input->hasOption('refresh') && $input->getOption('refresh'); $projects = $this->getProjects($refresh); if ($input->getOption('pipe')) { $output->writeln(array_keys($projects)); return 0; } $table = new Table($input, $output); $rows = []; foreach ($projects as $project) { $rows[] = [$project->id, $project->title, $project->getLink('#ui')]; } $header = ['ID', 'Title', 'URL']; if ($table->formatIsMachineReadable()) { $table->render($rows, $header); return 0; } $this->stdErr->writeln("Your projects are: "); $table->render($rows, $header); $this->stdErr->writeln("\nGet a project by running <info>platform get [id]</info>"); $this->stdErr->writeln("List a project's environments by running <info>platform environments</info>"); return 0; }
protected function execute(InputInterface $input, OutputInterface $output) { $keys = $this->getClient()->getSshKeys(); if (empty($keys)) { $this->stdErr->writeln("You do not yet have any SSH public keys in your Platform.sh account"); } else { $table = new Table($input, $output); $headers = ['ID', 'Title', 'Fingerprint']; $rows = []; foreach ($keys as $key) { $rows[] = [$key['key_id'], $key['title'], $key['fingerprint']]; } if ($table->formatIsMachineReadable()) { $table->render($rows, $headers); return 0; } $this->stdErr->writeln("Your SSH keys are:"); $table->render($rows, $headers); } $this->stdErr->writeln(''); $this->stdErr->writeln("Add a new SSH key by running <info>platform ssh-key:add [path]</info>"); $this->stdErr->writeln("Delete an SSH key by running <info>platform ssh-key:delete [id]</info>"); return !empty($keys) ? 0 : 1; }
protected function execute(InputInterface $input, OutputInterface $output) { $this->validateInput($input, $input->getOption('all')); $project = $this->getSelectedProject(); $startsAt = null; if ($input->getOption('start') && !($startsAt = strtotime($input->getOption('start')))) { $this->stdErr->writeln('Invalid date: <error>' . $input->getOption('start') . '</error>'); return 1; } $limit = (int) $input->getOption('limit'); if ($this->hasSelectedEnvironment() && !$input->getOption('all')) { $environmentSpecific = true; $environment = $this->getSelectedEnvironment(); $activities = $environment->getActivities($limit, $input->getOption('type'), $startsAt); } else { $environmentSpecific = false; $activities = $project->getActivities($limit, $input->getOption('type'), $startsAt); } if (!$activities) { $this->stdErr->writeln('No activities found'); return 1; } $table = new Table($input, $output); $rows = []; foreach ($activities as $activity) { $row = [new AdaptiveTableCell($activity->id, ['wrap' => false]), date('Y-m-d H:i:s', strtotime($activity['created_at'])), $activity->getDescription(), $activity->getCompletionPercent(), ActivityUtil::formatState($activity->state)]; if (!$environmentSpecific) { $row[] = implode(', ', $activity->environments); } $rows[] = $row; } $headers = ['ID', 'Created', 'Description', '% Complete', 'State']; if (!$environmentSpecific) { $headers[] = 'Environment(s)'; } if (!$table->formatIsMachineReadable()) { if ($environmentSpecific && isset($environment)) { $this->stdErr->writeln("Activities for the environment <info>" . $environment->id . "</info>"); } elseif (!$environmentSpecific) { $this->stdErr->writeln("Activities for the project <info>" . $project->id . "</info>"); } } $table->render($rows, $headers); return 0; }
protected function execute(InputInterface $input, OutputInterface $output) { $this->validateInput($input); if ($name = $input->getArgument('name')) { $variable = $this->getSelectedEnvironment()->getVariable($name); if (!$variable) { $this->stdErr->writeln("Variable not found: <error>{$name}</error>"); return 1; } if ($input->getOption('pipe')) { $output->writeln($variable->value); } else { $output->writeln(sprintf('<info>%s</info>: %s', $variable->name, $variable->value)); } return 0; } $results = $this->getSelectedEnvironment()->getVariables(); if (!$results) { $this->stdErr->writeln('No variables found'); return 1; } if ($input->getOption('pipe')) { throw new \InvalidArgumentException('Specify a variable name to use --pipe'); } $table = new Table($input, $output); $header = ['ID', 'Value', 'Inherited', 'JSON']; $rows = []; foreach ($results as $variable) { $value = $variable->value; if (!$table->formatIsMachineReadable()) { // Truncate long values. if (strlen($value) > 60) { $value = substr($value, 0, 57) . '...'; } // Wrap long values. $value = wordwrap($value, 30, "\n", true); } $rows[] = [$variable->id, $value, $variable->inherited ? 'Yes' : 'No', $variable->is_json ? 'Yes' : 'No']; } $table->render($rows, $header); return 0; }
protected function execute(InputInterface $input, OutputInterface $output) { $this->validateInput($input); $integrations = $this->getSelectedProject()->getIntegrations(); if (!$integrations) { $this->stdErr->writeln('No integrations found'); return 1; } $table = new Table($input, $output); $header = ['ID', 'Type', 'Summary']; $rows = []; foreach ($integrations as $integration) { $rows[] = [new AdaptiveTableCell($integration->id, ['wrap' => false]), $integration->type, $this->getIntegrationSummary($integration)]; } $table->render($rows, $header); $this->stdErr->writeln(''); $this->stdErr->writeln('View integration details with: <info>' . self::$config->get('application.executable') . ' integration:get [id]</info>'); $this->stdErr->writeln(''); $this->stdErr->writeln('Add a new integration with: <info>' . self::$config->get('application.executable') . ' integration:add</info>'); $this->stdErr->writeln('Delete an integration with: <info>' . self::$config->get('application.executable') . ' integration:delete [id]</info>'); return 0; }
protected function execute(InputInterface $input, OutputInterface $output) { $this->validateInput($input); $project = $this->getSelectedProject(); $rows = []; $i = 0; $table = new Table($input, $output); foreach ($project->getUsers() as $user) { $account = $this->getAccount($user); $role = $user['role']; $weight = $i++; if ($project->owner === $user->id) { $weight = -1; if (!$table->formatIsMachineReadable()) { $role .= ' (owner)'; } } $rows[$weight] = [$account['email'], $account['display_name'], $role]; } ksort($rows); $table->render(array_values($rows), ['Email address', 'Name', 'Project role']); return 0; }
/** * {@inheritdoc} */ protected function execute(InputInterface $input, OutputInterface $output) { $this->validateInput($input); $refresh = $input->hasOption('refresh') && $input->getOption('refresh'); $environments = $this->api()->getEnvironments($this->getSelectedProject(), $refresh ? true : null); if ($input->getOption('no-inactive')) { $environments = array_filter($environments, function ($environment) { return $environment->status !== 'inactive'; }); } if ($input->getOption('sort')) { $this->api()->sortResources($environments, $input->getOption('sort')); } if ($input->getOption('reverse')) { $environments = array_reverse($environments, true); } if ($input->getOption('pipe')) { $output->writeln(array_keys($environments)); return; } $project = $this->getSelectedProject(); $this->currentEnvironment = $this->getCurrentEnvironment($project); if (($currentProject = $this->getCurrentProject()) && $currentProject == $project) { $projectConfig = $this->localProject->getProjectConfig($this->getProjectRoot()); if (isset($projectConfig['mapping'])) { $this->mapping = $projectConfig['mapping']; } } $tree = $this->buildEnvironmentTree($environments); // Add orphaned environments (those whose parents do not exist) and // their children to the tree. foreach ($environments as $id => $environment) { if (!isset($tree[$id]) && !empty($environment->parent) && !isset($environments[$environment->parent])) { $tree[$id] = $environment; $this->children[$id] = $this->buildEnvironmentTree($environments, $id); } } // To make the display nicer, we move all the children of master // to the top level. if (isset($this->children['master'])) { $tree += $this->children['master']; $this->children['master'] = []; } $headers = ['ID', 'Name', 'Status']; $table = new Table($input, $output); if ($table->formatIsMachineReadable()) { $table->render($this->buildEnvironmentRows($tree, false, false), $headers); return; } $this->stdErr->writeln("Your environments are: "); $table->render($this->buildEnvironmentRows($tree), $headers); if (!$this->currentEnvironment) { return; } $this->stdErr->writeln("<info>*</info> - Indicates the current environment\n"); $currentEnvironment = $this->currentEnvironment; $this->stdErr->writeln("Check out a different environment by running <info>" . self::$config->get('application.executable') . " checkout [id]</info>"); if ($currentEnvironment->operationAvailable('branch')) { $this->stdErr->writeln("Branch a new environment by running <info>" . self::$config->get('application.executable') . " environment:branch [new-name]</info>"); } if ($currentEnvironment->operationAvailable('activate')) { $this->stdErr->writeln("Activate the current environment by running <info>" . self::$config->get('application.executable') . " environment:activate</info>"); } if ($currentEnvironment->operationAvailable('delete')) { $this->stdErr->writeln("Delete the current environment by running <info>" . self::$config->get('application.executable') . " environment:delete</info>"); } if ($currentEnvironment->operationAvailable('backup')) { $this->stdErr->writeln("Make a snapshot of the current environment by running <info>" . self::$config->get('application.executable') . " snapshot:create</info>"); } if ($currentEnvironment->operationAvailable('merge')) { $this->stdErr->writeln("Merge the current environment by running <info>" . self::$config->get('application.executable') . " environment:merge</info>"); } if ($currentEnvironment->operationAvailable('synchronize')) { $this->stdErr->writeln("Sync the current environment by running <info>" . self::$config->get('application.executable') . " environment:synchronize</info>"); } }
/** * {@inheritdoc} */ protected function execute(InputInterface $input, OutputInterface $output) { $this->validateInput($input); $refresh = $input->hasOption('refresh') && $input->getOption('refresh'); $environments = $this->getEnvironments(null, $refresh); if ($input->getOption('no-inactive')) { $environments = array_filter($environments, function ($environment) { return $environment->status !== 'inactive'; }); } if ($input->getOption('pipe')) { $output->writeln(array_keys($environments)); return; } $project = $this->getSelectedProject(); $this->currentEnvironment = $this->getCurrentEnvironment($project); if (($currentProject = $this->getCurrentProject()) && $currentProject == $project) { $config = $this->getProjectConfig($this->getProjectRoot()); if (isset($config['mapping'])) { $this->mapping = $config['mapping']; } } $tree = $this->buildEnvironmentTree($environments); // To make the display nicer, we move all the children of master // to the top level. if (isset($tree['master'])) { $tree += $this->children['master']; $this->children['master'] = []; } $headers = ['ID', 'Name', 'Status']; $table = new Table($input, $output); if ($table->formatIsMachineReadable()) { $table->render($this->buildEnvironmentRows($tree, false, false), $headers); return; } $this->stdErr->writeln("Your environments are: "); $table->render($this->buildEnvironmentRows($tree), $headers); if (!$this->currentEnvironment) { return; } $this->stdErr->writeln("<info>*</info> - Indicates the current environment\n"); $currentEnvironment = $this->currentEnvironment; $this->stdErr->writeln("Check out a different environment by running <info>platform checkout [id]</info>"); if ($currentEnvironment->operationAvailable('branch')) { $this->stdErr->writeln("Branch a new environment by running <info>platform environment:branch [new-name]</info>"); } if ($currentEnvironment->operationAvailable('activate')) { $this->stdErr->writeln("Activate the current environment by running <info>platform environment:activate</info>"); } if ($currentEnvironment->operationAvailable('delete')) { $this->stdErr->writeln("Delete the current environment by running <info>platform environment:delete</info>"); } if ($currentEnvironment->operationAvailable('backup')) { $this->stdErr->writeln("Make a snapshot of the current environment by running <info>platform snapshot:create</info>"); } if ($currentEnvironment->operationAvailable('merge')) { $this->stdErr->writeln("Merge the current environment by running <info>platform environment:merge</info>"); } if ($currentEnvironment->operationAvailable('synchronize')) { $this->stdErr->writeln("Sync the current environment by running <info>platform environment:synchronize</info>"); } }
protected function execute(InputInterface $input, OutputInterface $output) { $refresh = $input->hasOption('refresh') && $input->getOption('refresh'); // Fetch the list of projects. $projects = $this->api()->getProjects($refresh ? true : null); // Filter the list of projects. $filters = []; if ($host = $input->getOption('host')) { $filters['host'] = $host; } if ($title = $input->getOption('title')) { $filters['title'] = $title; } if ($input->getOption('my')) { $filters['my'] = true; } $this->filterProjects($projects, $filters); // Sort the list of projects. if ($input->getOption('sort')) { $this->api()->sortResources($projects, $input->getOption('sort')); } if ($input->getOption('reverse')) { $projects = array_reverse($projects, true); } // Display a simple list of project IDs, if --pipe is used. if ($input->getOption('pipe')) { $output->writeln(array_keys($projects)); return 0; } $table = new Table($input, $output); $machineReadable = $table->formatIsMachineReadable(); $rows = []; foreach ($projects as $project) { $title = $project->title ?: '[Untitled Project]'; // Add a warning next to the title if the project is suspended. if (!$machineReadable && $project->isSuspended()) { $title = sprintf('<fg=white;bg=black>%s</> <fg=yellow;bg=black>(suspended)</>', $title); } $rows[] = [new AdaptiveTableCell($project->id, ['wrap' => false]), $title, $project->getLink('#ui')]; } $header = ['ID', 'Title', 'URL']; // Display a simple table (and no messages) if the --format is // machine-readable (e.g. csv or tsv). if ($machineReadable) { $table->render($rows, $header); return 0; } // Display a message if no projects are found. if (empty($projects)) { if (!empty($filters)) { $filtersUsed = '<comment>--' . implode('</comment>, <comment>--', array_keys($filters)) . '</comment>'; $this->stdErr->writeln('No projects found (filters in use: ' . $filtersUsed . ').'); } else { $this->stdErr->writeln('You do not have any ' . self::$config->get('service.name') . ' projects yet.'); } return 0; } // Display the projects. if (empty($filters)) { $this->stdErr->writeln('Your projects are: '); } $table->render($rows, $header); $commandName = self::$config->get('application.executable'); $this->stdErr->writeln(['', 'Get a project by running: <info>' . $commandName . ' get [id]</info>', "List a project's environments by running: <info>" . $commandName . ' environments -p [id]</info>']); return 0; }