Passed
Push — master ( 0fc74f...0b9439 )
by Timo
02:27
created

ImplementCommand::retrieveCodeGenerator()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 0
1
<?php
2
3
/**
4
 * This file is part of the phpspec-behavior package.
5
 * (c) 2017 Timo Michna <timomichna/yahoo.de>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
11
namespace Tidal\PhpSpec\BehaviorExtension\Console\Command;
12
13
use Symfony\Component\Console\Output\OutputInterface;
14
use Symfony\Component\Console\Input\{
15
    InputArgument,
16
    InputOption,
17
    InputInterface
18
};
19
20
use Tidal\PhpSpec\ConsoleExtension\Command\GenericInlineConfigCommand;
21
use Tidal\PhpSpec\ConsoleExtension\Contract\Command\InlineConfigCommandInterface;
22
23
use Tidal\PhpSpec\BehaviorExtension\Behavior\Container\HasContainerTrait;
24
use Tidal\PhpSpec\BehaviorExtension\Behavior\Console\Command\{
25
    UsesInterfaceTrait,
26
    UsesBehaviorTrait
27
};
28
29
use PhpSpec\Locator\ResourceManager;
30
use PhpSpec\CodeGenerator\GeneratorManager;
31
32
/**
33
 * class Tidal\PhpSpec\Behavior\Command\ImplementCommand
34
 */
35
class ImplementCommand extends GenericInlineConfigCommand implements InlineConfigCommandInterface
36
{
37
    use
38
        UsesInterfaceTrait,
39
        UsesBehaviorTrait,
40
        HasContainerTrait;
41
42
    /**
43
     * CONFIG
44
     */
45
    public const NAME = 'behavior:implement';
46
    public const DESCRIPTION = 'Creates a Trait from a given Interface';
47
    public const HIDDEN = false;
48
    public const USAGES = [ '@todo' ];
49
    public const HELP = <<<EOF
50
The <info>%command.name%</info> command creates an trait from a given interface:
51
  <info>php %command.full_name% ClassName MethodName</info>
52
Will generate an example in the ClassNameSpec.
53
EOF;
54
55
    public const ARGUMENTS = [
56
        self::INTERFACE_INPUT => [
57
            self::MODE_KEY => InputArgument::REQUIRED,
58
            self::DESCRIPTION_KEY => 'Interface to create behavior for'
59
        ],
60
        self::TRAIT_INPUT => [
61
            self::MODE_KEY => InputArgument::OPTIONAL,
62
            self::DESCRIPTION_KEY => 'Custom trait class name'
63
        ]
64
    ];
65
66
    public const OPTIONS = [
67
        self::FORCE_KEY => [
68
            self::MODE_KEY => InputOption::VALUE_NONE,
69
            self::DESCRIPTION_KEY => 'Force creation of Trait without asking for confirmation'
70
        ]
71
    ];
72
73
    protected const INTERFACE_CONFIRMATION_QUESTION = 'Interface %s? does not exist. Do you want to generate it?';
74
    protected const TRAIT_CONFIRMATION_QUESTION = 'Do you want to generate a Trait for Interface %s?';
75
76
    protected const INTERFACE_INPUT = 'interface';
77
    protected const TRAIT_INPUT = 'trait';
78
79
    protected const MODE_KEY = 'mode';
80
    protected const DESCRIPTION_KEY = 'description';
81
    protected const FORCE_KEY = 'force';
82
    protected const INTERFACE_KEY = 'interface';
83
84
    protected const RESOURCE_MANAGER_ID = 'locator.resource_manager';
85
    protected const GENERATOR_MANAGER_ID = 'code_generator';
86
87
    /**
88
     * @param \Symfony\Component\Console\Input\InputInterface $input
89
     * @param OutputInterface $output
90
     *
91
     * @return int|null
92
     */
93
    protected function execute(InputInterface $input, OutputInterface $output)
94
    {
95
        if (method_exists($this->getContainer(), 'configure')) {
96
            $this->getContainer()->configure();
97
        }
98
99
        $interfaceName = $input->getArgument(self::INTERFACE_INPUT);
100
101
        if (!$this->validateInterface($interfaceName) && $this->confirmInterfaceGeneration($interfaceName)) {
102
            $this->retrieveGeneratorManager()->generate(
103
                $this->retrieveResourceManager()->createResource($interfaceName),
104
                self::INTERFACE_KEY
105
            );
106
        }
107
108
        $traitName = $input->getArgument(self::TRAIT_INPUT);
109
110
        if (!$this->validateTrait($traitName) && !$input->getOption(self::FORCE_KEY)) {
111
            return 0;
112
        }
113
114
        if (!$this->confirmTraitGeneration($interfaceName, $traitName)) {
115
            return 0;
116
        }
117
118
        return 0;
119
    }
120
121
    /**
122
     * @param string $interfaceName
123
     * @return bool
124
     */
125
    private function confirmInterfaceGeneration(string $interfaceName)
126
    {
127
        return $this->getWriter()->confirm(
128
            self::INTERFACE_CONFIRMATION_QUESTION,
129
            [
130
                $interfaceName
131
            ]
132
        );
133
    }
134
135
    /**
136
     * @param string $interfaceName
137
     * @param null|string $traitName
138
     * @return bool
139
     */
140
    private function confirmTraitGeneration(string $interfaceName, ? string $traitName)
141
    {
142
        return $this->getWriter()->confirm(
143
            self::TRAIT_CONFIRMATION_QUESTION,
144
            [
145
                $interfaceName,
146
                $traitName
147
            ]
148
        );
149
    }
150
151
    /**
152
     * @return object|ResourceManager
153
     */
154
    protected function retrieveResourceManager()
155
    {
156
        return $this->getContainer()->get(self::RESOURCE_MANAGER_ID);
157
    }
158
159
    /**
160
     * @return object|GeneratorManager
161
     */
162
    protected function retrieveGeneratorManager()
163
    {
164
        return $this->getContainer()->get(self::GENERATOR_MANAGER_ID);
165
    }
166
}
167
168