Issue #1936866 by jonhattan: Drush dl needs to put files in /modules or /themes,...
[project/drush.git] / examples / sandwich.drush.inc
1 <?php
2
3 /**
4 * @file
5 * Example drush command.
6 *
7 * To run this *fun* command, execute `sudo drush --include=./examples mmas`
8 * from within your drush directory.
9 *
10 * See `drush topic docs-commands` for more information about command authoring.
11 *
12 * You can copy this file to any of the following
13 * 1. A .drush folder in your HOME folder.
14 * 2. Anywhere in a folder tree below an active module on your site.
15 * 3. /usr/share/drush/commands (configurable)
16 * 4. In an arbitrary folder specified with the --include option.
17 * 5. Drupal's /drush or /sites/all/drush folders.
18 */
19
20 /**
21 * Implementation of hook_drush_command().
22 *
23 * In this hook, you specify which commands your
24 * drush module makes available, what it does and
25 * description.
26 *
27 * Notice how this structure closely resembles how
28 * you define menu hooks.
29 *
30 * See `drush topic docs-commands` for a list of recognized keys.
31 *
32 * @return
33 * An associative array describing your command(s).
34 */
35 function sandwich_drush_command() {
36 $items = array();
37
38 // The 'make-me-a-sandwich' command
39 $items['make-me-a-sandwich'] = array(
40 'description' => "Makes a delicious sandwich.",
41 'arguments' => array(
42 'filling' => 'The type of the sandwich (turkey, cheese, etc.). Defaults to ascii.',
43 ),
44 'options' => array(
45 'spreads' => array(
46 'description' => 'Comma delimited list of spreads.',
47 'example-value' => 'mayonnaise,mustard',
48 ),
49 ),
50 'examples' => array(
51 'drush mmas turkey --spreads=ketchup,mustard' => 'Make a terrible-tasting sandwich that is lacking in pickles.',
52 ),
53 'aliases' => array('mmas'),
54 'bootstrap' => DRUSH_BOOTSTRAP_DRUSH, // No bootstrap at all.
55 );
56
57 // The 'sandwiches-served' command. Informs how many 'mmas' commands completed.
58 $items['sandwiches-served'] = array(
59 'description' => "Report how many sandwiches we have made.",
60 'examples' => array(
61 'drush sandwiches-served' => 'Show how many sandwiches we have served.',
62 ),
63 'aliases' => array('sws'),
64 // Example output engine data: command returns a single keyed
65 // data item (e.g. array("served" => 1)) that can either be
66 // printed with a label (e.g. "served: 1"), or output raw with
67 // --pipe (e.g. "1").
68 'engines' => array(
69 'outputformat' => array(
70 'default' => 'key-value',
71 'pipe-format' => 'string',
72 'label' => 'Sandwiches Served',
73 'require-engine-capability' => array('format-single'),
74 ),
75 ),
76 'bootstrap' => DRUSH_BOOTSTRAP_DRUSH, // No bootstrap at all.
77 );
78
79 // The 'spreads-status' command. Prints a table about available spreads.
80 $items['spreads-status'] = array(
81 'description' => "Show a table of information about available spreads.",
82 'examples' => array(
83 'drush spreads-status' => 'Show a table of spreads.',
84 ),
85 'aliases' => array('sps'),
86 // Example output engine data: command returns a deep array
87 // that can either be printed in table format or as an
88 // ini file in sections.
89 'engines' => array(
90 'outputformat' => array(
91 'default' => 'table',
92 'pipe-format' => 'ini-sections',
93 // Commands that return deep arrays will usually use
94 // machine-ids for the column data. A 'field-labels'
95 // item maps from the machine-id to a human-readable label.
96 'field-labels' => array(
97 'name' => 'Name',
98 'description' => 'Description',
99 'available' => 'Num',
100 'taste' => 'Taste',
101 ),
102 // In table format, the 'column-widths' item is consulted
103 // to determine the default weights for any named column.
104 'column-widths' => array(
105 'name' => 10,
106 'available' => 3,
107 ),
108 'require-engine-capability' => array('format-table'),
109 ),
110 ),
111 'bootstrap' => DRUSH_BOOTSTRAP_DRUSH, // No bootstrap at all.
112 );
113
114 // Commandfiles may also add topics. These will appear in
115 // the list of topics when `drush topic` is executed.
116 // To view this topic, run `drush --include=/full/path/to/examples topic`
117 $items['sandwich-exposition'] = array(
118 'description' => 'Ruminations on the true meaning and philosophy of sandwiches.',
119 'hidden' => TRUE,
120 'topic' => TRUE,
121 'bootstrap' => DRUSH_BOOTSTRAP_DRUSH,
122 'callback' => 'drush_print_file',
123 'callback arguments' => array(dirname(__FILE__) . '/sandwich-topic.txt'),
124 );
125
126 return $items;
127 }
128
129
130
131 /**
132 * Implementation of hook_drush_help().
133 *
134 * This function is called whenever a drush user calls
135 * 'drush help <name-of-your-command>'. This hook is optional. If a command
136 * does not implement this hook, the command's description is used instead.
137 *
138 * This hook is also used to look up help metadata, such as help
139 * category title and summary. See the comments below for a description.
140 *
141 * @param
142 * A string with the help section (prepend with 'drush:')
143 *
144 * @return
145 * A string with the help text for your command.
146 */
147 function sandwich_drush_help($section) {
148 switch ($section) {
149 case 'drush:make-me-a-sandwich':
150 return dt("This command will make you a delicious sandwich, just how you like it.");
151 // The 'title' meta item is used to name a group of
152 // commands in `drush help`. If a title is not defined,
153 // the default is "All commands in ___", with the
154 // specific name of the commandfile (e.g. sandwich).
155 // Command files with less than four commands will
156 // be placed in the "Other commands" section, _unless_
157 // they define a title. It is therefore preferable
158 // to not define a title unless the file defines a lot
159 // of commands.
160 case 'meta:sandwich:title':
161 return dt("Sandwich commands");
162 // The 'summary' meta item is displayed in `drush help --filter`,
163 // and is used to give a general idea what the commands in this
164 // command file do, and what they have in common.
165 case 'meta:sandwich:summary':
166 return dt("Automates your sandwich-making business workflows.");
167 }
168 }
169
170 /**
171 * Implementation of drush_hook_COMMAND_validate().
172 *
173 * The validate command should exit with
174 * `return drush_set_error(...)` to stop execution of
175 * the command. In practice, calling drush_set_error
176 * OR returning FALSE is sufficient. See drush.api.php
177 * for more details.
178 */
179 function drush_sandwich_make_me_a_sandwich_validate() {
180 if (drush_is_windows()) {
181 // $name = drush_get_username();
182 // TODO: implement check for elevated process using w32api
183 // as sudo is not available for Windows
184 // http://php.net/manual/en/book.w32api.php
185 // http://social.msdn.microsoft.com/Forums/en/clr/thread/0957c58c-b30b-4972-a319-015df11b427d
186 }
187 else {
188 $name = posix_getpwuid(posix_geteuid());
189 if ($name['name'] !== 'root') {
190 return drush_set_error('MAKE_IT_YOUSELF', dt('What? Make your own sandwich.'));
191 }
192 }
193 }
194
195 /**
196 * Example drush command callback. This is where the action takes place.
197 *
198 * The function name should be same as command name but with dashes turned to
199 * underscores and 'drush_commandfile_' prepended, where 'commandfile' is
200 * taken from the file 'commandfile.drush.inc', which in this case is 'sandwich'.
201 * Note also that a simplification step is also done in instances where
202 * the commandfile name is the same as the beginning of the command name,
203 * "drush_example_example_foo" is simplified to just "drush_example_foo".
204 * To also implement a hook that is called before your command, implement
205 * "drush_hook_pre_example_foo". For a list of all available hooks for a
206 * given command, run drush in --debug mode.
207 *
208 * If for some reason you do not want your hook function to be named
209 * after your command, you may define a 'callback' item in your command
210 * object that specifies the exact name of the function that should be
211 * called. However, the specified callback function must still begin
212 * with "drush_commandfile_" (e.g. 'callback' => "drush_example_foo_execute")
213 * if you want that all hook functions are still called (e.g.
214 * drush_example_pre_foo_execute, and so on).
215 *
216 * In this function, all of Drupal's API is (usually) available, including
217 * any functions you have added in your own modules/themes.
218 *
219 * @see drush_invoke()
220 * @see drush.api.php
221 */
222 function drush_sandwich_make_me_a_sandwich($filling = 'ascii') {
223 $str_spreads = '';
224 // Read options with drush_get_option. Note that the options _must_
225 // be documented in the $items structure for this command in the 'command' hook.
226 // See `drush topic docs-commands` for more information.
227 if ($spreads = drush_get_option('spreads')) {
228 $list = implode(' and ', explode(',', $spreads));
229 $str_spreads = ' with just a dash of ' . $list;
230 }
231 $msg = dt('Okay. Enjoy this !filling sandwich!str_spreads.',
232 array('!filling' => $filling, '!str_spreads' => $str_spreads)
233 );
234 drush_print("\n" . $msg . "\n");
235
236 if (drush_get_context('DRUSH_NOCOLOR')) {
237 $filename = dirname(__FILE__) . '/sandwich-nocolor.txt';
238 }
239 else {
240 $filename = dirname(__FILE__) . '/sandwich.txt';
241 }
242 drush_print(file_get_contents($filename));
243 // Find out how many sandwiches have been served, and set
244 // the cached value to one greater.
245 $served = drush_sandwich_sandwiches_served();
246 drush_cache_set(drush_get_cid('sandwiches-served'), $served + 1);
247 }
248
249 /**
250 * Implementation of hook_drush_command() for sandwiches-served command.
251 *
252 * Demonstrates how to return a simple value that is transformed by
253 * the selected formatter to display either with a label (using the
254 * key-value formatter) or as the raw value itself (using the string formatter).
255 */
256 function drush_sandwich_sandwiches_served() {
257 $served = 0;
258 $served_object = drush_cache_get(drush_get_cid('sandwiches-served'));
259 if ($served_object) {
260 $served = $served_object->data;
261 }
262 // In the default format, key-value, this return value
263 // will print " Sandwiches Served : 1". In the default pipe
264 // format, only the array value ("1") is returned.
265 return $served;
266 }
267
268 /**
269 * Implementation of hook_drush_command() for spreads-status command.
270 *
271 * This ficticious command shows how a deep array can be constructed
272 * and used as a command return value that can be output by different
273 * output formatters.
274 */
275 function drush_sandwich_spreads_status() {
276 return array(
277 'ketchup' => array(
278 'name' => 'Ketchup',
279 'description' => 'Some say its a vegetable, but we know its a sweet spread.',
280 'available' => '7',
281 'taste' => 'sweet',
282 ),
283 'mayonnaise' => array(
284 'name' => 'Mayonnaise',
285 'description' => 'A nice dairy-free spead.',
286 'available' => '12',
287 'taste' => 'creamy',
288 ),
289 'mustard' => array(
290 'name' => 'Mustard',
291 'description' => 'Pardon me, but could you please pass that plastic yellow bottle?',
292 'available' => '8',
293 'taste' => 'tangy',
294 ),
295 'pickles' => array(
296 'name' => 'Pickles',
297 'description' => 'A necessary part of any sandwich that does not taste terrible.',
298 'available' => '63',
299 'taste' => 'tasty',
300 ),
301 );
302 }
303
304 /**
305 * Command argument complete callback. Provides argument
306 * values for shell completion.
307 *
308 * @return
309 * Array of popular fillings.
310 */
311 function sandwich_make_me_a_sandwich_complete() {
312 return array('values' => array('turkey', 'cheese', 'jelly', 'butter'));
313 }