1: <?php
2: /**
3: * CakePHP(tm) : Rapid Development Framework (https://cakephp.org)
4: * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
5: *
6: * Licensed under The MIT License
7: * For full copyright and license information, please see the LICENSE.txt
8: * Redistributions of files must retain the above copyright notice.
9: *
10: * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
11: * @link https://cakephp.org CakePHP Project
12: * @since 2.5.0
13: * @license https://opensource.org/licenses/mit-license.php MIT License
14: */
15: namespace Cake\Shell;
16:
17: use Cake\Console\Shell;
18:
19: /**
20: * Provide command completion shells such as bash.
21: *
22: * @property \Cake\Shell\Task\CommandTask $Command
23: */
24: class CompletionShell extends Shell
25: {
26: /**
27: * Contains tasks to load and instantiate
28: *
29: * @var array
30: */
31: public $tasks = ['Command'];
32:
33: /**
34: * Echo no header by overriding the startup method
35: *
36: * @return void
37: */
38: public function startup()
39: {
40: }
41:
42: /**
43: * Not called by the autocomplete shell - this is for curious users
44: *
45: * @return int|bool Returns the number of bytes returned from writing to stdout.
46: */
47: public function main()
48: {
49: return $this->out($this->getOptionParser()->help());
50: }
51:
52: /**
53: * list commands
54: *
55: * @return int|bool|null Returns the number of bytes returned from writing to stdout.
56: */
57: public function commands()
58: {
59: $options = $this->Command->commands();
60:
61: return $this->_output($options);
62: }
63:
64: /**
65: * list options for the named command
66: *
67: * @return int|bool|null Returns the number of bytes returned from writing to stdout.
68: */
69: public function options()
70: {
71: $commandName = $subCommandName = '';
72: if (!empty($this->args[0])) {
73: $commandName = $this->args[0];
74: }
75: if (!empty($this->args[1])) {
76: $subCommandName = $this->args[1];
77: }
78: $options = $this->Command->options($commandName, $subCommandName);
79:
80: return $this->_output($options);
81: }
82:
83: /**
84: * list subcommands for the named command
85: *
86: * @return int|bool|null Returns the number of bytes returned from writing to stdout.
87: * @throws \ReflectionException
88: */
89: public function subcommands()
90: {
91: if (!$this->args) {
92: return $this->_output();
93: }
94:
95: $options = $this->Command->subCommands($this->args[0]);
96:
97: return $this->_output($options);
98: }
99:
100: /**
101: * Guess autocomplete from the whole argument string
102: *
103: * @return int|bool|null Returns the number of bytes returned from writing to stdout.
104: */
105: public function fuzzy()
106: {
107: return $this->_output();
108: }
109:
110: /**
111: * Gets the option parser instance and configures it.
112: *
113: * @return \Cake\Console\ConsoleOptionParser
114: */
115: public function getOptionParser()
116: {
117: $parser = parent::getOptionParser();
118:
119: $parser->setDescription(
120: 'Used by shells like bash to autocomplete command name, options and arguments'
121: )->addSubcommand('commands', [
122: 'help' => 'Output a list of available commands',
123: 'parser' => [
124: 'description' => 'List all available',
125: ]
126: ])->addSubcommand('subcommands', [
127: 'help' => 'Output a list of available subcommands',
128: 'parser' => [
129: 'description' => 'List subcommands for a command',
130: 'arguments' => [
131: 'command' => [
132: 'help' => 'The command name',
133: 'required' => false,
134: ]
135: ]
136: ]
137: ])->addSubcommand('options', [
138: 'help' => 'Output a list of available options',
139: 'parser' => [
140: 'description' => 'List options',
141: 'arguments' => [
142: 'command' => [
143: 'help' => 'The command name',
144: 'required' => false,
145: ],
146: 'subcommand' => [
147: 'help' => 'The subcommand name',
148: 'required' => false,
149: ]
150: ]
151: ]
152: ])->addSubcommand('fuzzy', [
153: 'help' => 'Guess autocomplete'
154: ])->setEpilog([
155: 'This command is not intended to be called manually',
156: ]);
157:
158: return $parser;
159: }
160:
161: /**
162: * Emit results as a string, space delimited
163: *
164: * @param array $options The options to output
165: * @return int|bool|null Returns the number of bytes returned from writing to stdout.
166: */
167: protected function _output($options = [])
168: {
169: if ($options) {
170: return $this->out(implode(' ', $options));
171: }
172: }
173: }
174: