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: /**
28: * Contains tasks to load and instantiate
29: *
30: * @var array
31: */
32: public $tasks = ['Command'];
33:
34: /**
35: * Echo no header by overriding the startup method
36: *
37: * @return void
38: */
39: public function startup()
40: {
41: }
42:
43: /**
44: * Not called by the autocomplete shell - this is for curious users
45: *
46: * @return int|bool Returns the number of bytes returned from writing to stdout.
47: */
48: public function main()
49: {
50: return $this->out($this->getOptionParser()->help());
51: }
52:
53: /**
54: * list commands
55: *
56: * @return int|bool|null Returns the number of bytes returned from writing to stdout.
57: */
58: public function commands()
59: {
60: $options = $this->Command->commands();
61:
62: return $this->_output($options);
63: }
64:
65: /**
66: * list options for the named command
67: *
68: * @return int|bool|null Returns the number of bytes returned from writing to stdout.
69: */
70: public function options()
71: {
72: $commandName = $subCommandName = '';
73: if (!empty($this->args[0])) {
74: $commandName = $this->args[0];
75: }
76: if (!empty($this->args[1])) {
77: $subCommandName = $this->args[1];
78: }
79: $options = $this->Command->options($commandName, $subCommandName);
80:
81: return $this->_output($options);
82: }
83:
84: /**
85: * list subcommands for the named command
86: *
87: * @return int|bool|null Returns the number of bytes returned from writing to stdout.
88: * @throws \ReflectionException
89: */
90: public function subcommands()
91: {
92: if (!$this->args) {
93: return $this->_output();
94: }
95:
96: $options = $this->Command->subCommands($this->args[0]);
97:
98: return $this->_output($options);
99: }
100:
101: /**
102: * Guess autocomplete from the whole argument string
103: *
104: * @return int|bool|null Returns the number of bytes returned from writing to stdout.
105: */
106: public function fuzzy()
107: {
108: return $this->_output();
109: }
110:
111: /**
112: * Gets the option parser instance and configures it.
113: *
114: * @return \Cake\Console\ConsoleOptionParser
115: */
116: public function getOptionParser()
117: {
118: $parser = parent::getOptionParser();
119:
120: $parser->setDescription(
121: 'Used by shells like bash to autocomplete command name, options and arguments'
122: )->addSubcommand('commands', [
123: 'help' => 'Output a list of available commands',
124: 'parser' => [
125: 'description' => 'List all available',
126: ]
127: ])->addSubcommand('subcommands', [
128: 'help' => 'Output a list of available subcommands',
129: 'parser' => [
130: 'description' => 'List subcommands for a command',
131: 'arguments' => [
132: 'command' => [
133: 'help' => 'The command name',
134: 'required' => false,
135: ]
136: ]
137: ]
138: ])->addSubcommand('options', [
139: 'help' => 'Output a list of available options',
140: 'parser' => [
141: 'description' => 'List options',
142: 'arguments' => [
143: 'command' => [
144: 'help' => 'The command name',
145: 'required' => false,
146: ],
147: 'subcommand' => [
148: 'help' => 'The subcommand name',
149: 'required' => false,
150: ]
151: ]
152: ]
153: ])->addSubcommand('fuzzy', [
154: 'help' => 'Guess autocomplete'
155: ])->setEpilog([
156: 'This command is not intended to be called manually',
157: ]);
158:
159: return $parser;
160: }
161:
162: /**
163: * Emit results as a string, space delimited
164: *
165: * @param array $options The options to output
166: * @return int|bool|null Returns the number of bytes returned from writing to stdout.
167: */
168: protected function _output($options = [])
169: {
170: if ($options) {
171: return $this->out(implode($options, ' '));
172: }
173: }
174: }
175: