InitCommand::generatePackage()   F
last analyzed

Complexity

Conditions 20
Paths 2881

Size

Total Lines 80
Code Lines 41

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 420

Importance

Changes 1
Bugs 0 Features 0
Metric Value
dl 0
loc 80
rs 2.1875
c 1
b 0
f 0
ccs 0
cts 62
cp 0
cc 20
eloc 41
nc 2881
nop 0
crap 420

How to fix   Long Method    Complexity   

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
namespace keeko\tools\command;
3
4
use keeko\framework\schema\AuthorSchema;
5
use keeko\tools\helpers\InitCommandHelperTrait;
6
use keeko\tools\services\IOService;
7
use keeko\tools\ui\InitUI;
8
use Symfony\Component\Console\Input\InputInterface;
9
use Symfony\Component\Console\Input\InputOption;
10
use Symfony\Component\Console\Output\OutputInterface;
11
12
class InitCommand extends AbstractKeekoCommand {
13
14
	use InitCommandHelperTrait;
15
16
	protected function configure() {
17
		$this
18
			->setName('init')
19
			->setDescription('Initializes composer.json with keeko related values')
20
			->addOption(
21
				'name',
22
				'',
23
				InputOption::VALUE_REQUIRED,
24
				'Name of the package'
25 20
			)
26 20
			->addOption(
27 20
				'description',
28 20
				'd',
29 20
				InputOption::VALUE_OPTIONAL,
30 20
				'Description of the package'
31 20
			)
32 20
			->addOption(
33
				'author',
34 20
				'',
35 20
				InputOption::VALUE_OPTIONAL,
36 20
				'Author name of the package'
37 20
			)
38 20
			->addOption(
39
				'type',
40 20
				't',
41 20
				InputOption::VALUE_REQUIRED,
42 20
				'The type of the package (app|module)'
43 20
			)
44 20
			->addOption(
45
				'namespace',
46 20
				'ns',
47 20
				InputOption::VALUE_OPTIONAL,
48 20
				'The package\'s namespace for the src/ folder (If ommited, the package name is used)'
49 20
			)
50 20
			->addOption(
51
				'license',
52 20
				'l',
53 20
				InputOption::VALUE_OPTIONAL,
54 20
				'License of the package'
55 20
			)
56 20
			->addOption(
57
				'title',
58 20
				'',
59 20
				InputOption::VALUE_OPTIONAL,
60 20
				'The package\'s title (If ommited, second part of the package name is used)',
61 20
				null
62 20
			)
63
			->addOption(
64 20
				'classname',
65 20
				'c',
66 20
				InputOption::VALUE_OPTIONAL,
67 20
				'The main class name (If ommited, there is a default handler)',
68 20
				null
69 20
			)
70
			->addOption(
71 20
				'force',
72 20
				'f',
73 20
				InputOption::VALUE_NONE,
74 20
				'Allows to overwrite existing values'
75 20
			)
76 20
		;
77
78 20
		$this->configureGlobalOptions();
79
	}
80
81
	protected function initialize(InputInterface $input, OutputInterface $output) {
82
		parent::initialize($input, $output);
83
	}
84
85 20
	/**
86 20
	 * @return PackageSchema
87 20
	 */
88 20
	protected function getPackage() {
89
		return $this->package;
90 20
	}
91 20
92 20
	/**
93 20
	 * @return IOService
94 20
	 */
95
	protected function getIO() {
96 20
		return $this->io;
97
	}
98
99 20
	protected function interact(InputInterface $input, OutputInterface $output) {
100 20
		$ui = new InitUI($this);
101
		$ui->show();
102 3
	}
103 3
104 3
	protected function execute(InputInterface $input, OutputInterface $output) {
105
		$this->generatePackage();
106
		$this->generateCode();
107
	}
108
109
	private function generatePackage() {
110
		$input = $this->io->getInput();
111
		$force = $input->getOption('force');
112
113
		// name
114
		$localName = $this->package->getFullName();
115
		if (empty($localName) && $input->getOption('name') === null) {
116
			throw new \RuntimeException('No name for the package given');
117
		}
118
119
		if (($force || empty($localName)) && ($name = $input->getOption('name')) !== null) {
120
			$this->validateName($name);
121
			$this->package->setFullName($name);
122
		}
123
124
		// description
125
		if (($desc = $input->getOption('description')) !== null) {
126
			$this->package->setDescription($desc);
127
		}
128
129
		// type
130
		if (($type = $input->getOption('type')) !== null) {
131
			if (in_array($type, ['app', 'module'])) {
132
				$this->package->setType('keeko-' . $type);
133
			}
134
		}
135
136
		// license
137
		if (($license = $input->getOption('license')) !== null) {
138
			$this->package->setLicense($license);
139
		}
140
141
		// author
142
		if (($author = $input->getOption('author')) !== null
143
				&& ($this->package->getAuthors()->isEmpty() || $force)) {
144
			list($name, $email) = sscanf($author, '%s <%s>');
145
146
			$author = new AuthorSchema();
147
			$author->setName($name);
148
149
			if (substr($email, -1) == '>') {
150
				$email = substr($email, 0, -1);
151
			}
152
			$author->setEmail($email);
153
154
			$this->package->getAuthors()->add($author);
155
		}
156
157
		// autoload
158
		if (!$this->hasAutoload()) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->hasAutoload() of type string|null is loosely compared to false; this is ambiguous if the string can be empty. You might want to explicitly use === null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
159
			$namespace = $input->getOption('namespace');
160
			if ($namespace === null) {
161
				$namespace = str_replace('/', '\\', $this->package->getFullName());
162
			}
163
			if (substr($namespace, -2) !== '\\') {
164
				$namespace .= '\\';
165
			}
166
			$this->setAutoload($namespace);
167
		}
168
169
		$this->manageDependencies();
170
171
		// KEEKO
172
		if ($type === null) {
173
			$type = $this->getPackageType();
174
		}
175
176
		// title
177
		$keeko = $this->packageService->getKeeko()->getKeekoPackage($type);
178
		if (($title = $this->getPackageTitle()) !== null) {
179
			$keeko->setTitle($title);
180
		}
181
182
		// class
183
		if (($classname = $this->getPackageClass()) !== null) {
184
			$keeko->setClass($classname);
185
		}
186
187
		$this->packageService->savePackage($this->package);
188
	}
189
190
	private function manageDependencies() {
191
		// add require statements
192
		$require = $this->package->getRequire();
193
194
		if (!$require->has('php')) {
195
			$require->set('php', '>=5.5');
196
		}
197
198
		if (!$require->has('keeko/composer-installer')) {
199
			$require->set('keeko/composer-installer', '*');
200
		}
201
202
		// add require dev statements
203
		$requireDev = $this->package->getRequireDev();
204
		$requireDev->set('keeko/framework', 'dev-master');
205
		$requireDev->set('keeko/core', '@dev');
206
		$requireDev->set('propel/propel', '@alpha');
207
		$requireDev->set('puli/repository', '@beta');
208
		$requireDev->set('puli/composer-plugin', '@beta');
209
		$requireDev->set('puli/twig-extension', '@beta');
210
		$requireDev->set('puli/url-generator', '@beta');
211
		$requireDev->set('puli/discovery', '@beta');
212
	}
213
214
	private function generateCode() {
215
		$type = $this->getPackageType();
216
		$package = $this->package->getKeeko()->getKeekoPackage($type);
217
		$generator = $this->factory->createPackageGenerator($type);
218
		$class = $generator->generate($package);
219
220
		$this->codeService->dumpStruct($class, true);
221
	}
222
}
223