Skip to content

Commit a53a691

Browse files
committed
occ: Add command app:rollout
Signed-off-by: Felix Stupp <[email protected]>
1 parent 051518c commit a53a691

2 files changed

Lines changed: 140 additions & 0 deletions

File tree

core/Command/App/Rollout.php

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
<?php
2+
/**
3+
* @copyright Copyright (c) 2021, Felix Stupp <[email protected]>
4+
*
5+
* @author Felix Stupp <[email protected]>
6+
*
7+
* @license AGPL-3.0
8+
*
9+
* This code is free software: you can redistribute it and/or modify
10+
* it under the terms of the GNU Affero General Public License, version 3,
11+
* as published by the Free Software Foundation.
12+
*
13+
* This program is distributed in the hope that it will be useful,
14+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
15+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16+
* GNU Affero General Public License for more details.
17+
*
18+
* You should have received a copy of the GNU Affero General Public License, version 3,
19+
* along with this program. If not, see <http://www.gnu.org/licenses/>
20+
*
21+
*/
22+
namespace OC\Core\Command\App;
23+
24+
use OC\Installer;
25+
use OCP\App\AppPathNotFoundException;
26+
use OCP\App\IAppManager;
27+
use Symfony\Component\Console\Command\Command;
28+
use Symfony\Component\Console\Input\InputArgument;
29+
use Symfony\Component\Console\Input\InputInterface;
30+
use Symfony\Component\Console\Input\InputOption;
31+
use Symfony\Component\Console\Output\OutputInterface;
32+
33+
class Rollout extends Command {
34+
35+
/** @var IAppManager */
36+
protected $appManager;
37+
38+
/** @var int */
39+
protected $exitCode = 0;
40+
41+
/**
42+
* @param IAppManager $appManager
43+
*/
44+
public function __construct(IAppManager $appManager) {
45+
parent::__construct();
46+
$this->appManager = $appManager;
47+
}
48+
49+
protected function configure(): void {
50+
$this
51+
->setName('app:rollout')
52+
->setDescription('rollout list of apps which should be either installed and enabled or disabled or removed')
53+
->addArgument(
54+
'app-ids',
55+
InputArgument::REQUIRED | InputArgument::IS_ARRAY,
56+
'list of apps; names with suffix "+" or no known suffix will be installed/enabled, while names with suffix "-" will be disabled, if required'
57+
)
58+
->addOption(
59+
'force',
60+
'f',
61+
InputOption::VALUE_NONE,
62+
'install apps regardless of the Nextcloud version requirement'
63+
)
64+
;
65+
}
66+
67+
protected function execute(InputInterface $input, OutputInterface $output): int {
68+
$appIds = $input->getArgument('app-id');
69+
$forceEnable = (bool) $input->getOption('force');
70+
71+
foreach ($appIds as $appIdMarked) {
72+
$appId = substr($appIdMarked, 0, -1);
73+
$marker = substr($appIdMarked, 1);
74+
if ($marker == "+") {
75+
$this->enableApp($appId, $forceEnable, $output);
76+
} elseif ($marker == "-") {
77+
$this->disableApp($appId, $output);
78+
} else {
79+
// ignore marker as no known found
80+
$this->enableApp($appIdMarked, $forceEnable, $output);
81+
}
82+
}
83+
84+
return $this->exitCode;
85+
}
86+
87+
/**
88+
* @param string $appId
89+
* @param OutputInterface $output
90+
*/
91+
private function disableApp(string $appId, OutputInterface $output) {
92+
if ($this->appManager->isInstalled($appId) === false) {
93+
$output->writeln('No such app enabled: ' . $appId);
94+
return;
95+
}
96+
97+
try {
98+
$this->appManager->disableApp($appId);
99+
$appVersion = $this->appManager->getAppVersion($appId);
100+
$output->writeln($appId . ' ' . $appVersion . ' disabled');
101+
} catch (\Exception $e) {
102+
$output->writeln($e->getMessage());
103+
$this->exitCode = 1;
104+
}
105+
}
106+
107+
/**
108+
* @param string $appId
109+
* @param bool $forceEnable
110+
* @param OutputInterface $output
111+
*/
112+
private function enableApp(string $appId, bool $forceEnable, OutputInterface $output): void {
113+
if ($this->appManager->isInstalled($appId)) {
114+
$output->writeln($appId . ' already enabled');
115+
return;
116+
}
117+
118+
try {
119+
/** @var Installer $installer */
120+
$installer = \OC::$server->query(Installer::class);
121+
122+
if (false === $installer->isDownloaded($appId)) {
123+
$installer->downloadApp($appId);
124+
}
125+
126+
$installer->installApp($appId, $forceEnable);
127+
$appVersion = $this->appManager->getAppVersion($appId);
128+
129+
$this->appManager->enableApp($appId, $forceEnable);
130+
$output->writeln($appId . ' ' . $appVersion . ' enabled');
131+
} catch (AppPathNotFoundException $e) {
132+
$output->writeln($appId . ' not found');
133+
$this->exitCode = 1;
134+
} catch (\Exception $e) {
135+
$output->writeln($e->getMessage());
136+
$this->exitCode = 1;
137+
}
138+
}
139+
}

core/register_command.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@
7878
$application->add(new OC\Core\Command\App\GetPath());
7979
$application->add(new OC\Core\Command\App\ListApps(\OC::$server->getAppManager()));
8080
$application->add(new OC\Core\Command\App\Remove(\OC::$server->getAppManager(), \OC::$server->query(\OC\Installer::class), \OC::$server->get(LoggerInterface::class)));
81+
$application->add(new OC\Core\Command\App\Rollout(\OC::$server->getAppManager()));
8182
$application->add(\OC::$server->query(\OC\Core\Command\App\Update::class));
8283

8384
$application->add(\OC::$server->query(\OC\Core\Command\TwoFactorAuth\Cleanup::class));

0 commit comments

Comments
 (0)