rubycom 0.1.1 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.md +86 -5
 - data/Rakefile +12 -6
 - data/lib/rubycom/version.rb +1 -1
 - data/lib/rubycom.rb +118 -175
 - data/rubycom.gemspec +1 -1
 - data/test/rubycom/test_rubycom.rb +100 -30
 - data/test/rubycom/util_test_job.yaml +21 -0
 - data/test/rubycom/util_test_module.rb +8 -1
 - data/test/rubycom/util_test_no_singleton.rb +9 -9
 - metadata +5 -3
 
    
        data/README.md
    CHANGED
    
    | 
         @@ -21,6 +21,89 @@ by simply including Rubycom at the bottom. 
     | 
|
| 
       21 
21 
     | 
    
         
             
            * Command consoles can be built up by including other modules before including Rubycom.
         
     | 
| 
       22 
22 
     | 
    
         
             
            * Included modules become commands, their public singleton methods become sub-commands.
         
     | 
| 
       23 
23 
     | 
    
         | 
| 
      
 24 
     | 
    
         
            +
            Usage
         
     | 
| 
      
 25 
     | 
    
         
            +
            ---------------
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
            Write your module of methods, document them as you normally would. `include Rubycom` at the bottom.
         
     | 
| 
      
 28 
     | 
    
         
            +
            Optionally `#!/usr/bin/env ruby` at the top.
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
            Now any singleton methods `def self.method_name` will be available to call from the terminal.
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
            Calling `ruby ./path/to/module.rb <command_name>` will automatically discover and run your `<command_name>` singleton method.
         
     | 
| 
      
 33 
     | 
    
         
            +
            If no method is found by the given name, a usage print out will be given including a summary of each command available
         
     | 
| 
      
 34 
     | 
    
         
            +
            and it's description from the corresponding method's comments.
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
            Calling a valid command with incorrect arguments will produce a usage print out for the matched method.
         
     | 
| 
      
 37 
     | 
    
         
            +
            Rubycom will include as much documentation on the command line as you provide in your method comments. Currently Rubycom
         
     | 
| 
      
 38 
     | 
    
         
            +
            only handles @param and @return annotation style comments for discovering the method comments regarding params and return values.
         
     | 
| 
      
 39 
     | 
    
         
            +
            All other commentary will be included as part of the command description. In the absence of @param or @return comments,
         
     | 
| 
      
 40 
     | 
    
         
            +
            Rubycom will also leave off the corresponding Param: and Return: markers in the usage output.
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
            #####Special commands
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
            | Command | Description | Options |
         
     | 
| 
      
 45 
     | 
    
         
            +
            | ------- |:-----------:| -------:|
         
     | 
| 
      
 46 
     | 
    
         
            +
            | `ruby ./path/to/module.rb help [command_name]` | Will print out usage for the module or optionally the specified command.||
         
     | 
| 
      
 47 
     | 
    
         
            +
            | `ruby ./path/to/module.rb job </path/to/job.yaml>` | Runs the specified job file. See: "Jobs" below. | `--test` Prints the steps and context without running the commands. |
         
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
            ###Arguments
         
     | 
| 
      
 51 
     | 
    
         
            +
             
     | 
| 
      
 52 
     | 
    
         
            +
            * Arguments are automatically parsed from the command line using Ruby's core Yaml module.
         
     | 
| 
      
 53 
     | 
    
         
            +
            * Arguments will be passed to your method in order of their appearance on the command line.
         
     | 
| 
      
 54 
     | 
    
         
            +
            * If you specify a default value for a parameter in your method, then Rubycom will look for a named argument matching
         
     | 
| 
      
 55 
     | 
    
         
            +
                the parameter's name.
         
     | 
| 
      
 56 
     | 
    
         
            +
            * Users may call out option parameters in any order using `--<param_name>=<value>` or `--<param_name> <value>`
         
     | 
| 
      
 57 
     | 
    
         
            +
                * Currently Rubycom does not yet support sort names for optional parameters so specifying `-<param_name>`
         
     | 
| 
      
 58 
     | 
    
         
            +
                    is equivalent to `--<param_name>`
         
     | 
| 
      
 59 
     | 
    
         
            +
            * In the absence of a named option, any optional parameters still unfilled will be filled by unnamed arguments in
         
     | 
| 
      
 60 
     | 
    
         
            +
                order of appearance.
         
     | 
| 
      
 61 
     | 
    
         
            +
            * Optional parameters which do not get overridden either by a named option specification or an available unnamed
         
     | 
| 
      
 62 
     | 
    
         
            +
                argument will be filled by their default as usual.
         
     | 
| 
      
 63 
     | 
    
         
            +
            * If a rest parameter `*param_name` is defined in the method being called, any remaining arguments will be passed to the
         
     | 
| 
      
 64 
     | 
    
         
            +
                rest parameter after the required and optional parameters are filled.
         
     | 
| 
      
 65 
     | 
    
         
            +
             
     | 
| 
      
 66 
     | 
    
         
            +
            ###Jobs
         
     | 
| 
      
 67 
     | 
    
         
            +
             
     | 
| 
      
 68 
     | 
    
         
            +
            Jobs are a higher order orchestration mechanism for command line utilities. Rubycom provides a simple job runner to every
         
     | 
| 
      
 69 
     | 
    
         
            +
            command line utility. by calling `ruby ./path/to/module.rb job </path/to/job.yaml>` with a valid job yaml. Rubycom will
         
     | 
| 
      
 70 
     | 
    
         
            +
            run your job.
         
     | 
| 
      
 71 
     | 
    
         
            +
             
     | 
| 
      
 72 
     | 
    
         
            +
            * A valid job file is a Yaml file which specifies a `steps` node and any number of valid numbered child nodes
         
     | 
| 
      
 73 
     | 
    
         
            +
            * Optionally, an `env` node may specified.
         
     | 
| 
      
 74 
     | 
    
         
            +
                * If specified, `env` should include child nodes which are `key: value` pairs Ex: `working_dir: ./test/rubycom`
         
     | 
| 
      
 75 
     | 
    
         
            +
                * If an `env` is specified, values may be inserted into commands in the `steps` node as such: `env['key']`
         
     | 
| 
      
 76 
     | 
    
         
            +
                     * Ex: `ruby env[working_dir]/util_test_composite.rb test_composite_command env[test_msg]`
         
     | 
| 
      
 77 
     | 
    
         
            +
            * A valid `steps` child node is a numbered node `1:` with a `cmd:` child node and optionally several context `desc:`
         
     | 
| 
      
 78 
     | 
    
         
            +
                child nodes.
         
     | 
| 
      
 79 
     | 
    
         
            +
            * A `cmd:` node should specify the command string to run. Ex: `cmd: ls ./test_folder`
         
     | 
| 
      
 80 
     | 
    
         
            +
            * A context node should specify some text to be placed with the node's key in a formatted
         
     | 
| 
      
 81 
     | 
    
         
            +
                logging context Ex: `desc: Run test_composite_command`
         
     | 
| 
      
 82 
     | 
    
         
            +
             
     | 
| 
      
 83 
     | 
    
         
            +
            Below is an example job file which demonstrates the format Rubycom supports.
         
     | 
| 
      
 84 
     | 
    
         
            +
             
     | 
| 
      
 85 
     | 
    
         
            +
                ---
         
     | 
| 
      
 86 
     | 
    
         
            +
                env:
         
     | 
| 
      
 87 
     | 
    
         
            +
                  test_msg: Hello World
         
     | 
| 
      
 88 
     | 
    
         
            +
                  test_arg: 123
         
     | 
| 
      
 89 
     | 
    
         
            +
                  working_dir: ./test/rubycom
         
     | 
| 
      
 90 
     | 
    
         
            +
                steps:
         
     | 
| 
      
 91 
     | 
    
         
            +
                  1:
         
     | 
| 
      
 92 
     | 
    
         
            +
                    desc: Run test_composite_command with environment variable
         
     | 
| 
      
 93 
     | 
    
         
            +
                    cmd: ruby env[working_dir]/util_test_composite.rb test_composite_command env[test_msg]
         
     | 
| 
      
 94 
     | 
    
         
            +
                  2:
         
     | 
| 
      
 95 
     | 
    
         
            +
                    Var: Run UtilTestModule/test_command_options_arr with environment variable
         
     | 
| 
      
 96 
     | 
    
         
            +
                    cmd: ruby env[working_dir]/util_test_composite.rb UtilTestModule test_command_options_arr '["Hello World", world2]'
         
     | 
| 
      
 97 
     | 
    
         
            +
                  3:
         
     | 
| 
      
 98 
     | 
    
         
            +
                    Context: Run test_command_with_args with environment variable
         
     | 
| 
      
 99 
     | 
    
         
            +
                    cmd: ruby env[working_dir]/util_test_module.rb test_command_with_args env[test_msg] env[test_arg]
         
     | 
| 
      
 100 
     | 
    
         
            +
                  4:
         
     | 
| 
      
 101 
     | 
    
         
            +
                    Cmd: Run ls for arbitrary command support
         
     | 
| 
      
 102 
     | 
    
         
            +
                    cmd: ls
         
     | 
| 
      
 103 
     | 
    
         
            +
                  5:
         
     | 
| 
      
 104 
     | 
    
         
            +
                    Arbitrary_Context: Run ls with environment variable
         
     | 
| 
      
 105 
     | 
    
         
            +
                    cmd: ls env[working_dir]
         
     | 
| 
      
 106 
     | 
    
         
            +
             
     | 
| 
       24 
107 
     | 
    
         | 
| 
       25 
108 
     | 
    
         
             
            Raison d'etre
         
     | 
| 
       26 
109 
     | 
    
         
             
            ---------------
         
     | 
| 
         @@ -53,9 +136,7 @@ The result is a function library which can be consumed easily from other classes 
     | 
|
| 
       53 
136 
     | 
    
         | 
| 
       54 
137 
     | 
    
         
             
            Coming Soon
         
     | 
| 
       55 
138 
     | 
    
         
             
            ---------------
         
     | 
| 
       56 
     | 
    
         
            -
            *  
     | 
| 
       57 
     | 
    
         
            -
            * Job help/usage output will include descriptions from command for each step
         
     | 
| 
       58 
     | 
    
         
            -
            * Build a job yaml by running each command in sequence with a special option --job_add <path_to_yaml>
         
     | 
| 
      
 139 
     | 
    
         
            +
            * Build a job yaml by running each command in sequence with a special option --job_add <path_to_yaml>[:step_number]
         
     | 
| 
       59 
140 
     | 
    
         
             
            * Edit job files from the command line using special options.
         
     | 
| 
       60 
     | 
    
         
            -
                * --job_update <path_to_yaml>
         
     | 
| 
       61 
     | 
    
         
            -
                * -- 
     | 
| 
      
 141 
     | 
    
         
            +
                * --job_update <path_to_yaml>[:step_number]
         
     | 
| 
      
 142 
     | 
    
         
            +
                * --job_remove <path_to_yaml>[:step_number]
         
     | 
    
        data/Rakefile
    CHANGED
    
    | 
         @@ -1,8 +1,14 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            require " 
     | 
| 
       2 
     | 
    
         
            -
            require 'rake/testtask'
         
     | 
| 
      
 1 
     | 
    
         
            +
            require "#{File.expand_path(File.dirname(__FILE__))}/lib/rubycom/version.rb"
         
     | 
| 
       3 
2 
     | 
    
         
             
            require 'yard'
         
     | 
| 
       4 
3 
     | 
    
         | 
| 
       5 
     | 
    
         
            -
            task :default => [: 
     | 
| 
      
 4 
     | 
    
         
            +
            task :default => [:package]
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            task :clean do
         
     | 
| 
      
 7 
     | 
    
         
            +
              FileUtils.rm_rf('./doc')
         
     | 
| 
      
 8 
     | 
    
         
            +
              FileUtils.rm_rf('./.yardoc')
         
     | 
| 
      
 9 
     | 
    
         
            +
              FileUtils.rm_rf('./pkg')
         
     | 
| 
      
 10 
     | 
    
         
            +
              FileUtils.rm(Dir.glob('./rubycom-*.gem'))
         
     | 
| 
      
 11 
     | 
    
         
            +
            end
         
     | 
| 
       6 
12 
     | 
    
         | 
| 
       7 
13 
     | 
    
         
             
            task :test do
         
     | 
| 
       8 
14 
     | 
    
         
             
              test_files = Dir.glob("**/test/*/test_*.rb")
         
     | 
| 
         @@ -14,7 +20,7 @@ end 
     | 
|
| 
       14 
20 
     | 
    
         | 
| 
       15 
21 
     | 
    
         
             
            YARD::Rake::YardocTask.new
         
     | 
| 
       16 
22 
     | 
    
         | 
| 
       17 
     | 
    
         
            -
            task :package => [:test, :yard] do
         
     | 
| 
      
 23 
     | 
    
         
            +
            task :package => [:clean, :test, :yard] do
         
     | 
| 
       18 
24 
     | 
    
         
             
              gem_specs = Dir.glob("**/*.gemspec")
         
     | 
| 
       19 
25 
     | 
    
         
             
              gem_specs.each { |gem_spec|
         
     | 
| 
       20 
26 
     | 
    
         
             
                system("gem build #{gem_spec}")
         
     | 
| 
         @@ -23,9 +29,9 @@ task :package => [:test, :yard] do 
     | 
|
| 
       23 
29 
     | 
    
         
             
            end
         
     | 
| 
       24 
30 
     | 
    
         | 
| 
       25 
31 
     | 
    
         
             
            task :install => :package do
         
     | 
| 
       26 
     | 
    
         
            -
              system 
     | 
| 
      
 32 
     | 
    
         
            +
              system("gem install rubycom-#{Rubycom::VERSION}")
         
     | 
| 
       27 
33 
     | 
    
         
             
            end
         
     | 
| 
       28 
34 
     | 
    
         | 
| 
       29 
35 
     | 
    
         
             
            task :release => :package do
         
     | 
| 
       30 
     | 
    
         
            -
              system 
     | 
| 
      
 36 
     | 
    
         
            +
              system("gem push ./rubycom-#{Rubycom::VERSION}.gem")
         
     | 
| 
       31 
37 
     | 
    
         
             
            end
         
     | 
    
        data/lib/rubycom/version.rb
    CHANGED
    
    
    
        data/lib/rubycom.rb
    CHANGED
    
    | 
         @@ -1,5 +1,6 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            require "#{File.expand_path(File.dirname(__FILE__))}/rubycom/version.rb"
         
     | 
| 
       2 
2 
     | 
    
         
             
            require 'yaml'
         
     | 
| 
      
 3 
     | 
    
         
            +
            require 'find'
         
     | 
| 
       3 
4 
     | 
    
         
             
            require 'method_source'
         
     | 
| 
       4 
5 
     | 
    
         | 
| 
       5 
6 
     | 
    
         
             
            # Upon inclusion in another Module, Rubycom will attempt to call a method in the including module by parsing
         
     | 
| 
         @@ -8,7 +9,8 @@ require 'method_source' 
     | 
|
| 
       8 
9 
     | 
    
         
             
            # If a Method match can not be made, Rubycom will print help instead by parsing source comments from the including
         
     | 
| 
       9 
10 
     | 
    
         
             
            # module or it's included modules.
         
     | 
| 
       10 
11 
     | 
    
         
             
            module Rubycom
         
     | 
| 
       11 
     | 
    
         
            -
              class CLIError < StandardError; 
     | 
| 
      
 12 
     | 
    
         
            +
              class CLIError < StandardError;
         
     | 
| 
      
 13 
     | 
    
         
            +
              end
         
     | 
| 
       12 
14 
     | 
    
         | 
| 
       13 
15 
     | 
    
         
             
              # Detects that Rubycom was included in another module and calls Rubycom#run
         
     | 
| 
       14 
16 
     | 
    
         
             
              #
         
     | 
| 
         @@ -44,6 +46,36 @@ module Rubycom 
     | 
|
| 
       44 
46 
     | 
    
         
             
                      puts cmd_usage
         
     | 
| 
       45 
47 
     | 
    
         
             
                      return cmd_usage
         
     | 
| 
       46 
48 
     | 
    
         
             
                    end
         
     | 
| 
      
 49 
     | 
    
         
            +
                  elsif command == 'job'
         
     | 
| 
      
 50 
     | 
    
         
            +
                    begin
         
     | 
| 
      
 51 
     | 
    
         
            +
                      raise CLIError, 'No job specified' if arguments[0].nil? || arguments[0].empty?
         
     | 
| 
      
 52 
     | 
    
         
            +
                      job_hash = YAML.load_file(arguments[0])
         
     | 
| 
      
 53 
     | 
    
         
            +
                      STDOUT.sync = true
         
     | 
| 
      
 54 
     | 
    
         
            +
                      if arguments.delete('-test') || arguments.delete('--test')
         
     | 
| 
      
 55 
     | 
    
         
            +
                        puts "[Test Job #{arguments[0]}]"
         
     | 
| 
      
 56 
     | 
    
         
            +
                        job_hash['steps'].each { |step, step_hash|
         
     | 
| 
      
 57 
     | 
    
         
            +
                          step = "[Step: #{step}/#{job_hash['steps'].length}]"
         
     | 
| 
      
 58 
     | 
    
         
            +
                          context = step_hash.select{|key| key!="cmd"}.map{|key,val| "[#{key}: #{val}]"}.join(' ')
         
     | 
| 
      
 59 
     | 
    
         
            +
                          env = job_hash['env'] || {}
         
     | 
| 
      
 60 
     | 
    
         
            +
                          env.map { |key, val| step_hash['cmd'].gsub!("env[#{key}]", "#{((val.class == String)&&(val.match(/\w+/))) ? "\"#{val}\"" : val}") }
         
     | 
| 
      
 61 
     | 
    
         
            +
                          cmd = "[cmd: #{step_hash['cmd']}]"
         
     | 
| 
      
 62 
     | 
    
         
            +
                          puts "#{[step,context,cmd].join(' ')}"
         
     | 
| 
      
 63 
     | 
    
         
            +
                        }
         
     | 
| 
      
 64 
     | 
    
         
            +
                      else
         
     | 
| 
      
 65 
     | 
    
         
            +
                        puts "[Job #{arguments[0]}]"
         
     | 
| 
      
 66 
     | 
    
         
            +
                        job_hash['steps'].each { |step, step_hash|
         
     | 
| 
      
 67 
     | 
    
         
            +
                          step = "[Step: #{step}/#{job_hash['steps'].length}]"
         
     | 
| 
      
 68 
     | 
    
         
            +
                          context = step_hash.select{|key| key!="cmd"}.map{|key,val| "[#{key}: #{val}]"}.join(' ')
         
     | 
| 
      
 69 
     | 
    
         
            +
                          env = job_hash['env'] || {}
         
     | 
| 
      
 70 
     | 
    
         
            +
                          env.map { |key, val| step_hash['cmd'].gsub!("env[#{key}]", "#{((val.class == String)&&(val.match(/\w+/))) ? "\"#{val}\"" : val}") }
         
     | 
| 
      
 71 
     | 
    
         
            +
                          cmd = "[cmd: #{step_hash['cmd']}]"
         
     | 
| 
      
 72 
     | 
    
         
            +
                          puts "#{[step,context,cmd].join(' ')}"
         
     | 
| 
      
 73 
     | 
    
         
            +
                          system(step_hash['cmd'])
         
     | 
| 
      
 74 
     | 
    
         
            +
                        }
         
     | 
| 
      
 75 
     | 
    
         
            +
                      end
         
     | 
| 
      
 76 
     | 
    
         
            +
                    rescue CLIError => e
         
     | 
| 
      
 77 
     | 
    
         
            +
                      $stderr.puts e
         
     | 
| 
      
 78 
     | 
    
         
            +
                    end
         
     | 
| 
       47 
79 
     | 
    
         
             
                  else
         
     | 
| 
       48 
80 
     | 
    
         
             
                    output = self.run_command(base, command, arguments)
         
     | 
| 
       49 
81 
     | 
    
         
             
                    std_output = nil
         
     | 
| 
         @@ -53,7 +85,8 @@ module Rubycom 
     | 
|
| 
       53 
85 
     | 
    
         
             
                  end
         
     | 
| 
       54 
86 
     | 
    
         | 
| 
       55 
87 
     | 
    
         
             
                rescue CLIError => e
         
     | 
| 
       56 
     | 
    
         
            -
                   
     | 
| 
      
 88 
     | 
    
         
            +
                  $stderr.puts e
         
     | 
| 
      
 89 
     | 
    
         
            +
                  $stderr.puts self.get_summary(base)
         
     | 
| 
       57 
90 
     | 
    
         
             
                end
         
     | 
| 
       58 
91 
     | 
    
         
             
              end
         
     | 
| 
       59 
92 
     | 
    
         | 
| 
         @@ -64,36 +97,20 @@ module Rubycom 
     | 
|
| 
       64 
97 
     | 
    
         
             
              # @param [Array] arguments a String Array representing the arguments for the given command
         
     | 
| 
       65 
98 
     | 
    
         
             
              def self.run_command(base, command, arguments=[])
         
     | 
| 
       66 
99 
     | 
    
         
             
                raise CLIError, 'No command specified.' if command.nil? || command.length == 0
         
     | 
| 
       67 
     | 
    
         
            -
                 
     | 
| 
       68 
     | 
    
         
            -
             
     | 
| 
       69 
     | 
    
         
            -
             
     | 
| 
       70 
     | 
    
         
            -
             
     | 
| 
       71 
     | 
    
         
            -
                  self.run_command(eval(command), arguments[0], arguments[1..-1])
         
     | 
| 
       72 
     | 
    
         
            -
                else
         
     | 
| 
       73 
     | 
    
         
            -
                  method = base.public_method(command_sym)
         
     | 
| 
       74 
     | 
    
         
            -
                  raise CLIError, "No public method found for symbol: #{command_sym}" if method.nil?
         
     | 
| 
       75 
     | 
    
         
            -
                  parameters = self.get_param_definitions(method)
         
     | 
| 
       76 
     | 
    
         
            -
                  params_hash = self.parse_arguments(parameters, arguments)
         
     | 
| 
       77 
     | 
    
         
            -
                  params = []
         
     | 
| 
       78 
     | 
    
         
            -
                  method.parameters.each { |type, name|
         
     | 
| 
       79 
     | 
    
         
            -
                    if type == :rest
         
     | 
| 
       80 
     | 
    
         
            -
                      if params_hash[name].class == Array
         
     | 
| 
       81 
     | 
    
         
            -
                        params_hash[name].each { |arg|
         
     | 
| 
       82 
     | 
    
         
            -
                          params << arg
         
     | 
| 
       83 
     | 
    
         
            -
                        }
         
     | 
| 
       84 
     | 
    
         
            -
                      else
         
     | 
| 
       85 
     | 
    
         
            -
                        params << params_hash[name]
         
     | 
| 
       86 
     | 
    
         
            -
                      end
         
     | 
| 
       87 
     | 
    
         
            -
                    else
         
     | 
| 
       88 
     | 
    
         
            -
                      params << params_hash[name]
         
     | 
| 
       89 
     | 
    
         
            -
                    end
         
     | 
| 
       90 
     | 
    
         
            -
                  }
         
     | 
| 
       91 
     | 
    
         
            -
                  if arguments.nil? || arguments.empty?
         
     | 
| 
       92 
     | 
    
         
            -
                    output = method.call
         
     | 
| 
      
 100 
     | 
    
         
            +
                begin
         
     | 
| 
      
 101 
     | 
    
         
            +
                  raise CLIError, "Invalid Command: #{command}" unless self.get_top_level_commands(base).include? command.to_sym
         
     | 
| 
      
 102 
     | 
    
         
            +
                  if base.included_modules.map { |mod| mod.name.to_sym }.include?(command.to_sym)
         
     | 
| 
      
 103 
     | 
    
         
            +
                    self.run_command(eval(command), arguments[0], arguments[1..-1])
         
     | 
| 
       93 
104 
     | 
    
         
             
                  else
         
     | 
| 
       94 
     | 
    
         
            -
                     
     | 
| 
      
 105 
     | 
    
         
            +
                    method = base.public_method(command.to_sym)
         
     | 
| 
      
 106 
     | 
    
         
            +
                    raise CLIError, "No public method found for symbol: #{command.to_sym}" if method.nil?
         
     | 
| 
      
 107 
     | 
    
         
            +
                    param_defs = self.get_param_definitions(method)
         
     | 
| 
      
 108 
     | 
    
         
            +
                    args = self.parse_arguments(param_defs, arguments)
         
     | 
| 
      
 109 
     | 
    
         
            +
                    (arguments.nil? || arguments.empty?) ? method.call : method.call(*method.parameters.map { |arr| args[arr[1]]}.flatten)
         
     | 
| 
       95 
110 
     | 
    
         
             
                  end
         
     | 
| 
       96 
     | 
    
         
            -
             
     | 
| 
      
 111 
     | 
    
         
            +
                rescue CLIError => e
         
     | 
| 
      
 112 
     | 
    
         
            +
                  $stderr.puts e
         
     | 
| 
      
 113 
     | 
    
         
            +
                  $stderr.puts self.get_command_usage(base, command, arguments)
         
     | 
| 
       97 
114 
     | 
    
         
             
                end
         
     | 
| 
       98 
115 
     | 
    
         
             
              end
         
     | 
| 
       99 
116 
     | 
    
         | 
| 
         @@ -107,58 +124,32 @@ module Rubycom 
     | 
|
| 
       107 
124 
     | 
    
         
             
              # @param [Array] arguments an Array of Strings representing the arguments to be parsed
         
     | 
| 
       108 
125 
     | 
    
         
             
              # @return [Hash] a Hash mapping the defined parameters to their matching argument values
         
     | 
| 
       109 
126 
     | 
    
         
             
              def self.parse_arguments(parameters={}, arguments=[])
         
     | 
| 
       110 
     | 
    
         
            -
                 
     | 
| 
       111 
     | 
    
         
            -
                 
     | 
| 
       112 
     | 
    
         
            -
                 
     | 
| 
       113 
     | 
    
         
            -
                 
     | 
| 
       114 
     | 
    
         
            -
                 
     | 
| 
       115 
     | 
    
         
            -
                parameters.each_value { |def_hash|
         
     | 
| 
       116 
     | 
    
         
            -
                  req_l += 1 if def_hash[:type] == :req
         
     | 
| 
       117 
     | 
    
         
            -
                  opt_l += 1 if def_hash[:type] == :opt
         
     | 
| 
       118 
     | 
    
         
            -
                  has_rest_param = true if def_hash[:type] == :rest
         
     | 
| 
       119 
     | 
    
         
            -
                  def_hash[:default] = self.parse_arg(def_hash[:default])[:arg] unless def_hash[:default] == :nil_rubycom_required_param
         
     | 
| 
       120 
     | 
    
         
            -
                }
         
     | 
| 
       121 
     | 
    
         
            -
                raise CLIError, "Wrong number of arguments. Expected at least #{req_l}, received #{args_l}" if args_l < req_l
         
     | 
| 
       122 
     | 
    
         
            -
                unless has_rest_param
         
     | 
| 
       123 
     | 
    
         
            -
                  raise CLIError, "Wrong number of arguments. Expected at most #{req_l + opt_l}, received #{args_l}" if args_l > (req_l + opt_l)
         
     | 
| 
       124 
     | 
    
         
            -
                end
         
     | 
| 
       125 
     | 
    
         
            -
             
     | 
| 
       126 
     | 
    
         
            -
                args = []
         
     | 
| 
       127 
     | 
    
         
            -
                arguments.each { |arg|
         
     | 
| 
       128 
     | 
    
         
            -
                  args << self.parse_arg(arg)
         
     | 
| 
       129 
     | 
    
         
            -
                }
         
     | 
| 
      
 127 
     | 
    
         
            +
                raise CLIError, 'parameters may not be nil' if parameters.nil?
         
     | 
| 
      
 128 
     | 
    
         
            +
                raise CLIError, 'arguments may not be nil' if arguments.nil?
         
     | 
| 
      
 129 
     | 
    
         
            +
                types = parameters.values.group_by { |hsh| hsh[:type] }.map { |type, defs_arr| Hash[type, defs_arr.length] }.reduce(&:merge) || {}
         
     | 
| 
      
 130 
     | 
    
         
            +
                raise CLIError, "Wrong number of arguments. Expected at least #{types[:req]}, received #{arguments.length}" if arguments.length < (types[:req]||0)
         
     | 
| 
      
 131 
     | 
    
         
            +
                raise CLIError, "Wrong number of arguments. Expected at most #{(types[:req]||0) + (types[:opt]||0)}, received #{arguments.length}" if types[:rest].nil? && (arguments.length > ((types[:req]||0) + (types[:opt]||0)))
         
     | 
| 
       130 
132 
     | 
    
         | 
| 
       131 
     | 
    
         
            -
                 
     | 
| 
       132 
     | 
    
         
            -
             
     | 
| 
       133 
     | 
    
         
            -
                 
     | 
| 
       134 
     | 
    
         
            -
                   
     | 
| 
       135 
     | 
    
         
            -
             
     | 
| 
       136 
     | 
    
         
            -
                   
     | 
| 
       137 
     | 
    
         
            -
             
     | 
| 
       138 
     | 
    
         
            -
                  else
         
     | 
| 
       139 
     | 
    
         
            -
                    parsed_options[key]=val
         
     | 
| 
       140 
     | 
    
         
            -
                  end
         
     | 
| 
       141 
     | 
    
         
            -
                }
         
     | 
| 
      
 133 
     | 
    
         
            +
                sorted_args = arguments.map { |arg|
         
     | 
| 
      
 134 
     | 
    
         
            +
                  Rubycom.parse_arg(arg)
         
     | 
| 
      
 135 
     | 
    
         
            +
                }.group_by { |hsh|
         
     | 
| 
      
 136 
     | 
    
         
            +
                  hsh.keys.first
         
     | 
| 
      
 137 
     | 
    
         
            +
                }.map { |key, arr|
         
     | 
| 
      
 138 
     | 
    
         
            +
                  (key == :rubycom_non_opt_arg) ? Hash[key, arr.map { |hsh| hsh.values }.flatten] : Hash[key, arr.map { |hsh| hsh.values.first }.reduce(&:merge)]
         
     | 
| 
      
 139 
     | 
    
         
            +
                }.reduce(&:merge) || {}
         
     | 
| 
       142 
140 
     | 
    
         | 
| 
       143 
     | 
    
         
            -
                 
     | 
| 
       144 
     | 
    
         
            -
                parameters.each { |param_name, def_hash|
         
     | 
| 
      
 141 
     | 
    
         
            +
                parameters.map { |param_sym, def_hash|
         
     | 
| 
       145 
142 
     | 
    
         
             
                  if def_hash[:type] == :req
         
     | 
| 
       146 
     | 
    
         
            -
                    raise CLIError, "No argument available for #{ 
     | 
| 
       147 
     | 
    
         
            -
                     
     | 
| 
      
 143 
     | 
    
         
            +
                    raise CLIError, "No argument available for #{param_sym}" if sorted_args[:rubycom_non_opt_arg].nil? || sorted_args[:rubycom_non_opt_arg].length == 0
         
     | 
| 
      
 144 
     | 
    
         
            +
                    Hash[param_sym, sorted_args[:rubycom_non_opt_arg].shift]
         
     | 
| 
       148 
145 
     | 
    
         
             
                  elsif def_hash[:type] == :opt
         
     | 
| 
       149 
     | 
    
         
            -
                     
     | 
| 
       150 
     | 
    
         
            -
                    result_hash[param_name] = parsed_args.shift if result_hash[param_name].nil?
         
     | 
| 
       151 
     | 
    
         
            -
                    result_hash[param_name] = parameters[param_name][:default] if result_hash[param_name].nil?
         
     | 
| 
      
 146 
     | 
    
         
            +
                    Hash[param_sym, ((sorted_args[param_sym]) ? sorted_args[param_sym] : ((sorted_args[:rubycom_non_opt_arg].shift || parameters[param_sym][:default]) rescue parameters[param_sym][:default]))]
         
     | 
| 
       152 
147 
     | 
    
         
             
                  elsif def_hash[:type] == :rest
         
     | 
| 
       153 
     | 
    
         
            -
                     
     | 
| 
       154 
     | 
    
         
            -
             
     | 
| 
       155 
     | 
    
         
            -
             
     | 
| 
       156 
     | 
    
         
            -
                    else
         
     | 
| 
       157 
     | 
    
         
            -
                      result_hash[param_name] = parsed_options[param_name]
         
     | 
| 
       158 
     | 
    
         
            -
                    end
         
     | 
| 
      
 148 
     | 
    
         
            +
                    ret = Hash[param_sym, ((sorted_args[param_sym]) ? sorted_args[param_sym] : sorted_args[:rubycom_non_opt_arg])]
         
     | 
| 
      
 149 
     | 
    
         
            +
                    sorted_args[:rubycom_non_opt_arg] = []
         
     | 
| 
      
 150 
     | 
    
         
            +
                    ret
         
     | 
| 
       159 
151 
     | 
    
         
             
                  end
         
     | 
| 
       160 
     | 
    
         
            -
                }
         
     | 
| 
       161 
     | 
    
         
            -
                result_hash
         
     | 
| 
      
 152 
     | 
    
         
            +
                }.reduce(&:merge)
         
     | 
| 
       162 
153 
     | 
    
         
             
              end
         
     | 
| 
       163 
154 
     | 
    
         | 
| 
       164 
155 
     | 
    
         
             
              # Uses YAML.load to parse the given String
         
     | 
| 
         @@ -166,41 +157,19 @@ module Rubycom 
     | 
|
| 
       166 
157 
     | 
    
         
             
              # @param [String] arg a String representing the argument to be parsed
         
     | 
| 
       167 
158 
     | 
    
         
             
              # @return [Object] the result of parsing the given arg with YAML.load
         
     | 
| 
       168 
159 
     | 
    
         
             
              def self.parse_arg(arg)
         
     | 
| 
       169 
     | 
    
         
            -
                 
     | 
| 
       170 
     | 
    
         
            -
                 
     | 
| 
       171 
     | 
    
         
            -
             
     | 
| 
       172 
     | 
    
         
            -
                 
     | 
| 
       173 
     | 
    
         
            -
             
     | 
| 
       174 
     | 
    
         
            -
             
     | 
| 
       175 
     | 
    
         
            -
                   
     | 
| 
       176 
     | 
    
         
            -
                     
     | 
| 
       177 
     | 
    
         
            -
             
     | 
| 
       178 
     | 
    
         
            -
                   
     | 
| 
       179 
     | 
    
         
            -
                    if arg.match(/^--/) != nil
         
     | 
| 
       180 
     | 
    
         
            -
                      arg = arg.reverse.chomp('--').reverse
         
     | 
| 
       181 
     | 
    
         
            -
                    elsif arg.match(/^-/) != nil
         
     | 
| 
       182 
     | 
    
         
            -
                      arg = arg.reverse.chomp('-').reverse
         
     | 
| 
       183 
     | 
    
         
            -
                    end
         
     | 
| 
       184 
     | 
    
         
            -
             
     | 
| 
       185 
     | 
    
         
            -
                    if arg.match(/^\w+=/) != nil
         
     | 
| 
       186 
     | 
    
         
            -
                      arg_arr = arg.split('=')
         
     | 
| 
       187 
     | 
    
         
            -
                      param_name = arg_arr.shift.strip
         
     | 
| 
       188 
     | 
    
         
            -
                      arg_val = arg_arr.join('=').lstrip
         
     | 
| 
       189 
     | 
    
         
            -
                    elsif arg.match(/^\w+\s+\S+/) != nil
         
     | 
| 
       190 
     | 
    
         
            -
                      arg_arr = arg.split(' ')
         
     | 
| 
       191 
     | 
    
         
            -
                      param_name = arg_arr.shift
         
     | 
| 
       192 
     | 
    
         
            -
                      arg_val = arg_arr.join(' ')
         
     | 
| 
       193 
     | 
    
         
            -
                    end
         
     | 
| 
       194 
     | 
    
         
            -
                  end
         
     | 
| 
       195 
     | 
    
         
            -
                end
         
     | 
| 
       196 
     | 
    
         
            -
             
     | 
| 
       197 
     | 
    
         
            -
                val = YAML.load(arg_val) rescue nil
         
     | 
| 
       198 
     | 
    
         
            -
                if val.nil?
         
     | 
| 
       199 
     | 
    
         
            -
                  result[param_name.to_sym] = "#{arg_val}"
         
     | 
| 
      
 160 
     | 
    
         
            +
                return Hash[:rubycom_non_opt_arg, nil] if arg.nil?
         
     | 
| 
      
 161 
     | 
    
         
            +
                if arg.is_a?(String) && ((arg.match(/^[-]{3,}\w+/) != nil) || ((arg.match(/^[-]{1,}\w+/) == nil) && (arg.match(/^\w+=/) != nil)))
         
     | 
| 
      
 162 
     | 
    
         
            +
                  raise CLIError, "Improper option specification, options must start with one or two dashes. Received: #{arg}"
         
     | 
| 
      
 163 
     | 
    
         
            +
                elsif arg.is_a?(String) && arg.match(/^(-|--)\w+[=|\s]{1}/) != nil
         
     | 
| 
      
 164 
     | 
    
         
            +
                  k, v = arg.partition(/^(-|--)\w+[=|\s]{1}/).select { |part|
         
     | 
| 
      
 165 
     | 
    
         
            +
                    !part.empty?
         
     | 
| 
      
 166 
     | 
    
         
            +
                  }.each_with_index.map { |part, index|
         
     | 
| 
      
 167 
     | 
    
         
            +
                    index == 0 ? part.chomp('=').gsub(/^--/, '').gsub(/^-/, '').strip.to_sym : (YAML.load(part) rescue "#{part}")
         
     | 
| 
      
 168 
     | 
    
         
            +
                  }
         
     | 
| 
      
 169 
     | 
    
         
            +
                  Hash[k, v]
         
     | 
| 
       200 
170 
     | 
    
         
             
                else
         
     | 
| 
       201 
     | 
    
         
            -
                   
     | 
| 
      
 171 
     | 
    
         
            +
                  Hash[:rubycom_non_opt_arg, (YAML.load("#{arg}") rescue "#{arg}")]
         
     | 
| 
       202 
172 
     | 
    
         
             
                end
         
     | 
| 
       203 
     | 
    
         
            -
                result
         
     | 
| 
       204 
173 
     | 
    
         
             
              end
         
     | 
| 
       205 
174 
     | 
    
         | 
| 
       206 
175 
     | 
    
         
             
              # Retrieves the summary for each command method in the given Module
         
     | 
| 
         @@ -208,25 +177,13 @@ module Rubycom 
     | 
|
| 
       208 
177 
     | 
    
         
             
              # @param [Module] base the module which invoked 'include Rubycom'
         
     | 
| 
       209 
178 
     | 
    
         
             
              # @return [String] the summary for each command method in the given Module
         
     | 
| 
       210 
179 
     | 
    
         
             
              def self.get_summary(base)
         
     | 
| 
       211 
     | 
    
         
            -
                longest_name_length = self.get_longest_command_name(base).length
         
     | 
| 
       212 
180 
     | 
    
         
             
                self.get_top_level_commands(base).each_with_index.map { |sym, index|
         
     | 
| 
       213 
     | 
    
         
            -
                   
     | 
| 
       214 
     | 
    
         
            -
                  if index == 0
         
     | 
| 
       215 
     | 
    
         
            -
                    "Commands:\n" << self.get_command_summary(base, sym, separator)
         
     | 
| 
       216 
     | 
    
         
            -
                  else
         
     | 
| 
       217 
     | 
    
         
            -
                    self.get_command_summary(base, sym, separator)
         
     | 
| 
       218 
     | 
    
         
            -
                  end
         
     | 
| 
      
 181 
     | 
    
         
            +
                  "#{"Commands:\n" if index == 0}" << self.get_command_summary(base, sym, self.get_separator(sym, self.get_longest_command_name(base).length))
         
     | 
| 
       219 
182 
     | 
    
         
             
                }.reduce(:+) or "No Commands found for #{base}."
         
     | 
| 
       220 
183 
     | 
    
         
             
              end
         
     | 
| 
       221 
184 
     | 
    
         | 
| 
       222 
185 
     | 
    
         
             
              def self.get_separator(sym, spacer_length=0)
         
     | 
| 
       223 
     | 
    
         
            -
                 
     | 
| 
       224 
     | 
    
         
            -
                sep_length = spacer_length - cmd_name.length
         
     | 
| 
       225 
     | 
    
         
            -
                separator = ""
         
     | 
| 
       226 
     | 
    
         
            -
                sep_length.times {
         
     | 
| 
       227 
     | 
    
         
            -
                  separator << " "
         
     | 
| 
       228 
     | 
    
         
            -
                }
         
     | 
| 
       229 
     | 
    
         
            -
                separator << "  -  "
         
     | 
| 
      
 186 
     | 
    
         
            +
                [].unshift(" " * (spacer_length - sym.to_s.length)).join << "  -  "
         
     | 
| 
       230 
187 
     | 
    
         
             
              end
         
     | 
| 
       231 
188 
     | 
    
         | 
| 
       232 
189 
     | 
    
         
             
              # Retrieves the summary for the given command_name
         
     | 
| 
         @@ -238,27 +195,23 @@ module Rubycom 
     | 
|
| 
       238 
195 
     | 
    
         
             
                raise CLIError, "Can not get usage for #{command_name} with base: #{base||"nil"}" if base.nil? || !base.respond_to?(:included_modules)
         
     | 
| 
       239 
196 
     | 
    
         
             
                return 'No command specified.' if command_name.nil? || command_name.length == 0
         
     | 
| 
       240 
197 
     | 
    
         
             
                if base.included_modules.map { |mod| mod.name.to_sym }.include?(command_name.to_sym)
         
     | 
| 
       241 
     | 
    
         
            -
                   
     | 
| 
      
 198 
     | 
    
         
            +
                  mod_const = Kernel.const_get(command_name.to_sym)
         
     | 
| 
      
 199 
     | 
    
         
            +
                  desc = File.read(mod_const.public_method(mod_const.singleton_methods().first).source_location.first).split(//).reduce(""){|str,c|
         
     | 
| 
      
 200 
     | 
    
         
            +
                    unless str.gsub("\n",'').gsub(/\s+/,'').include?("module#{mod_const}")
         
     | 
| 
      
 201 
     | 
    
         
            +
                      str << c
         
     | 
| 
      
 202 
     | 
    
         
            +
                      end
         
     | 
| 
      
 203 
     | 
    
         
            +
                      str
         
     | 
| 
      
 204 
     | 
    
         
            +
                  }.split("\n").select{|line| line.strip.match(/^#/)}.map{|line| line.strip.gsub(/^#+/,'')}.join("\n")
         
     | 
| 
       242 
205 
     | 
    
         
             
                else
         
     | 
| 
       243 
206 
     | 
    
         
             
                  raise CLIError, "Invalid command for #{base}, #{command_name}" unless base.public_methods.include?(command_name.to_sym)
         
     | 
| 
       244 
     | 
    
         
            -
                   
     | 
| 
       245 
     | 
    
         
            -
                  method_doc = self.get_doc(m)
         
     | 
| 
       246 
     | 
    
         
            -
                  desc = method_doc[:desc].join("\n")
         
     | 
| 
      
 207 
     | 
    
         
            +
                  desc = self.get_doc(base.public_method(command_name.to_sym))[:desc].join("\n") rescue nil
         
     | 
| 
       247 
208 
     | 
    
         
             
                end
         
     | 
| 
       248 
209 
     | 
    
         
             
                (desc.nil?||desc=='nil'||desc.length==0) ? "#{command_name}\n" : self.get_formatted_summary(command_name, desc, separator)
         
     | 
| 
       249 
210 
     | 
    
         
             
              end
         
     | 
| 
       250 
211 
     | 
    
         | 
| 
       251 
212 
     | 
    
         
             
              def self.get_formatted_summary(command_name, command_description, separator = '  -  ')
         
     | 
| 
       252 
213 
     | 
    
         
             
                width = 95
         
     | 
| 
       253 
     | 
    
         
            -
                 
     | 
| 
       254 
     | 
    
         
            -
                command_name.to_s.split(//).each {
         
     | 
| 
       255 
     | 
    
         
            -
                  spacer << " "
         
     | 
| 
       256 
     | 
    
         
            -
                }
         
     | 
| 
       257 
     | 
    
         
            -
                sep_space = ""
         
     | 
| 
       258 
     | 
    
         
            -
                separator.split(//).each {
         
     | 
| 
       259 
     | 
    
         
            -
                  sep_space << " "
         
     | 
| 
       260 
     | 
    
         
            -
                }
         
     | 
| 
       261 
     | 
    
         
            -
                prefix = "#{spacer}#{sep_space}"
         
     | 
| 
      
 214 
     | 
    
         
            +
                prefix = command_name.to_s.split(//).map { " " }.join + separator.split(//).map { " " }.join
         
     | 
| 
       262 
215 
     | 
    
         
             
                line_width = width - prefix.length
         
     | 
| 
       263 
216 
     | 
    
         
             
                description_msg = command_description.gsub(/(.{1,#{line_width}})(?: +|$)\n?|(.{#{line_width}})/, "#{prefix}"+'\1\2'+"\n")
         
     | 
| 
       264 
217 
     | 
    
         
             
                "#{command_name}#{separator}#{description_msg.lstrip}"
         
     | 
| 
         @@ -294,17 +247,17 @@ module Rubycom 
     | 
|
| 
       294 
247 
     | 
    
         
             
                  m = base.public_method(command_name.to_sym)
         
     | 
| 
       295 
248 
     | 
    
         
             
                  method_doc = self.get_doc(m)
         
     | 
| 
       296 
249 
     | 
    
         | 
| 
       297 
     | 
    
         
            -
                   
     | 
| 
       298 
     | 
    
         
            -
                   
     | 
| 
       299 
     | 
    
         
            -
                  #{ 
     | 
| 
       300 
     | 
    
         
            -
             
     | 
| 
       301 
     | 
    
         
            -
                   
     | 
| 
       302 
     | 
    
         
            -
             
     | 
| 
       303 
     | 
    
         
            -
                  END
         
     | 
| 
      
 250 
     | 
    
         
            +
                  msg = "Usage: #{m.name} #{self.get_param_usage(m)}\n"
         
     | 
| 
      
 251 
     | 
    
         
            +
                  msg << "#{"Parameters:"}\n" unless m.parameters.empty?
         
     | 
| 
      
 252 
     | 
    
         
            +
                  msg << "#{method_doc[:param].join("\n    ")}\n" unless method_doc[:param].nil?
         
     | 
| 
      
 253 
     | 
    
         
            +
                  msg << "#{"Returns:"}\n"  unless method_doc[:return].nil?
         
     | 
| 
      
 254 
     | 
    
         
            +
                  msg << "#{method_doc[:return].join("\n    ")}\n" unless method_doc[:return].nil?
         
     | 
| 
      
 255 
     | 
    
         
            +
                  msg
         
     | 
| 
       304 
256 
     | 
    
         
             
                end
         
     | 
| 
       305 
257 
     | 
    
         
             
              end
         
     | 
| 
       306 
258 
     | 
    
         | 
| 
       307 
259 
     | 
    
         
             
              def self.get_param_usage(method)
         
     | 
| 
      
 260 
     | 
    
         
            +
                return "" if method.parameters.nil? || method.parameters.empty?
         
     | 
| 
       308 
261 
     | 
    
         
             
                method.parameters.map { |type, param| {type => param}
         
     | 
| 
       309 
262 
     | 
    
         
             
                }.group_by { |entry| entry.keys.first
         
     | 
| 
       310 
263 
     | 
    
         
             
                }.map { |key, val| Hash[key, val.map { |param| param.values.first }]
         
     | 
| 
         @@ -327,35 +280,29 @@ module Rubycom 
     | 
|
| 
       327 
280 
     | 
    
         
             
              # @return [Hash] a Hash representing the given Method's parameters
         
     | 
| 
       328 
281 
     | 
    
         
             
              def self.get_param_definitions(method)
         
     | 
| 
       329 
282 
     | 
    
         
             
                raise CLIError, 'method must be an instance of the Method class' unless method.class == Method
         
     | 
| 
       330 
     | 
    
         
            -
                 
     | 
| 
       331 
     | 
    
         
            -
             
     | 
| 
       332 
     | 
    
         
            -
                 
     | 
| 
       333 
     | 
    
         
            -
             
     | 
| 
       334 
     | 
    
         
            -
                 
     | 
| 
       335 
     | 
    
         
            -
             
     | 
| 
       336 
     | 
    
         
            -
             
     | 
| 
       337 
     | 
    
         
            -
             
     | 
| 
       338 
     | 
    
         
            -
             
     | 
| 
       339 
     | 
    
         
            -
             
     | 
| 
       340 
     | 
    
         
            -
             
     | 
| 
       341 
     | 
    
         
            -
             
     | 
| 
       342 
     | 
    
         
            -
             
     | 
| 
       343 
     | 
    
         
            -
                   
     | 
| 
       344 
     | 
    
         
            -
             
     | 
| 
       345 
     | 
    
         
            -
                    param_definitions[name.to_sym][:default] = param_definitions[name.to_sym][:def].split('=')[1..-1].join('=')
         
     | 
| 
       346 
     | 
    
         
            -
                  else
         
     | 
| 
       347 
     | 
    
         
            -
                    param_definitions[name.to_sym][:default] = :nil_rubycom_required_param
         
     | 
| 
       348 
     | 
    
         
            -
                  end
         
     | 
| 
       349 
     | 
    
         
            -
                }
         
     | 
| 
       350 
     | 
    
         
            -
                param_definitions
         
     | 
| 
      
 283 
     | 
    
         
            +
                method.parameters.map { |param|
         
     | 
| 
      
 284 
     | 
    
         
            +
                  param[1].to_s
         
     | 
| 
      
 285 
     | 
    
         
            +
                }.map { |param_name|
         
     | 
| 
      
 286 
     | 
    
         
            +
                  {param_name.to_sym => method.source.split("\n").select { |line| line.include?(param_name) }.first}
         
     | 
| 
      
 287 
     | 
    
         
            +
                }.map { |param_hash|
         
     | 
| 
      
 288 
     | 
    
         
            +
                  param_def = param_hash.flatten[1].gsub(/(def\s+self\.#{method.name.to_s}|def\s+#{method.name.to_s})/, '').lstrip.chomp.chomp(')').reverse.chomp('(').reverse.split(',').map { |param_n| param_n.lstrip }.select { |candidate| candidate.include?(param_hash.flatten[0].to_s) }.first
         
     | 
| 
      
 289 
     | 
    
         
            +
                  Hash[
         
     | 
| 
      
 290 
     | 
    
         
            +
                      param_hash.flatten[0],
         
     | 
| 
      
 291 
     | 
    
         
            +
                      Hash[
         
     | 
| 
      
 292 
     | 
    
         
            +
                          :def, param_def,
         
     | 
| 
      
 293 
     | 
    
         
            +
                          :type, method.parameters.select { |arr| arr[1] == param_hash.flatten[0] }.flatten[0],
         
     | 
| 
      
 294 
     | 
    
         
            +
                          :default, (param_def.include?('=') ? YAML.load(param_def.split('=')[1..-1].join('=')) : :nil_rubycom_required_param)
         
     | 
| 
      
 295 
     | 
    
         
            +
                      ]
         
     | 
| 
      
 296 
     | 
    
         
            +
                  ]
         
     | 
| 
      
 297 
     | 
    
         
            +
                }.reduce(&:merge) || {}
         
     | 
| 
       351 
298 
     | 
    
         
             
              end
         
     | 
| 
       352 
299 
     | 
    
         | 
| 
       353 
300 
     | 
    
         
             
              # Retrieves the given method's documentation from it's source code.
         
     | 
| 
       354 
301 
     | 
    
         
             
              #
         
     | 
| 
       355 
302 
     | 
    
         
             
              # @param [Method] method the Method who's documentation should be retrieved
         
     | 
| 
       356 
303 
     | 
    
         
             
              # @return [Hash] a Hash representing the given Method's documentation, documentation parsed as follows:
         
     | 
| 
       357 
     | 
    
         
            -
              #                :desc = the first general method comment 
     | 
| 
       358 
     | 
    
         
            -
              #                : 
     | 
| 
      
 304 
     | 
    
         
            +
              #                :desc = the first general method comment lines,
         
     | 
| 
      
 305 
     | 
    
         
            +
              #                :word = each @word comment (i.e.- a line starting with @param will be saved as :param => ["line"])
         
     | 
| 
       359 
306 
     | 
    
         
             
              def self.get_doc(method)
         
     | 
| 
       360 
307 
     | 
    
         
             
                method.comment.split("\n").map { |line|
         
     | 
| 
       361 
308 
     | 
    
         
             
                  line.gsub(/#\s*/, '') }.group_by { |doc|
         
     | 
| 
         @@ -382,17 +329,13 @@ module Rubycom 
     | 
|
| 
       382 
329 
     | 
    
         
             
              # @return [Hash] a Hash of Symbols representing the command methods in the given base and it's included modules (if all=true)
         
     | 
| 
       383 
330 
     | 
    
         
             
              def self.get_commands(base, all=true)
         
     | 
| 
       384 
331 
     | 
    
         
             
                return {} if base.nil? || !base.respond_to?(:singleton_methods) || !base.respond_to?(:included_modules)
         
     | 
| 
       385 
     | 
    
         
            -
                excluded_commands = [:included, :extended]
         
     | 
| 
       386 
     | 
    
         
            -
                excluded_modules = [:Rubycom]
         
     | 
| 
       387 
332 
     | 
    
         
             
                {
         
     | 
| 
       388 
333 
     | 
    
         
             
                    base.name.to_sym => {
         
     | 
| 
       389 
     | 
    
         
            -
                        commands: base.singleton_methods(true).select { |sym| ! 
     | 
| 
       390 
     | 
    
         
            -
                        inclusions: base.included_modules.select { |mod| 
     | 
| 
       391 
     | 
    
         
            -
                           
     | 
| 
       392 
     | 
    
         
            -
             
     | 
| 
       393 
     | 
    
         
            -
                           
     | 
| 
       394 
     | 
    
         
            -
                            mod.name.to_sym
         
     | 
| 
       395 
     | 
    
         
            -
                          end
         
     | 
| 
      
 334 
     | 
    
         
            +
                        commands: base.singleton_methods(true).select { |sym| ![:included, :extended].include?(sym) },
         
     | 
| 
      
 335 
     | 
    
         
            +
                        inclusions: base.included_modules.select { |mod|
         
     | 
| 
      
 336 
     | 
    
         
            +
                          ![:Rubycom].include?(mod.name.to_sym)
         
     | 
| 
      
 337 
     | 
    
         
            +
                        }.map { |mod|
         
     | 
| 
      
 338 
     | 
    
         
            +
                          all ? self.get_commands(mod) : mod.name.to_sym
         
     | 
| 
       396 
339 
     | 
    
         
             
                        }
         
     | 
| 
       397 
340 
     | 
    
         
             
                    }
         
     | 
| 
       398 
341 
     | 
    
         
             
                }
         
     | 
    
        data/rubycom.gemspec
    CHANGED
    
    | 
         @@ -7,7 +7,7 @@ Gem::Specification.new do |spec| 
     | 
|
| 
       7 
7 
     | 
    
         
             
              spec.name          = "rubycom"
         
     | 
| 
       8 
8 
     | 
    
         
             
              spec.version       = Rubycom::VERSION
         
     | 
| 
       9 
9 
     | 
    
         
             
              spec.authors       = ["Danny Purcell"]
         
     | 
| 
       10 
     | 
    
         
            -
              spec.email         = [" 
     | 
| 
      
 10 
     | 
    
         
            +
              spec.email         = ["d.purcell.jr+rubycom@gmail.com"]
         
     | 
| 
       11 
11 
     | 
    
         
             
              spec.description   = %q{Allows command-line access for all singleton methods in an including class. Reads Yard style documentation for command line help output. Uses Yaml for parsing options. Allows the user to make a command-line tool by simply including Rubycom at the bottom.}
         
     | 
| 
       12 
12 
     | 
    
         
             
              spec.summary       = %q{Converts singleton methods to command-line functions upon inclusion.}
         
     | 
| 
       13 
13 
     | 
    
         
             
              spec.homepage      = "http://dannypurcell.github.io/Rubycom"
         
     | 
| 
         @@ -113,19 +113,20 @@ class TestRubycom < Test::Unit::TestCase 
     | 
|
| 
       113 
113 
     | 
    
         
             
                  UtilTestModule <command> [args]
         
     | 
| 
       114 
114 
     | 
    
         | 
| 
       115 
115 
     | 
    
         
             
                Commands:
         
     | 
| 
       116 
     | 
    
         
            -
             
     | 
| 
       117 
     | 
    
         
            -
             
     | 
| 
       118 
     | 
    
         
            -
             
     | 
| 
       119 
     | 
    
         
            -
                   
     | 
| 
       120 
     | 
    
         
            -
             
     | 
| 
       121 
     | 
    
         
            -
             
     | 
| 
       122 
     | 
    
         
            -
             
     | 
| 
       123 
     | 
    
         
            -
             
     | 
| 
       124 
     | 
    
         
            -
             
     | 
| 
       125 
     | 
    
         
            -
             
     | 
| 
       126 
     | 
    
         
            -
             
     | 
| 
       127 
     | 
    
         
            -
                   
     | 
| 
       128 
     | 
    
         
            -
             
     | 
| 
      
 116 
     | 
    
         
            +
                test_command                -  A basic test command
         
     | 
| 
      
 117 
     | 
    
         
            +
                test_command_with_arg       -  A test_command with one arg
         
     | 
| 
      
 118 
     | 
    
         
            +
                test_command_arg_named_arg  -  A test_command with an arg named arg
         
     | 
| 
      
 119 
     | 
    
         
            +
                test_command_with_args      -  A test_command with two args
         
     | 
| 
      
 120 
     | 
    
         
            +
                test_command_with_options   -  A test_command with an optional argument
         
     | 
| 
      
 121 
     | 
    
         
            +
                test_command_all_options    -  A test_command with all optional arguments
         
     | 
| 
      
 122 
     | 
    
         
            +
                test_command_options_arr    -  A test_command with an options array
         
     | 
| 
      
 123 
     | 
    
         
            +
                test_command_with_return    -  A test_command with a return argument
         
     | 
| 
      
 124 
     | 
    
         
            +
                test_command_arg_timestamp  -  A test_command with a Timestamp argument and an unnecessarily
         
     | 
| 
      
 125 
     | 
    
         
            +
                                               long description which should overflow when
         
     | 
| 
      
 126 
     | 
    
         
            +
                                               it tries to line up with other descriptions.
         
     | 
| 
      
 127 
     | 
    
         
            +
                test_command_arg_false      -  A test_command with a Boolean argument
         
     | 
| 
      
 128 
     | 
    
         
            +
                test_command_arg_arr        -  A test_command with an array argument
         
     | 
| 
      
 129 
     | 
    
         
            +
                test_command_arg_hash       -  A test_command with an Hash argument
         
     | 
| 
       129 
130 
     | 
    
         | 
| 
       130 
131 
     | 
    
         
             
                END
         
     | 
| 
       131 
132 
     | 
    
         
             
                assert_equal(expected.gsub(/\n|\r|\s/, ''), result.gsub(/\n|\r|\s/, ''))
         
     | 
| 
         @@ -150,14 +151,15 @@ class TestRubycom < Test::Unit::TestCase 
     | 
|
| 
       150 
151 
     | 
    
         
             
                Commands:
         
     | 
| 
       151 
152 
     | 
    
         
             
                test_command                -  A basic test command
         
     | 
| 
       152 
153 
     | 
    
         
             
                test_command_with_arg       -  A test_command with one arg
         
     | 
| 
      
 154 
     | 
    
         
            +
                test_command_arg_named_arg  -  A test_command with an arg named arg
         
     | 
| 
       153 
155 
     | 
    
         
             
                test_command_with_args      -  A test_command with two args
         
     | 
| 
       154 
156 
     | 
    
         
             
                test_command_with_options   -  A test_command with an optional argument
         
     | 
| 
       155 
157 
     | 
    
         
             
                test_command_all_options    -  A test_command with all optional arguments
         
     | 
| 
       156 
158 
     | 
    
         
             
                test_command_options_arr    -  A test_command with an options array
         
     | 
| 
       157 
159 
     | 
    
         
             
                test_command_with_return    -  A test_command with a return argument
         
     | 
| 
       158 
160 
     | 
    
         
             
                test_command_arg_timestamp  -  A test_command with a Timestamp argument and an unnecessarily
         
     | 
| 
       159 
     | 
    
         
            -
                                               long description which should overflow when 
     | 
| 
       160 
     | 
    
         
            -
                                               with other descriptions.
         
     | 
| 
      
 161 
     | 
    
         
            +
                                               long description which should overflow when
         
     | 
| 
      
 162 
     | 
    
         
            +
                                               it tries to line up with other descriptions.
         
     | 
| 
       161 
163 
     | 
    
         
             
                test_command_arg_false      -  A test_command with a Boolean argument
         
     | 
| 
       162 
164 
     | 
    
         
             
                test_command_arg_arr        -  A test_command with an array argument
         
     | 
| 
       163 
165 
     | 
    
         
             
                test_command_arg_hash       -  A test_command with an Hash argument
         
     | 
| 
         @@ -178,7 +180,7 @@ class TestRubycom < Test::Unit::TestCase 
     | 
|
| 
       178 
180 
     | 
    
         
             
              end
         
     | 
| 
       179 
181 
     | 
    
         | 
| 
       180 
182 
     | 
    
         
             
              def test_get_top_level_commands
         
     | 
| 
       181 
     | 
    
         
            -
                test_command_list = [:test_command, :test_command_with_arg, :test_command_with_args, :test_command_with_options,
         
     | 
| 
      
 183 
     | 
    
         
            +
                test_command_list = [:test_command, :test_command_with_arg, :test_command_arg_named_arg, :test_command_with_args, :test_command_with_options,
         
     | 
| 
       182 
184 
     | 
    
         
             
                                     :test_command_all_options, :test_command_options_arr, :test_command_with_return,
         
     | 
| 
       183 
185 
     | 
    
         
             
                                     :test_command_arg_timestamp, :test_command_arg_false, :test_command_arg_arr,
         
     | 
| 
       184 
186 
     | 
    
         
             
                                     :test_command_arg_hash]
         
     | 
| 
         @@ -219,21 +221,21 @@ class TestRubycom < Test::Unit::TestCase 
     | 
|
| 
       219 
221 
     | 
    
         
             
              def test_parse_arg_string
         
     | 
| 
       220 
222 
     | 
    
         
             
                test_arg = "test_arg"
         
     | 
| 
       221 
223 
     | 
    
         
             
                result = Rubycom.parse_arg(test_arg)
         
     | 
| 
       222 
     | 
    
         
            -
                expected = { 
     | 
| 
      
 224 
     | 
    
         
            +
                expected = {rubycom_non_opt_arg: "test_arg"}
         
     | 
| 
       223 
225 
     | 
    
         
             
                assert_equal(expected, result)
         
     | 
| 
       224 
226 
     | 
    
         
             
              end
         
     | 
| 
       225 
227 
     | 
    
         | 
| 
       226 
228 
     | 
    
         
             
              def test_parse_arg_fixnum
         
     | 
| 
       227 
229 
     | 
    
         
             
                test_arg = "1234512415435"
         
     | 
| 
       228 
230 
     | 
    
         
             
                result = Rubycom.parse_arg(test_arg)
         
     | 
| 
       229 
     | 
    
         
            -
                expected = { 
     | 
| 
      
 231 
     | 
    
         
            +
                expected = {rubycom_non_opt_arg: 1234512415435}
         
     | 
| 
       230 
232 
     | 
    
         
             
                assert_equal(expected, result)
         
     | 
| 
       231 
233 
     | 
    
         
             
              end
         
     | 
| 
       232 
234 
     | 
    
         | 
| 
       233 
235 
     | 
    
         
             
              def test_parse_arg_float
         
     | 
| 
       234 
236 
     | 
    
         
             
                test_arg = "12345.67890"
         
     | 
| 
       235 
237 
     | 
    
         
             
                result = Rubycom.parse_arg(test_arg)
         
     | 
| 
       236 
     | 
    
         
            -
                expected = { 
     | 
| 
      
 238 
     | 
    
         
            +
                expected = {rubycom_non_opt_arg: 12345.67890}
         
     | 
| 
       237 
239 
     | 
    
         
             
                assert_equal(expected, result)
         
     | 
| 
       238 
240 
     | 
    
         
             
              end
         
     | 
| 
       239 
241 
     | 
    
         | 
| 
         @@ -241,8 +243,8 @@ class TestRubycom < Test::Unit::TestCase 
     | 
|
| 
       241 
243 
     | 
    
         
             
                time = Time.new
         
     | 
| 
       242 
244 
     | 
    
         
             
                test_arg = time.to_s
         
     | 
| 
       243 
245 
     | 
    
         
             
                result = Rubycom.parse_arg(test_arg)
         
     | 
| 
       244 
     | 
    
         
            -
                expected = { 
     | 
| 
       245 
     | 
    
         
            -
                assert_equal(expected[: 
     | 
| 
      
 246 
     | 
    
         
            +
                expected = {rubycom_non_opt_arg: time}
         
     | 
| 
      
 247 
     | 
    
         
            +
                assert_equal(expected[:rubycom_non_opt_arg].to_i, result[:rubycom_non_opt_arg].to_i)
         
     | 
| 
       246 
248 
     | 
    
         
             
              end
         
     | 
| 
       247 
249 
     | 
    
         | 
| 
       248 
250 
     | 
    
         
             
              def test_parse_arg_datetime
         
     | 
| 
         @@ -250,14 +252,14 @@ class TestRubycom < Test::Unit::TestCase 
     | 
|
| 
       250 
252 
     | 
    
         
             
                date = Date.new(time.year, time.month, time.day)
         
     | 
| 
       251 
253 
     | 
    
         
             
                test_arg = date.to_s
         
     | 
| 
       252 
254 
     | 
    
         
             
                result = Rubycom.parse_arg(test_arg)
         
     | 
| 
       253 
     | 
    
         
            -
                expected = { 
     | 
| 
      
 255 
     | 
    
         
            +
                expected = {rubycom_non_opt_arg: date}
         
     | 
| 
       254 
256 
     | 
    
         
             
                assert_equal(expected, result)
         
     | 
| 
       255 
257 
     | 
    
         
             
              end
         
     | 
| 
       256 
258 
     | 
    
         | 
| 
       257 
259 
     | 
    
         
             
              def test_parse_arg_array
         
     | 
| 
       258 
260 
     | 
    
         
             
                test_arg = ["1", 2, "a", 'b']
         
     | 
| 
       259 
261 
     | 
    
         
             
                result = Rubycom.parse_arg(test_arg.to_s)
         
     | 
| 
       260 
     | 
    
         
            -
                expected = { 
     | 
| 
      
 262 
     | 
    
         
            +
                expected = {rubycom_non_opt_arg: test_arg}
         
     | 
| 
       261 
263 
     | 
    
         
             
                assert_equal(expected, result)
         
     | 
| 
       262 
264 
     | 
    
         
             
              end
         
     | 
| 
       263 
265 
     | 
    
         | 
| 
         @@ -265,28 +267,91 @@ class TestRubycom < Test::Unit::TestCase 
     | 
|
| 
       265 
267 
     | 
    
         
             
                time = Time.new.to_s
         
     | 
| 
       266 
268 
     | 
    
         
             
                test_arg = ":a: \"#{time}\""
         
     | 
| 
       267 
269 
     | 
    
         
             
                result = Rubycom.parse_arg(test_arg.to_s)
         
     | 
| 
       268 
     | 
    
         
            -
                expected = { 
     | 
| 
      
 270 
     | 
    
         
            +
                expected = {rubycom_non_opt_arg: {a: time}}
         
     | 
| 
       269 
271 
     | 
    
         
             
                assert_equal(expected, result)
         
     | 
| 
       270 
272 
     | 
    
         
             
              end
         
     | 
| 
       271 
273 
     | 
    
         | 
| 
       272 
274 
     | 
    
         
             
              def test_parse_arg_hash_group
         
     | 
| 
       273 
275 
     | 
    
         
             
                test_arg = ":a: [1,2]\n:b: 1\n:c: test\n:d: 1.0\n:e: \"2013-05-08 23:21:52 -0500\"\n"
         
     | 
| 
       274 
276 
     | 
    
         
             
                result = Rubycom.parse_arg(test_arg.to_s)
         
     | 
| 
       275 
     | 
    
         
            -
                expected = { 
     | 
| 
      
 277 
     | 
    
         
            +
                expected = {rubycom_non_opt_arg: {:a => [1, 2], :b => 1, :c => "test", :d => 1.0, :e => "2013-05-08 23:21:52 -0500"}}
         
     | 
| 
       276 
278 
     | 
    
         
             
                assert_equal(expected, result)
         
     | 
| 
       277 
279 
     | 
    
         
             
              end
         
     | 
| 
       278 
280 
     | 
    
         | 
| 
       279 
281 
     | 
    
         
             
              def test_parse_arg_yaml
         
     | 
| 
       280 
282 
     | 
    
         
             
                test_arg = {:a => ["1", 2, "a", 'b'], :b => 1, :c => "test", :d => "#{Time.now.to_s}"}
         
     | 
| 
       281 
283 
     | 
    
         
             
                result = Rubycom.parse_arg(test_arg.to_yaml)
         
     | 
| 
       282 
     | 
    
         
            -
                expected = { 
     | 
| 
      
 284 
     | 
    
         
            +
                expected = {rubycom_non_opt_arg: test_arg}
         
     | 
| 
       283 
285 
     | 
    
         
             
                assert_equal(expected, result)
         
     | 
| 
       284 
286 
     | 
    
         
             
              end
         
     | 
| 
       285 
287 
     | 
    
         | 
| 
       286 
288 
     | 
    
         
             
              def test_parse_arg_code
         
     | 
| 
       287 
289 
     | 
    
         
             
                test_arg = 'def self.test_code_method; raise "Fail - test_parse_arg_code";end'
         
     | 
| 
       288 
290 
     | 
    
         
             
                result = Rubycom.parse_arg(test_arg.to_s)
         
     | 
| 
       289 
     | 
    
         
            -
                expected = { 
     | 
| 
      
 291 
     | 
    
         
            +
                expected = {rubycom_non_opt_arg: 'def self.test_code_method; raise "Fail - test_parse_arg_code";end'}
         
     | 
| 
      
 292 
     | 
    
         
            +
                assert_equal(expected, result)
         
     | 
| 
      
 293 
     | 
    
         
            +
              end
         
     | 
| 
      
 294 
     | 
    
         
            +
             
     | 
| 
      
 295 
     | 
    
         
            +
              def test_parse_opt_string_eq
         
     | 
| 
      
 296 
     | 
    
         
            +
                test_arg = "-test_arg=\"test\""
         
     | 
| 
      
 297 
     | 
    
         
            +
                result = Rubycom.parse_arg(test_arg)
         
     | 
| 
      
 298 
     | 
    
         
            +
                expected = {test_arg: "test"}
         
     | 
| 
      
 299 
     | 
    
         
            +
                assert_equal(expected, result)
         
     | 
| 
      
 300 
     | 
    
         
            +
              end
         
     | 
| 
      
 301 
     | 
    
         
            +
             
     | 
| 
      
 302 
     | 
    
         
            +
              def test_parse_opt_string_sp
         
     | 
| 
      
 303 
     | 
    
         
            +
                test_arg = "-test_arg \"test\""
         
     | 
| 
      
 304 
     | 
    
         
            +
                result = Rubycom.parse_arg(test_arg)
         
     | 
| 
      
 305 
     | 
    
         
            +
                expected = {test_arg: "test"}
         
     | 
| 
      
 306 
     | 
    
         
            +
                assert_equal(expected, result)
         
     | 
| 
      
 307 
     | 
    
         
            +
              end
         
     | 
| 
      
 308 
     | 
    
         
            +
             
     | 
| 
      
 309 
     | 
    
         
            +
              def test_parse_opt_long_string_eq
         
     | 
| 
      
 310 
     | 
    
         
            +
                test_arg = "--test_arg=\"test\""
         
     | 
| 
      
 311 
     | 
    
         
            +
                result = Rubycom.parse_arg(test_arg)
         
     | 
| 
      
 312 
     | 
    
         
            +
                expected = {test_arg: "test"}
         
     | 
| 
      
 313 
     | 
    
         
            +
                assert_equal(expected, result)
         
     | 
| 
      
 314 
     | 
    
         
            +
              end
         
     | 
| 
      
 315 
     | 
    
         
            +
             
     | 
| 
      
 316 
     | 
    
         
            +
              def test_parse_opt_long_string_sp
         
     | 
| 
      
 317 
     | 
    
         
            +
                test_arg = "--test_arg \"test\""
         
     | 
| 
      
 318 
     | 
    
         
            +
                result = Rubycom.parse_arg(test_arg)
         
     | 
| 
      
 319 
     | 
    
         
            +
                expected = {test_arg: "test"}
         
     | 
| 
      
 320 
     | 
    
         
            +
                assert_equal(expected, result)
         
     | 
| 
      
 321 
     | 
    
         
            +
              end
         
     | 
| 
      
 322 
     | 
    
         
            +
             
     | 
| 
      
 323 
     | 
    
         
            +
              def test_get_param_definitions
         
     | 
| 
      
 324 
     | 
    
         
            +
                test_method = UtilTestModule.public_method('test_command_with_args')
         
     | 
| 
      
 325 
     | 
    
         
            +
                expected = {:test_arg=>{:def=>"test_arg", :type=>:req, :default=>:nil_rubycom_required_param}, :another_test_arg=>{:def=>"another_test_arg", :type=>:req, :default=>:nil_rubycom_required_param}}
         
     | 
| 
      
 326 
     | 
    
         
            +
                result = Rubycom.get_param_definitions(test_method)
         
     | 
| 
      
 327 
     | 
    
         
            +
                assert_equal(expected, result)
         
     | 
| 
      
 328 
     | 
    
         
            +
              end
         
     | 
| 
      
 329 
     | 
    
         
            +
             
     | 
| 
      
 330 
     | 
    
         
            +
              def test_get_param_definitions_no_args
         
     | 
| 
      
 331 
     | 
    
         
            +
                test_method = UtilTestModule.public_method('test_command')
         
     | 
| 
      
 332 
     | 
    
         
            +
                expected = {}
         
     | 
| 
      
 333 
     | 
    
         
            +
                result = Rubycom.get_param_definitions(test_method)
         
     | 
| 
      
 334 
     | 
    
         
            +
                assert_equal(expected, result)
         
     | 
| 
      
 335 
     | 
    
         
            +
              end
         
     | 
| 
      
 336 
     | 
    
         
            +
             
     | 
| 
      
 337 
     | 
    
         
            +
              def test_get_param_definitions_arr_param
         
     | 
| 
      
 338 
     | 
    
         
            +
                test_method = UtilTestModule.public_method('test_command_options_arr')
         
     | 
| 
      
 339 
     | 
    
         
            +
                expected = {:test_option=>{:def=>"test_option=\"test_option_default\"", :type=>:opt, :default=>"test_option_default"}, :test_options=>{:def=>"*test_options", :type=>:rest, :default=>:nil_rubycom_required_param}}
         
     | 
| 
      
 340 
     | 
    
         
            +
                result = Rubycom.get_param_definitions(test_method)
         
     | 
| 
      
 341 
     | 
    
         
            +
                assert_equal(expected, result)
         
     | 
| 
      
 342 
     | 
    
         
            +
              end
         
     | 
| 
      
 343 
     | 
    
         
            +
             
     | 
| 
      
 344 
     | 
    
         
            +
              def test_get_param_definitions_all_options
         
     | 
| 
      
 345 
     | 
    
         
            +
                test_method = UtilTestModule.public_method('test_command_all_options')
         
     | 
| 
      
 346 
     | 
    
         
            +
                expected = {:test_arg=>{:def=>"test_arg='test_arg_default'", :type=>:opt, :default=>"test_arg_default"}, :test_option=>{:def=>"test_option='test_option_default'", :type=>:opt, :default=>"test_option_default"}}
         
     | 
| 
      
 347 
     | 
    
         
            +
                result = Rubycom.get_param_definitions(test_method)
         
     | 
| 
      
 348 
     | 
    
         
            +
                assert_equal(expected, result)
         
     | 
| 
      
 349 
     | 
    
         
            +
              end
         
     | 
| 
      
 350 
     | 
    
         
            +
             
     | 
| 
      
 351 
     | 
    
         
            +
              def test_get_param_definitions_mixed
         
     | 
| 
      
 352 
     | 
    
         
            +
                test_method = UtilTestModule.public_method('test_command_with_options')
         
     | 
| 
      
 353 
     | 
    
         
            +
                expected = {:test_arg=>{:def=>"test_arg", :type=>:req, :default=>:nil_rubycom_required_param}, :test_option=>{:def=>"test_option='option_default'", :type=>:opt, :default=>"option_default"}}
         
     | 
| 
      
 354 
     | 
    
         
            +
                result = Rubycom.get_param_definitions(test_method)
         
     | 
| 
       290 
355 
     | 
    
         
             
                assert_equal(expected, result)
         
     | 
| 
       291 
356 
     | 
    
         
             
              end
         
     | 
| 
       292 
357 
     | 
    
         | 
| 
         @@ -334,6 +399,7 @@ class TestRubycom < Test::Unit::TestCase 
     | 
|
| 
       334 
399 
     | 
    
         
             
                Commands:
         
     | 
| 
       335 
400 
     | 
    
         
             
                test_command                -  A basic test command
         
     | 
| 
       336 
401 
     | 
    
         
             
                test_command_with_arg       -  A test_command with one arg
         
     | 
| 
      
 402 
     | 
    
         
            +
                test_command_arg_named_arg  -  A test_command with an arg named arg
         
     | 
| 
       337 
403 
     | 
    
         
             
                test_command_with_args      -  A test_command with two args
         
     | 
| 
       338 
404 
     | 
    
         
             
                test_command_with_options   -  A test_command with an optional argument
         
     | 
| 
       339 
405 
     | 
    
         
             
                test_command_all_options    -  A test_command with all optional arguments
         
     | 
| 
         @@ -347,7 +413,7 @@ class TestRubycom < Test::Unit::TestCase 
     | 
|
| 
       347 
413 
     | 
    
         
             
                test_command_arg_hash       -  A test_command with an Hash argument
         
     | 
| 
       348 
414 
     | 
    
         
             
                END
         
     | 
| 
       349 
415 
     | 
    
         
             
                expected_out = expected
         
     | 
| 
       350 
     | 
    
         
            -
                assert_equal(expected, result)
         
     | 
| 
      
 416 
     | 
    
         
            +
                assert_equal(expected.gsub(/\n|\r|\s/, ''), result.gsub(/\n|\r|\s/, ''))
         
     | 
| 
       351 
417 
     | 
    
         
             
                assert_equal(expected_out.gsub(/\n|\r|\s/, ''), tst_out.gsub(/\n|\r|\s/, ''))
         
     | 
| 
       352 
418 
     | 
    
         
             
              ensure
         
     | 
| 
       353 
419 
     | 
    
         
             
                $stdout = o_stdout
         
     | 
| 
         @@ -596,9 +662,13 @@ class TestRubycom < Test::Unit::TestCase 
     | 
|
| 
       596 
662 
     | 
    
         
             
                result = Rubycom.run(base, args)
         
     | 
| 
       597 
663 
     | 
    
         | 
| 
       598 
664 
     | 
    
         
             
                expected = nil
         
     | 
| 
       599 
     | 
    
         
            -
                expected_out = "No argument available for test_arg"
         
     | 
| 
      
 665 
     | 
    
         
            +
                expected_out = "No argument available for test_arg\n"
         
     | 
| 
      
 666 
     | 
    
         
            +
             
     | 
| 
       600 
667 
     | 
    
         
             
                assert_equal(expected, result)
         
     | 
| 
       601 
     | 
    
         
            -
                assert_equal(expected_out, tst_out. 
     | 
| 
      
 668 
     | 
    
         
            +
                assert_equal(expected_out, tst_out.lines.first)
         
     | 
| 
      
 669 
     | 
    
         
            +
                Rubycom.get_command_usage(base,args[0],args[1..-1]).each_line{|expected_line|
         
     | 
| 
      
 670 
     | 
    
         
            +
                  assert_equal(true, tst_out.lines.include?(expected_line))
         
     | 
| 
      
 671 
     | 
    
         
            +
                }
         
     | 
| 
       602 
672 
     | 
    
         
             
              ensure
         
     | 
| 
       603 
673 
     | 
    
         
             
                $stdout = o_stdout
         
     | 
| 
       604 
674 
     | 
    
         
             
                $stderr = o_stderr
         
     | 
| 
         @@ -0,0 +1,21 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            ---
         
     | 
| 
      
 2 
     | 
    
         
            +
            env:
         
     | 
| 
      
 3 
     | 
    
         
            +
              test_msg: Hello World
         
     | 
| 
      
 4 
     | 
    
         
            +
              test_arg: 123
         
     | 
| 
      
 5 
     | 
    
         
            +
              working_dir: ./test/rubycom
         
     | 
| 
      
 6 
     | 
    
         
            +
            steps:
         
     | 
| 
      
 7 
     | 
    
         
            +
              1:
         
     | 
| 
      
 8 
     | 
    
         
            +
                desc: Run test_composite_command with environment variable
         
     | 
| 
      
 9 
     | 
    
         
            +
                cmd: ruby env[working_dir]/util_test_composite.rb test_composite_command env[test_msg]
         
     | 
| 
      
 10 
     | 
    
         
            +
              2:
         
     | 
| 
      
 11 
     | 
    
         
            +
                Var: Run UtilTestModule/test_command_options_arr with environment variable
         
     | 
| 
      
 12 
     | 
    
         
            +
                cmd: ruby env[working_dir]/util_test_composite.rb UtilTestModule test_command_options_arr '["Hello World 1", world2]'
         
     | 
| 
      
 13 
     | 
    
         
            +
              3:
         
     | 
| 
      
 14 
     | 
    
         
            +
                Cntxt: Run test_command_with_args with environment variable
         
     | 
| 
      
 15 
     | 
    
         
            +
                cmd: ruby env[working_dir]/util_test_module.rb test_command_with_args env[test_msg] env[test_arg]
         
     | 
| 
      
 16 
     | 
    
         
            +
              4:
         
     | 
| 
      
 17 
     | 
    
         
            +
                Cmd: Run ls for arbitrary command support
         
     | 
| 
      
 18 
     | 
    
         
            +
                cmd: ls
         
     | 
| 
      
 19 
     | 
    
         
            +
              5:
         
     | 
| 
      
 20 
     | 
    
         
            +
                Arbitrary_Context: Run ls with environment variable
         
     | 
| 
      
 21 
     | 
    
         
            +
                cmd: ls env[working_dir]
         
     | 
| 
         @@ -1,5 +1,5 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            require "#{File.expand_path(File.dirname(__FILE__))}/../../lib/rubycom.rb"
         
     | 
| 
       2 
     | 
    
         
            -
             
     | 
| 
      
 2 
     | 
    
         
            +
            # A command module used for testing
         
     | 
| 
       3 
3 
     | 
    
         
             
            module UtilTestModule
         
     | 
| 
       4 
4 
     | 
    
         | 
| 
       5 
5 
     | 
    
         
             
              # A test non-command method
         
     | 
| 
         @@ -19,6 +19,13 @@ module UtilTestModule 
     | 
|
| 
       19 
19 
     | 
    
         
             
                "test_arg=#{test_arg}"
         
     | 
| 
       20 
20 
     | 
    
         
             
              end
         
     | 
| 
       21 
21 
     | 
    
         | 
| 
      
 22 
     | 
    
         
            +
              # A test_command with an arg named arg
         
     | 
| 
      
 23 
     | 
    
         
            +
              #
         
     | 
| 
      
 24 
     | 
    
         
            +
              # @param [String] arg a test argument whose parameter name is arg
         
     | 
| 
      
 25 
     | 
    
         
            +
              def self.test_command_arg_named_arg(arg)
         
     | 
| 
      
 26 
     | 
    
         
            +
                "arg=#{arg}"
         
     | 
| 
      
 27 
     | 
    
         
            +
              end
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
       22 
29 
     | 
    
         
             
              # A test_command with two args
         
     | 
| 
       23 
30 
     | 
    
         
             
              # @param [String] test_arg a test argument
         
     | 
| 
       24 
31 
     | 
    
         
             
              # @param [String] another_test_arg another test argument
         
     | 
| 
         @@ -1,10 +1,10 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            require "#{File.expand_path(File.dirname(__FILE__))}/../../lib/rubycom.rb"
         
     | 
| 
       2 
     | 
    
         
            -
            require "#{File.expand_path(File.dirname(__FILE__))}/util_test_composite.rb"
         
     | 
| 
       3 
     | 
    
         
            -
             
     | 
| 
       4 
     | 
    
         
            -
            module UtilTestNoSingleton
         
     | 
| 
       5 
     | 
    
         
            -
              def test_method
         
     | 
| 
       6 
     | 
    
         
            -
                "TEST_NON_SINGLETON_METHOD"
         
     | 
| 
       7 
     | 
    
         
            -
              end
         
     | 
| 
       8 
     | 
    
         
            -
             
     | 
| 
       9 
     | 
    
         
            -
              include Rubycom
         
     | 
| 
      
 1 
     | 
    
         
            +
            require "#{File.expand_path(File.dirname(__FILE__))}/../../lib/rubycom.rb"
         
     | 
| 
      
 2 
     | 
    
         
            +
            require "#{File.expand_path(File.dirname(__FILE__))}/util_test_composite.rb"
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            module UtilTestNoSingleton
         
     | 
| 
      
 5 
     | 
    
         
            +
              def test_method
         
     | 
| 
      
 6 
     | 
    
         
            +
                "TEST_NON_SINGLETON_METHOD"
         
     | 
| 
      
 7 
     | 
    
         
            +
              end
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
              include Rubycom
         
     | 
| 
       10 
10 
     | 
    
         
             
            end
         
     | 
    
        metadata
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            --- !ruby/object:Gem::Specification
         
     | 
| 
       2 
2 
     | 
    
         
             
            name: rubycom
         
     | 
| 
       3 
3 
     | 
    
         
             
            version: !ruby/object:Gem::Version
         
     | 
| 
       4 
     | 
    
         
            -
              version: 0. 
     | 
| 
      
 4 
     | 
    
         
            +
              version: 0.2.0
         
     | 
| 
       5 
5 
     | 
    
         
             
              prerelease: 
         
     | 
| 
       6 
6 
     | 
    
         
             
            platform: ruby
         
     | 
| 
       7 
7 
     | 
    
         
             
            authors:
         
     | 
| 
         @@ -9,7 +9,7 @@ authors: 
     | 
|
| 
       9 
9 
     | 
    
         
             
            autorequire: 
         
     | 
| 
       10 
10 
     | 
    
         
             
            bindir: bin
         
     | 
| 
       11 
11 
     | 
    
         
             
            cert_chain: []
         
     | 
| 
       12 
     | 
    
         
            -
            date: 2013-06- 
     | 
| 
      
 12 
     | 
    
         
            +
            date: 2013-06-14 00:00:00.000000000 Z
         
     | 
| 
       13 
13 
     | 
    
         
             
            dependencies:
         
     | 
| 
       14 
14 
     | 
    
         
             
            - !ruby/object:Gem::Dependency
         
     | 
| 
       15 
15 
     | 
    
         
             
              name: bundler
         
     | 
| 
         @@ -96,7 +96,7 @@ description: Allows command-line access for all singleton methods in an includin 
     | 
|
| 
       96 
96 
     | 
    
         
             
              parsing options. Allows the user to make a command-line tool by simply including
         
     | 
| 
       97 
97 
     | 
    
         
             
              Rubycom at the bottom.
         
     | 
| 
       98 
98 
     | 
    
         
             
            email:
         
     | 
| 
       99 
     | 
    
         
            -
            -  
     | 
| 
      
 99 
     | 
    
         
            +
            - d.purcell.jr+rubycom@gmail.com
         
     | 
| 
       100 
100 
     | 
    
         
             
            executables: []
         
     | 
| 
       101 
101 
     | 
    
         
             
            extensions: []
         
     | 
| 
       102 
102 
     | 
    
         
             
            extra_rdoc_files: []
         
     | 
| 
         @@ -111,6 +111,7 @@ files: 
     | 
|
| 
       111 
111 
     | 
    
         
             
            - rubycom.gemspec
         
     | 
| 
       112 
112 
     | 
    
         
             
            - test/rubycom/test_rubycom.rb
         
     | 
| 
       113 
113 
     | 
    
         
             
            - test/rubycom/util_test_composite.rb
         
     | 
| 
      
 114 
     | 
    
         
            +
            - test/rubycom/util_test_job.yaml
         
     | 
| 
       114 
115 
     | 
    
         
             
            - test/rubycom/util_test_module.rb
         
     | 
| 
       115 
116 
     | 
    
         
             
            - test/rubycom/util_test_no_singleton.rb
         
     | 
| 
       116 
117 
     | 
    
         
             
            - test/rubycom/utility_tester.rb
         
     | 
| 
         @@ -142,6 +143,7 @@ summary: Converts singleton methods to command-line functions upon inclusion. 
     | 
|
| 
       142 
143 
     | 
    
         
             
            test_files:
         
     | 
| 
       143 
144 
     | 
    
         
             
            - test/rubycom/test_rubycom.rb
         
     | 
| 
       144 
145 
     | 
    
         
             
            - test/rubycom/util_test_composite.rb
         
     | 
| 
      
 146 
     | 
    
         
            +
            - test/rubycom/util_test_job.yaml
         
     | 
| 
       145 
147 
     | 
    
         
             
            - test/rubycom/util_test_module.rb
         
     | 
| 
       146 
148 
     | 
    
         
             
            - test/rubycom/util_test_no_singleton.rb
         
     | 
| 
       147 
149 
     | 
    
         
             
            - test/rubycom/utility_tester.rb
         
     |