Passed
Push — master ( 0999f0...13fe7b )
by Morris
11:47
created

Remove::execute()   B

Complexity

Conditions 7
Paths 10

Size

Total Lines 52
Code Lines 30

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 7
eloc 30
nc 10
nop 2
dl 0
loc 52
rs 8.5066
c 0
b 0
f 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * @copyright Copyright (c) 2018, Patrik Kernstock <[email protected]>
4
 *
5
 * @author Patrik Kernstock <[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
23
namespace OC\Core\Command\App;
24
25
use Throwable;
26
use OC\Installer;
27
use OCP\App\IAppManager;
28
use OCP\ILogger;
29
use Stecman\Component\Symfony\Console\BashCompletion\Completion\CompletionAwareInterface;
30
use Stecman\Component\Symfony\Console\BashCompletion\CompletionContext;
31
use Symfony\Component\Console\Command\Command;
32
use Symfony\Component\Console\Input\InputArgument;
33
use Symfony\Component\Console\Input\InputOption;
34
use Symfony\Component\Console\Input\InputInterface;
35
use Symfony\Component\Console\Output\OutputInterface;
36
37
class Remove extends Command implements CompletionAwareInterface {
38
39
	/** @var IAppManager */
40
	protected $manager;
41
	/** @var Installer */
42
	private $installer;
43
	/** @var ILogger */
44
	private $logger;
45
46
	/**
47
	 * @param IAppManager $manager
48
	 * @param Installer $installer
49
	 * @param ILogger $logger
50
	 */
51
	public function __construct(IAppManager $manager, Installer $installer, ILogger $logger) {
52
		parent::__construct();
53
		$this->manager = $manager;
54
		$this->installer = $installer;
55
		$this->logger = $logger;
56
	}
57
58
	protected function configure() {
59
		$this
60
			->setName('app:remove')
61
			->setDescription('remove an app')
62
			->addArgument(
63
				'app-id',
64
				InputArgument::REQUIRED,
65
				'remove the specified app'
66
			)
67
			->addOption(
68
				'keep-data',
69
				null,
70
				InputOption::VALUE_NONE,
71
				'keep app data and do not remove them'
72
			);
73
	}
74
75
	protected function execute(InputInterface $input, OutputInterface $output) {
76
		$appId = $input->getArgument('app-id');
77
78
		// Check if the app is installed
79
		if (!\OC_App::getAppPath($appId)) {
0 ignored issues
show
Bug introduced by
It seems like $appId can also be of type null and string[]; however, parameter $appId of OC_App::getAppPath() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

79
		if (!\OC_App::getAppPath(/** @scrutinizer ignore-type */ $appId)) {
Loading history...
80
			$output->writeln($appId . ' is not installed');
0 ignored issues
show
Bug introduced by
Are you sure $appId of type null|string|string[] can be used in concatenation? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

80
			$output->writeln(/** @scrutinizer ignore-type */ $appId . ' is not installed');
Loading history...
81
			return 1;
82
		}
83
84
		// Removing shipped apps is not possible, therefore we pre-check that
85
		// before trying to remove it
86
		if ($this->manager->isShipped($appId)) {
0 ignored issues
show
Bug introduced by
It seems like $appId can also be of type string[]; however, parameter $appId of OCP\App\IAppManager::isShipped() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

86
		if ($this->manager->isShipped(/** @scrutinizer ignore-type */ $appId)) {
Loading history...
87
			$output->writeln($appId . ' could not be removed as it is a shipped app');
88
			return 1;
89
		}
90
91
		// If we want to keep the data of the app, we simply don't disable it here.
92
		// App uninstall tasks are being executed when disabled. More info: PR #11627.
93
		if (!$input->getOption('keep-data')) {
94
			try {
95
				$this->manager->disableApp($appId);
0 ignored issues
show
Bug introduced by
It seems like $appId can also be of type string[]; however, parameter $appId of OCP\App\IAppManager::disableApp() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

95
				$this->manager->disableApp(/** @scrutinizer ignore-type */ $appId);
Loading history...
96
				$output->writeln($appId . ' disabled');
97
			} catch(Throwable $e) {
98
				$output->writeln('<error>Error: ' . $e->getMessage() . '</error>');
99
				$this->logger->logException($e, [
100
					'app' => 'CLI',
101
					'level' => ILogger::ERROR
102
				]);
103
				return 1;
104
			}
105
		}
106
107
		// Let's try to remove the app...
108
		try {
109
			$result = $this->installer->removeApp($appId);
0 ignored issues
show
Bug introduced by
It seems like $appId can also be of type string[]; however, parameter $appId of OC\Installer::removeApp() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

109
			$result = $this->installer->removeApp(/** @scrutinizer ignore-type */ $appId);
Loading history...
110
		} catch(Throwable $e) {
111
			$output->writeln('<error>Error: ' . $e->getMessage() . '</error>');
112
			$this->logger->logException($e, [
113
				'app' => 'CLI',
114
				'level' => ILogger::ERROR
115
			]);
116
			return 1;
117
		}
118
119
		if($result === false) {
120
			$output->writeln($appId . ' could not be removed');
121
			return 1;
122
		}
123
124
		$output->writeln($appId . ' removed');
125
126
		return 0;
127
	}
128
129
	/**
130
	 * @param string $optionName
131
	 * @param CompletionContext $context
132
	 * @return string[]
133
	 */
134
	public function completeOptionValues($optionName, CompletionContext $context) {
135
		return [];
136
	}
137
138
	/**
139
	 * @param string $argumentName
140
	 * @param CompletionContext $context
141
	 * @return string[]
142
	 */
143
	public function completeArgumentValues($argumentName, CompletionContext $context) {
144
		if ($argumentName === 'app-id') {
145
			return \OC_App::getAllApps();
146
		}
147
		return [];
148
	}
149
}
150