Class: CommandMapper::Command
- Inherits:
-
Object
- Object
- CommandMapper::Command
- Includes:
- Types
- Defined in:
- lib/command_mapper/command.rb
Overview
Base class for all mapped commands.
Direct Known Subclasses
Instance Attribute Summary collapse
-
#command_env ⇒ Hash{String => String}
readonly
The environment variables to execute the command with.
-
#command_name ⇒ String
readonly
The command name.
-
#command_path ⇒ String?
readonly
The optional path to the command.
-
#command_subcommand ⇒ Command?
readonly
The subcommand's options and arguments.
Class Method Summary collapse
-
.argument(name, required: true, type: Str.new, repeats: false) ⇒ Object
Defines an option for the command.
-
.arguments ⇒ Hash{Symbol => Argument}
All defined options.
-
.capture(params = {}, **kwargs) {|command| ... } ⇒ String
Initializes and runs the command in a shell and captures all stdout output.
- .command(new_command_name) {|self| ... } ⇒ Object
-
.command_name ⇒ String
Gets or sets the command name.
-
.has_argument?(name) ⇒ Boolean
Determines if an argument with the given name has been defined.
-
.has_option?(name) ⇒ Boolean
Determines if an option with the given name has been defined.
-
.has_subcommand?(name) ⇒ Boolean
Determines if a subcommand with the given name has been defined.
-
.option(flag, name: nil, value: nil, repeats: false, equals: nil, value_in_flag: nil, &block) ⇒ Object
Defines an option for the command.
-
.options ⇒ Hash{Symbol => Option}
All defined options.
-
.popen(params = {}, mode: 'r', **kwargs) {|command| ... } ⇒ IO
Initializes and executes the command and returns an IO object to it.
-
.run(params = {}, **kwargs) {|command| ... } ⇒ Boolean?
Initializes and runs the command.
-
.spawn(params = {}, **kwargs) {|command| ... } ⇒ Integer
Initializes and spawns the command as a separate process, returning the PID of the process.
-
.subcommand(name) {|subcommand| ... } ⇒ Object
Defines a subcommand.
-
.subcommands ⇒ Hash{Symbol => Command.class}
All defined subcommands.
-
.sudo(params = {}, sudo: {}, **kwargs) {|command| ... } ⇒ Boolean?
Initializes and runs the command through
sudo
.
Instance Method Summary collapse
-
#[](name) ⇒ Object
Gets the value of an option or an argument.
-
#[]=(name, value) ⇒ Object
Sets an option or an argument with the given name.
-
#capture_command ⇒ String
Runs the command in a shell and captures all stdout output.
-
#command_argv ⇒ Array<String>
Returns an Array of command-line arguments for the command.
-
#command_string ⇒ String
Escapes any shell control-characters so that it can be ran in a shell.
-
#initialize(params = {}, command_name: self.class.command_name, command_path: nil, command_env: {}, **kwargs) {|self| ... } ⇒ Command
constructor
Initializes the command.
-
#popen_command(mode = nil) ⇒ IO
Executes the command and returns an IO object to it.
-
#run_command ⇒ Boolean?
Runs the command.
-
#spawn_command ⇒ Integer
Spawns the command as a separate process, returning the PID of the process.
-
#sudo_command(askpass: nil, background: nil, bell: nil, close_from: nil, chdir: nil, preserve_env: nil, group: nil, set_home: nil, host: nil, login: nil, remove_timestamp: nil, reset_timestamp: nil, non_interactive: nil, preserve_groups: nil, prompt: nil, chroot: nil, role: nil, stdin: nil, shell: nil, type: nil, command_timeout: nil, other_user: nil, user: nil, &block) ⇒ Boolean?
Runs the command through
sudo
. - #to_a ⇒ Object
- #to_s ⇒ Object
Methods included from Types
Constructor Details
#initialize(params = {}, command_name: self.class.command_name, command_path: nil, command_env: {}, **kwargs) {|self| ... } ⇒ Command
Initializes the command.
71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
# File 'lib/command_mapper/command.rb', line 71 def initialize(params={}, command_name: self.class.command_name, command_path: nil, command_env: {}, **kwargs) @command_name = command_name @command_path = command_path @command_env = command_env params = params.merge(kwargs) params.each do |name,value| self[name] = value end yield self if block_given? end |
Instance Attribute Details
#command_env ⇒ Hash{String => String} (readonly)
The environment variables to execute the command with.
30 31 32 |
# File 'lib/command_mapper/command.rb', line 30 def command_env @command_env end |
#command_name ⇒ String (readonly)
The command name.
20 21 22 |
# File 'lib/command_mapper/command.rb', line 20 def command_name @command_name end |
#command_path ⇒ String? (readonly)
The optional path to the command.
25 26 27 |
# File 'lib/command_mapper/command.rb', line 25 def command_path @command_path end |
#command_subcommand ⇒ Command? (readonly)
The subcommand's options and arguments.
35 36 37 |
# File 'lib/command_mapper/command.rb', line 35 def command_subcommand @command_subcommand end |
Class Method Details
.argument(name, required: true, type: Str.new, repeats: false) ⇒ Object
Defines an option for the command.
504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 |
# File 'lib/command_mapper/command.rb', line 504 def self.argument(name, required: true, type: Str.new, repeats: false) name = name.to_sym argument = Argument.new(name, required: required, type: type, repeats: repeats) if is_internal_method?(argument.name) raise(ArgumentError,"argument #{name.inspect} cannot override internal method with same name: ##{argument.name}") elsif has_option?(argument.name) raise(ArgumentError,"argument #{name.inspect} conflicts with another option with the same name") elsif has_subcommand?(argument.name) raise(ArgumentError,"argument #{name.inspect} conflicts with another subcommand with the same name") end self.arguments[argument.name] = argument attr_accessor name end |
.arguments ⇒ Hash{Symbol => Argument}
All defined options.
450 451 452 453 454 455 456 |
# File 'lib/command_mapper/command.rb', line 450 def self.arguments @arguments ||= if superclass < Command superclass.arguments.dup else {} end end |
.capture(params = {}, **kwargs) {|command| ... } ⇒ String
Initializes and runs the command in a shell and captures all stdout output.
158 159 160 161 |
# File 'lib/command_mapper/command.rb', line 158 def self.capture(params={},**kwargs,&block) command = new(params,**kwargs,&block) command.capture_command end |
.command(new_command_name) {|self| ... } ⇒ Object
317 318 319 320 |
# File 'lib/command_mapper/command.rb', line 317 def self.command(new_command_name,&block) @command_name = new_command_name.to_s.freeze yield self if block_given? end |
.command_name ⇒ String
Gets or sets the command name.
292 293 294 295 296 297 298 |
# File 'lib/command_mapper/command.rb', line 292 def self.command_name @command_name || if superclass < Command superclass.command_name else raise(NotImplementedError,"#{self} did not call command(...)") end end |
.has_argument?(name) ⇒ Boolean
Determines if an argument with the given name has been defined.
471 472 473 |
# File 'lib/command_mapper/command.rb', line 471 def self.has_argument?(name) arguments.has_key?(name) end |
.has_option?(name) ⇒ Boolean
Determines if an option with the given name has been defined.
350 351 352 |
# File 'lib/command_mapper/command.rb', line 350 def self.has_option?(name) .has_key?(name) end |
.has_subcommand?(name) ⇒ Boolean
Determines if a subcommand with the given name has been defined.
551 552 553 |
# File 'lib/command_mapper/command.rb', line 551 def self.has_subcommand?(name) subcommands.has_key?(name) end |
.option(flag, name: nil, value: nil, repeats: false, equals: nil, value_in_flag: nil, &block) ⇒ Object
Defines an option for the command.
413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 |
# File 'lib/command_mapper/command.rb', line 413 def self.option(flag, name: nil, value: nil, repeats: false, # formatting options equals: nil, value_in_flag: nil, &block) option = Option.new(flag, name: name, value: value, repeats: repeats, # formatting options equals: equals, value_in_flag: value_in_flag, &block) if is_internal_method?(option.name) if name raise(ArgumentError,"option #{flag.inspect} with name #{name.inspect} cannot override the internal method with same name: ##{option.name}") else raise(ArgumentError,"option #{flag.inspect} maps to method name ##{option.name} and cannot override the internal method with same name: ##{option.name}") end elsif has_argument?(option.name) raise(ArgumentError,"option #{flag.inspect} with name #{option.name.inspect} conflicts with another argument with the same name") elsif has_subcommand?(option.name) raise(ArgumentError,"option #{flag.inspect} with name #{option.name.inspect} conflicts with another subcommand with the same name") end self.[option.name] = option attr_accessor option.name end |
.options ⇒ Hash{Symbol => Option}
All defined options.
329 330 331 332 333 334 335 |
# File 'lib/command_mapper/command.rb', line 329 def self. @options ||= if superclass < Command superclass..dup else {} end end |
.popen(params = {}, mode: 'r', **kwargs) {|command| ... } ⇒ IO
Initializes and executes the command and returns an IO object to it.
183 184 185 186 |
# File 'lib/command_mapper/command.rb', line 183 def self.popen(params={}, mode: 'r', **kwargs,&block) command = new(params,**kwargs,&block) command.popen_command end |
.run(params = {}, **kwargs) {|command| ... } ⇒ Boolean?
Initializes and runs the command.
105 106 107 108 |
# File 'lib/command_mapper/command.rb', line 105 def self.run(params={},**kwargs,&block) command = new(params,**kwargs,&block) command.run_command end |
.spawn(params = {}, **kwargs) {|command| ... } ⇒ Integer
Initializes and spawns the command as a separate process, returning the PID of the process.
134 135 136 137 |
# File 'lib/command_mapper/command.rb', line 134 def self.spawn(params={},**kwargs,&block) command = new(params,**kwargs,&block) command.spawn_command end |
.subcommand(name) {|subcommand| ... } ⇒ Object
Also defines a class within the command class using the subcommand's name.
Defines a subcommand.
585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 |
# File 'lib/command_mapper/command.rb', line 585 def self.subcommand(name,&block) name = name.to_s method_name = name.tr('-','_') class_name = name.split(/[_-]+/).map(&:capitalize).join subcommand_name = method_name.to_sym if is_internal_method?(method_name) raise(ArgumentError,"subcommand #{name.inspect} maps to method name ##{method_name} and cannot override the internal method with same name: ##{method_name}") elsif has_option?(subcommand_name) raise(ArgumentError,"subcommand #{name.inspect} conflicts with another option with the same name") elsif has_argument?(subcommand_name) raise(ArgumentError,"subcommand #{name.inspect} conflicts with another argument with the same name") end subcommand_class = Class.new(Command) subcommand_class.command(name) subcommand_class.class_eval(&block) self.subcommands[subcommand_name] = subcommand_class const_set(class_name,subcommand_class) define_method(method_name) do |&block| if block then @command_subcommand = subcommand_class.new(&block) else @command_subcommand end end define_method(:"#{method_name}=") do || @command_subcommand = if subcommand_class.new() end end end |
.subcommands ⇒ Hash{Symbol => Command.class}
All defined subcommands.
530 531 532 533 534 535 536 |
# File 'lib/command_mapper/command.rb', line 530 def self.subcommands @subcommands ||= if superclass < Command superclass.subcommands.dup else {} end end |
.sudo(params = {}, sudo: {}, **kwargs) {|command| ... } ⇒ Boolean?
Initializes and runs the command through sudo
.
276 277 278 279 |
# File 'lib/command_mapper/command.rb', line 276 def self.sudo(params={}, sudo: {}, **kwargs,&block) command = new(params,**kwargs,&block) command.sudo_command(**sudo) end |
Instance Method Details
#[](name) ⇒ Object
Gets the value of an option or an argument.
631 632 633 634 635 636 637 638 639 |
# File 'lib/command_mapper/command.rb', line 631 def [](name) name = name.to_s if respond_to?(name) send(name) else raise(ArgumentError,"#{self.class} does not define ##{name}") end end |
#[]=(name, value) ⇒ Object
Sets an option or an argument with the given name.
656 657 658 659 660 661 662 |
# File 'lib/command_mapper/command.rb', line 656 def []=(name,value) if respond_to?("#{name}=") send("#{name}=",value) else raise(ArgumentError,"#{self.class} does not define ##{name}=") end end |
#capture_command ⇒ String
Runs the command in a shell and captures all stdout output.
764 765 766 |
# File 'lib/command_mapper/command.rb', line 764 def capture_command `#{command_string}` end |
#command_argv ⇒ Array<String>
Returns an Array of command-line arguments for the command.
673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 |
# File 'lib/command_mapper/command.rb', line 673 def command_argv argv = [@command_path || @command_name] self.class..each do |name,option| unless (value = self[name]).nil? option.argv(argv,value) end end if @command_subcommand # a subcommand takes precedence over any command arguments argv.concat(@command_subcommand.command_argv) else additional_args = [] self.class.arguments.each do |name,argument| value = self[name] if value.nil? if argument.required? raise(ArgumentRequired,"argument #{name} is required") end else argument.argv(additional_args,value) end end if additional_args.any? { |arg| arg.start_with?('-') } # append a '--' separator if any of the arguments start with a '-' argv << '--' end argv.concat(additional_args) end return argv end |
#command_string ⇒ String
Escapes any shell control-characters so that it can be ran in a shell.
717 718 719 720 721 722 723 724 725 726 727 728 729 |
# File 'lib/command_mapper/command.rb', line 717 def command_string escaped_command = Shellwords.shelljoin(command_argv) unless @command_env.empty? escaped_env = @command_env.map { |name,value| "#{Shellwords.shellescape(name)}=#{Shellwords.shellescape(value)}" }.join(' ') escaped_command = "#{escaped_env} #{escaped_command}" end return escaped_command end |
#popen_command(mode = nil) ⇒ IO
Executes the command and returns an IO object to it.
774 775 776 777 778 |
# File 'lib/command_mapper/command.rb', line 774 def popen_command(mode=nil) if mode then IO.popen(@command_env,command_argv,mode) else IO.popen(@command_env,command_argv) end end |
#run_command ⇒ Boolean?
Runs the command.
738 739 740 |
# File 'lib/command_mapper/command.rb', line 738 def run_command Kernel.system(@command_env,*command_argv) end |
#spawn_command ⇒ Integer
Spawns the command as a separate process, returning the PID of the process.
754 755 756 |
# File 'lib/command_mapper/command.rb', line 754 def spawn_command Process.spawn(@command_env,*command_argv) end |
#sudo_command(askpass: nil, background: nil, bell: nil, close_from: nil, chdir: nil, preserve_env: nil, group: nil, set_home: nil, host: nil, login: nil, remove_timestamp: nil, reset_timestamp: nil, non_interactive: nil, preserve_groups: nil, prompt: nil, chroot: nil, role: nil, stdin: nil, shell: nil, type: nil, command_timeout: nil, other_user: nil, user: nil, &block) ⇒ Boolean?
Runs the command through sudo
.
856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 |
# File 'lib/command_mapper/command.rb', line 856 def sudo_command(askpass: nil, background: nil, bell: nil, close_from: nil, chdir: nil, preserve_env: nil, group: nil, set_home: nil, host: nil, login: nil, remove_timestamp: nil, reset_timestamp: nil, non_interactive: nil, preserve_groups: nil, prompt: nil, chroot: nil, role: nil, stdin: nil, shell: nil, type: nil, command_timeout: nil, other_user: nil, user: nil, &block) sudo_params = {command: command_argv} sudo_params[:askpass] = askpass unless askpass.nil? sudo_params[:background] = background unless background.nil? sudo_params[:bell] = bell unless bell.nil? sudo_params[:close_from] = close_from unless close_from.nil? sudo_params[:chdir] = chdir unless chdir.nil? sudo_params[:preserve_env] = preserve_env unless preserve_env.nil? sudo_params[:group] = group unless group.nil? sudo_params[:set_home] = set_home unless set_home.nil? sudo_params[:host] = host unless host.nil? sudo_params[:login] = login unless login.nil? sudo_params[:remove_timestamp] = unless .nil? sudo_params[:reset_timestamp] = unless .nil? sudo_params[:non_interactive] = non_interactive unless non_interactive.nil? sudo_params[:preserve_groups] = preserve_groups unless preserve_groups.nil? sudo_params[:prompt] = prompt unless prompt.nil? sudo_params[:chroot] = chroot unless chroot.nil? sudo_params[:role] = role unless role.nil? sudo_params[:stdin] = stdin unless stdin.nil? sudo_params[:shell] = shell unless shell.nil? sudo_params[:type] = type unless type.nil? sudo_params[:command_timeout] = command_timeout unless command_timeout.nil? sudo_params[:other_user] = other_user unless other_user.nil? sudo_params[:user] = user unless user.nil? Sudo.run(sudo_params, command_env: @command_env, &block) end |
#to_a ⇒ Object
911 912 913 |
# File 'lib/command_mapper/command.rb', line 911 def to_a command_argv end |
#to_s ⇒ Object
918 919 920 |
# File 'lib/command_mapper/command.rb', line 918 def to_s command_string end |