| 
									
										
										
										
											2016-02-03 23:01:32 +08:00
										 |  |  | ## The contents of this file are subject to the Mozilla Public License | 
					
						
							|  |  |  | ## Version 1.1 (the "License"); you may not use this file except in | 
					
						
							|  |  |  | ## compliance with the License. You may obtain a copy of the License | 
					
						
							|  |  |  | ## at http://www.mozilla.org/MPL/ | 
					
						
							|  |  |  | ## | 
					
						
							|  |  |  | ## Software distributed under the License is distributed on an "AS IS" | 
					
						
							|  |  |  | ## basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See | 
					
						
							|  |  |  | ## the License for the specific language governing rights and | 
					
						
							|  |  |  | ## limitations under the License. | 
					
						
							|  |  |  | ## | 
					
						
							|  |  |  | ## The Original Code is RabbitMQ. | 
					
						
							|  |  |  | ## | 
					
						
							|  |  |  | ## The Initial Developer of the Original Code is GoPivotal, Inc. | 
					
						
							|  |  |  | ## Copyright (c) 2007-2016 Pivotal Software, Inc.  All rights reserved. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-03 22:42:45 +08:00
										 |  |  | defmodule RabbitMQCtl do | 
					
						
							| 
									
										
										
										
											2016-06-09 09:00:43 +08:00
										 |  |  |   alias RabbitMQ.CLI.Distribution,  as: Distribution | 
					
						
							|  |  |  |   alias RabbitMQ.CLI.StandardCodes, as: StandardCodes | 
					
						
							| 
									
										
										
										
											2016-06-09 08:34:56 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-09 09:08:21 +08:00
										 |  |  |   import RabbitMQ.CLI.Ctl.Helpers | 
					
						
							|  |  |  |   import  RabbitMQ.CLI.Ctl.Parser | 
					
						
							| 
									
										
										
										
											2016-06-09 08:34:56 +08:00
										 |  |  |   import RabbitMQ.CLI.ExitCodes | 
					
						
							| 
									
										
										
										
											2016-02-03 02:54:36 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-09 18:07:46 +08:00
										 |  |  |   def main(unparsed_command) do | 
					
						
							| 
									
										
										
										
											2016-05-27 05:02:10 +08:00
										 |  |  |     {parsed_cmd, options, invalid} = parse(unparsed_command) | 
					
						
							| 
									
										
										
										
											2016-06-09 08:34:56 +08:00
										 |  |  |     case {is_command?(parsed_cmd), invalid} do | 
					
						
							| 
									
										
										
										
											2016-06-08 22:19:37 +08:00
										 |  |  |       {false, _}  -> | 
					
						
							|  |  |  |         HelpCommand.all_usage() |> handle_exit(exit_usage); | 
					
						
							|  |  |  |       {_, [_|_]}  -> | 
					
						
							|  |  |  |         print_standard_messages({:bad_option, invalid}, unparsed_command) | 
					
						
							|  |  |  |         |> handle_exit | 
					
						
							|  |  |  |       {true, []}  -> | 
					
						
							| 
									
										
										
										
											2016-06-10 05:55:59 +08:00
										 |  |  |         effective_options = options |> merge_defaults_defaults |> normalize_node | 
					
						
							| 
									
										
										
										
											2016-06-09 08:34:56 +08:00
										 |  |  |         Distribution.start(effective_options) | 
					
						
							| 
									
										
										
										
											2016-06-08 22:19:37 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |         effective_options | 
					
						
							|  |  |  |         |> run_command(parsed_cmd) | 
					
						
							|  |  |  |         |> StandardCodes.map_to_standard_code | 
					
						
							|  |  |  |         |> print_standard_messages(unparsed_command) | 
					
						
							|  |  |  |         |> handle_exit | 
					
						
							| 
									
										
										
										
											2016-03-05 05:35:54 +08:00
										 |  |  |     end | 
					
						
							| 
									
										
										
										
											2016-02-03 05:32:35 +08:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-24 19:33:11 +08:00
										 |  |  |   def merge_defaults_defaults(%{} = options) do | 
					
						
							| 
									
										
										
										
											2016-03-08 03:08:38 +08:00
										 |  |  |     options | 
					
						
							| 
									
										
										
										
											2016-05-24 19:33:11 +08:00
										 |  |  |     |> merge_defaults_node | 
					
						
							|  |  |  |     |> merge_defaults_timeout | 
					
						
							| 
									
										
										
										
											2016-06-08 22:19:37 +08:00
										 |  |  |     |> merge_defaults_longnames | 
					
						
							| 
									
										
										
										
											2016-03-08 03:08:38 +08:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-24 19:33:11 +08:00
										 |  |  |   defp merge_defaults_node(%{} = opts), do: Map.merge(%{node: get_rabbit_hostname}, opts) | 
					
						
							| 
									
										
										
										
											2016-03-08 06:45:50 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-24 19:33:11 +08:00
										 |  |  |   defp merge_defaults_timeout(%{} = opts), do: Map.merge(%{timeout: :infinity}, opts) | 
					
						
							| 
									
										
										
										
											2016-03-08 06:45:50 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-08 22:19:37 +08:00
										 |  |  |   defp merge_defaults_longnames(%{} = opts), do: Map.merge(%{longnames: false}, opts) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-10 05:55:59 +08:00
										 |  |  |   defp normalize_node(%{node: node} = opts) do | 
					
						
							|  |  |  |     Map.merge(opts, %{node: parse_node(node)}) | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-02 06:38:09 +08:00
										 |  |  |   defp maybe_connect_to_rabbitmq("help", _), do: nil | 
					
						
							| 
									
										
										
										
											2016-05-31 16:40:48 +08:00
										 |  |  |   defp maybe_connect_to_rabbitmq(_, node) do | 
					
						
							| 
									
										
										
										
											2016-06-09 08:34:56 +08:00
										 |  |  |     connect_to_rabbitmq(node) | 
					
						
							| 
									
										
										
										
											2016-05-31 16:40:48 +08:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-26 07:04:24 +08:00
										 |  |  |   defp run_command(_, []), do: HelpCommand.all_usage() | 
					
						
							| 
									
										
										
										
											2016-05-06 01:17:50 +08:00
										 |  |  |   defp run_command(options, [command_name | arguments]) do | 
					
						
							| 
									
										
										
										
											2016-05-09 18:07:46 +08:00
										 |  |  |     with_command(command_name, | 
					
						
							|  |  |  |         fn(command) -> | 
					
						
							|  |  |  |             case invalid_flags(command, options) do | 
					
						
							| 
									
										
										
										
											2016-05-26 07:04:24 +08:00
										 |  |  |               [] -> | 
					
						
							| 
									
										
										
										
											2016-05-24 19:33:11 +08:00
										 |  |  |                 case command.validate(arguments, options) do | 
					
						
							|  |  |  |                   :ok -> | 
					
						
							|  |  |  |                     {arguments, options} = command.merge_defaults(arguments, options) | 
					
						
							|  |  |  |                     print_banner(command, arguments, options) | 
					
						
							| 
									
										
										
										
											2016-05-31 16:40:48 +08:00
										 |  |  |                     maybe_connect_to_rabbitmq(command_name, options[:node]) | 
					
						
							| 
									
										
										
										
											2016-05-24 19:33:11 +08:00
										 |  |  |                     execute_command(command, arguments, options) | 
					
						
							|  |  |  |                   err -> err | 
					
						
							|  |  |  |                 end | 
					
						
							| 
									
										
										
										
											2016-05-09 18:07:46 +08:00
										 |  |  |               result  ->  {:bad_option, result} | 
					
						
							|  |  |  |             end | 
					
						
							|  |  |  |         end) | 
					
						
							| 
									
										
										
										
											2016-02-03 02:54:36 +08:00
										 |  |  |   end | 
					
						
							| 
									
										
										
										
											2016-02-26 05:16:25 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-09 18:07:46 +08:00
										 |  |  |   defp with_command(command_name, fun) do | 
					
						
							| 
									
										
										
										
											2016-06-09 08:34:56 +08:00
										 |  |  |     command = commands[command_name] | 
					
						
							| 
									
										
										
										
											2016-05-26 07:04:24 +08:00
										 |  |  |     fun.(command) | 
					
						
							| 
									
										
										
										
											2016-05-05 06:31:11 +08:00
										 |  |  |   end | 
					
						
							| 
									
										
										
										
											2016-04-27 02:38:23 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-24 19:33:11 +08:00
										 |  |  |   defp print_banner(command, args, opts) do | 
					
						
							| 
									
										
										
										
											2016-05-31 16:40:48 +08:00
										 |  |  |     case command.banner(args, opts) do | 
					
						
							| 
									
										
										
										
											2016-06-02 06:38:09 +08:00
										 |  |  |      nil -> nil | 
					
						
							| 
									
										
										
										
											2016-05-31 16:40:48 +08:00
										 |  |  |      banner -> IO.inspect banner | 
					
						
							|  |  |  |     end | 
					
						
							| 
									
										
										
										
											2016-05-24 19:33:11 +08:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-09 18:07:46 +08:00
										 |  |  |   defp execute_command(command, arguments, options) do | 
					
						
							|  |  |  |     command.run(arguments, options) | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-27 02:38:23 +08:00
										 |  |  |   defp print_standard_messages({:badrpc, :nodedown} = result, unparsed_command) do | 
					
						
							| 
									
										
										
										
											2016-05-27 05:02:10 +08:00
										 |  |  |     {_, options, _} = parse(unparsed_command) | 
					
						
							| 
									
										
										
										
											2016-03-09 01:15:56 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     IO.puts "Error: unable to connect to node '#{options[:node]}': nodedown" | 
					
						
							| 
									
										
										
										
											2016-04-27 02:38:23 +08:00
										 |  |  |     result | 
					
						
							| 
									
										
										
										
											2016-03-09 01:15:56 +08:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-27 02:38:23 +08:00
										 |  |  |   defp print_standard_messages({:badrpc, :timeout} = result, unparsed_command) do | 
					
						
							| 
									
										
										
										
											2016-05-27 05:02:10 +08:00
										 |  |  |     {_, options, _} = parse(unparsed_command) | 
					
						
							| 
									
										
										
										
											2016-04-27 02:38:23 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-09 01:15:56 +08:00
										 |  |  |     IO.puts "Error: {timeout, #{options[:timeout]}}" | 
					
						
							| 
									
										
										
										
											2016-04-27 02:38:23 +08:00
										 |  |  |     result | 
					
						
							| 
									
										
										
										
											2016-03-09 01:15:56 +08:00
										 |  |  |   end | 
					
						
							| 
									
										
										
										
											2016-03-22 01:59:22 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-09 23:38:37 +08:00
										 |  |  |   defp print_standard_messages({:too_many_args, _} = result, unparsed_command) do | 
					
						
							| 
									
										
										
										
											2016-05-27 05:02:10 +08:00
										 |  |  |     {[cmd | _], _, _} = parse(unparsed_command) | 
					
						
							| 
									
										
										
										
											2016-05-09 23:38:37 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-27 02:38:23 +08:00
										 |  |  |     IO.puts "Error: too many arguments." | 
					
						
							| 
									
										
										
										
											2016-04-30 02:08:42 +08:00
										 |  |  |     IO.puts "Given:\n\t#{unparsed_command |> Enum.join(" ")}" | 
					
						
							| 
									
										
										
										
											2016-05-26 07:28:20 +08:00
										 |  |  |     HelpCommand.run([cmd], %{}) | 
					
						
							| 
									
										
										
										
											2016-04-27 02:38:23 +08:00
										 |  |  |     result | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-09 23:38:37 +08:00
										 |  |  |   defp print_standard_messages({:not_enough_args, _} = result, unparsed_command) do | 
					
						
							| 
									
										
										
										
											2016-05-27 05:02:10 +08:00
										 |  |  |     {[cmd | _], _, _} = parse(unparsed_command) | 
					
						
							| 
									
										
										
										
											2016-05-09 23:38:37 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-27 02:38:23 +08:00
										 |  |  |     IO.puts "Error: not enough arguments." | 
					
						
							| 
									
										
										
										
											2016-04-30 02:08:42 +08:00
										 |  |  |     IO.puts "Given:\n\t#{unparsed_command |> Enum.join(" ")}" | 
					
						
							| 
									
										
										
										
											2016-05-26 07:28:20 +08:00
										 |  |  |     HelpCommand.run([cmd], %{}) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-27 02:38:23 +08:00
										 |  |  |     result | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   defp print_standard_messages({:refused, user, _, _} = result, _) do | 
					
						
							| 
									
										
										
										
											2016-04-02 01:58:47 +08:00
										 |  |  |     IO.puts "Error: failed to authenticate user \"#{user}\"" | 
					
						
							| 
									
										
										
										
											2016-04-27 02:38:23 +08:00
										 |  |  |     result | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-06 22:02:58 +08:00
										 |  |  |   defp print_standard_messages( | 
					
						
							|  |  |  |     {failed_command, | 
					
						
							|  |  |  |      {:mnesia_unexpectedly_running, node_name}} = result, _) | 
					
						
							|  |  |  |   when | 
					
						
							|  |  |  |     failed_command == :reset_failed or | 
					
						
							|  |  |  |     failed_command == :join_cluster_failed | 
					
						
							|  |  |  |   do | 
					
						
							| 
									
										
										
										
											2016-06-02 18:19:07 +08:00
										 |  |  |     IO.puts "Mnesia is still running on node #{node_name}." | 
					
						
							| 
									
										
										
										
											2016-06-06 22:00:50 +08:00
										 |  |  |     IO.puts "Please stop RabbitMQ with rabbitmqctl stop_app first." | 
					
						
							| 
									
										
										
										
											2016-06-02 18:19:07 +08:00
										 |  |  |     result | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-02 22:36:52 +08:00
										 |  |  |   defp print_standard_messages({:error, :process_not_running} = result, _) do | 
					
						
							|  |  |  |     IO.puts "Error: process is not running." | 
					
						
							|  |  |  |     result | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   defp print_standard_messages({:error, {:garbage_in_pid_file, _}} = result, _) do | 
					
						
							|  |  |  |     IO.puts "Error: garbage in pid file." | 
					
						
							|  |  |  |     result | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   defp print_standard_messages({:error, {:could_not_read_pid, err}} = result, _) do | 
					
						
							|  |  |  |     IO.puts "Error: could not read pid. Detail: #{err}" | 
					
						
							|  |  |  |     result | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-02 06:38:09 +08:00
										 |  |  |   defp print_standard_messages({:healthcheck_failed, message} = result, _) do | 
					
						
							|  |  |  |     IO.puts "Error: healthcheck failed. Message: #{message}" | 
					
						
							|  |  |  |     result | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-09 23:07:49 +08:00
										 |  |  |   defp print_standard_messages({:bad_option, _} = result, unparsed_command) do | 
					
						
							| 
									
										
										
										
											2016-05-27 05:02:10 +08:00
										 |  |  |     {[cmd | _], _, _} = parse(unparsed_command) | 
					
						
							| 
									
										
										
										
											2016-05-09 23:07:49 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-05 03:40:09 +08:00
										 |  |  |     IO.puts "Error: invalid options for this command." | 
					
						
							|  |  |  |     IO.puts "Given:\n\t#{unparsed_command |> Enum.join(" ")}" | 
					
						
							| 
									
										
										
										
											2016-05-26 07:28:20 +08:00
										 |  |  |     HelpCommand.run([cmd], %{}) | 
					
						
							| 
									
										
										
										
											2016-05-05 03:40:09 +08:00
										 |  |  |     result | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-24 19:33:11 +08:00
										 |  |  |   defp print_standard_messages({:validation_failure, err_detail} = result, unparsed_command) do | 
					
						
							| 
									
										
										
										
											2016-05-30 07:16:10 +08:00
										 |  |  |     {[command_name | _], _, _} = parse(unparsed_command) | 
					
						
							|  |  |  |     err = format_validation_error(err_detail) # TODO format the error better | 
					
						
							| 
									
										
										
										
											2016-05-24 19:33:11 +08:00
										 |  |  |     IO.puts "Error: #{err}" | 
					
						
							|  |  |  |     IO.puts "Given:\n\t#{unparsed_command |> Enum.join(" ")}" | 
					
						
							| 
									
										
										
										
											2016-05-30 07:16:10 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-09 08:34:56 +08:00
										 |  |  |     case is_command?(command_name) do | 
					
						
							| 
									
										
										
										
											2016-05-30 07:16:10 +08:00
										 |  |  |       true  -> | 
					
						
							| 
									
										
										
										
											2016-06-09 08:34:56 +08:00
										 |  |  |         command = commands[command_name] | 
					
						
							| 
									
										
										
										
											2016-05-30 07:16:10 +08:00
										 |  |  |         HelpCommand.print_base_usage(command) | 
					
						
							|  |  |  |       false -> | 
					
						
							|  |  |  |         HelpCommand.all_usage() | 
					
						
							|  |  |  |         ExitCodes.exit_usage | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-24 19:33:11 +08:00
										 |  |  |     result | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-27 02:38:23 +08:00
										 |  |  |   defp print_standard_messages(result, _) do | 
					
						
							|  |  |  |     result | 
					
						
							| 
									
										
										
										
											2016-04-02 01:58:47 +08:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-24 19:33:11 +08:00
										 |  |  |   defp format_validation_error(:not_enough_args), do: "not enough arguments." | 
					
						
							|  |  |  |   defp format_validation_error({:not_enough_args, detail}), do: "not enough arguments. #{detail}" | 
					
						
							|  |  |  |   defp format_validation_error(:too_many_args), do: "too many arguments." | 
					
						
							|  |  |  |   defp format_validation_error({:too_many_args, detail}), do: "too many arguments. #{detail}" | 
					
						
							|  |  |  |   defp format_validation_error(:bad_argument), do: "Bad argument." | 
					
						
							|  |  |  |   defp format_validation_error({:bad_argument, detail}), do: "Bad argument. #{detail}" | 
					
						
							|  |  |  |   defp format_validation_error(err), do: inspect err | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   defp handle_exit({:validation_failure, :not_enough_args}), do: exit_program(exit_usage) | 
					
						
							|  |  |  |   defp handle_exit({:validation_failure, :too_many_args}), do: exit_program(exit_usage) | 
					
						
							|  |  |  |   defp handle_exit({:validation_failure, {:not_enough_args, _}}), do: exit_program(exit_usage) | 
					
						
							|  |  |  |   defp handle_exit({:validation_failure, {:too_many_args, _}}), do: exit_program(exit_usage) | 
					
						
							|  |  |  |   defp handle_exit({:validation_failure, {:bad_argument, _}}), do: exit_program(exit_dataerr) | 
					
						
							|  |  |  |   defp handle_exit({:validation_failure, :bad_argument}), do: exit_program(exit_dataerr) | 
					
						
							|  |  |  |   defp handle_exit({:validation_failure, _}), do: exit_program(exit_usage) | 
					
						
							| 
									
										
										
										
											2016-06-09 05:42:51 +08:00
										 |  |  |   defp handle_exit({:bad_option, _} = _err), do: exit_program(exit_usage) | 
					
						
							| 
									
										
										
										
											2016-03-23 00:21:12 +08:00
										 |  |  |   defp handle_exit({:badrpc, :timeout}), do: exit_program(exit_tempfail) | 
					
						
							|  |  |  |   defp handle_exit({:badrpc, :nodedown}), do: exit_program(exit_unavailable) | 
					
						
							| 
									
										
										
										
											2016-04-02 01:58:47 +08:00
										 |  |  |   defp handle_exit({:refused, _, _, _}), do: exit_program(exit_dataerr) | 
					
						
							| 
									
										
										
										
											2016-06-02 06:38:09 +08:00
										 |  |  |   defp handle_exit({:healthcheck_failed, _}), do: exit_program(exit_software) | 
					
						
							| 
									
										
										
										
											2016-06-06 22:02:58 +08:00
										 |  |  |   defp handle_exit({:join_cluster_failed, _}), do: exit_program(exit_software) | 
					
						
							| 
									
										
										
										
											2016-06-02 18:19:07 +08:00
										 |  |  |   defp handle_exit({:reset_failed, _}), do: exit_program(exit_software) | 
					
						
							| 
									
										
										
										
											2016-03-23 00:21:12 +08:00
										 |  |  |   defp handle_exit({:error, _}), do: exit_program(exit_software) | 
					
						
							| 
									
										
										
										
											2016-06-02 06:38:09 +08:00
										 |  |  |   defp handle_exit(true), do: handle_exit(:ok, exit_ok) | 
					
						
							| 
									
										
										
										
											2016-04-02 01:42:25 +08:00
										 |  |  |   defp handle_exit(:ok), do: handle_exit(:ok, exit_ok) | 
					
						
							|  |  |  |   defp handle_exit({:ok, result}), do: handle_exit({:ok, result}, exit_ok) | 
					
						
							|  |  |  |   defp handle_exit(result) when is_list(result), do: handle_exit({:ok, result}, exit_ok) | 
					
						
							| 
									
										
										
										
											2016-03-23 00:21:12 +08:00
										 |  |  |   defp handle_exit(:ok, code), do: exit_program(code) | 
					
						
							|  |  |  |   defp handle_exit({:ok, result}, code) do | 
					
						
							| 
									
										
										
										
											2016-05-26 03:03:17 +08:00
										 |  |  |     case Enumerable.impl_for(result) do | 
					
						
							|  |  |  |       nil -> IO.inspect result; | 
					
						
							|  |  |  |       _   -> result |> Stream.map(&IO.inspect/1) |> Stream.run | 
					
						
							|  |  |  |     end | 
					
						
							| 
									
										
										
										
											2016-03-23 00:21:12 +08:00
										 |  |  |     exit_program(code) | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-05 18:39:27 +08:00
										 |  |  |   defp invalid_flags(command, opts) do | 
					
						
							| 
									
										
										
										
											2016-06-09 08:34:56 +08:00
										 |  |  |     Map.keys(opts) -- (command.flags ++ global_flags) | 
					
						
							| 
									
										
										
										
											2016-05-05 03:40:09 +08:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-23 00:21:12 +08:00
										 |  |  |   defp exit_program(code) do | 
					
						
							|  |  |  |     :net_kernel.stop | 
					
						
							| 
									
										
										
										
											2016-04-02 00:13:01 +08:00
										 |  |  |     exit({:shutdown, code}) | 
					
						
							| 
									
										
										
										
											2016-03-23 00:21:12 +08:00
										 |  |  |   end | 
					
						
							| 
									
										
										
										
											2016-02-03 02:54:36 +08:00
										 |  |  | end |