commander-rb / commander

The complete solution for Ruby command-line executables
MIT License
822 stars 74 forks source link

Integration with Aruba in_process #76

Closed tsetsik closed 4 years ago

tsetsik commented 5 years ago

Imagine the following case:

I'm using aruba in my cucumber BDD tests, which by default is executing the commands in a child process. That is slow and doesn't allow me to stub/mock components. So the alternative which they provide is called in_process, which is not spawning a new process, it uses the current one . With this approach you have to trigger your application, since my application is CLI app. So in my case I have the following:

runner.rb

module Cli
  module App
    class Runner
      def initialize(argv, stdin, stdout, stderr, kernel)
        @argv   = argv
        @stdin  = stdin
        @stdout = stdout
        @stderr = stderr
        @kernel = kernel
      end

      def execute!
        MyApp::Command.new.run
      end
    end
  end
end

And my command.rb looks lik:

require 'commander'

module MyApp
  class Command
    include Commander::Methods

    def run
      program :name, 'myapp'
      program :version, MyApp::VERSION
      program :description, 'This tool handles the syncing from Bitbucket / GIT to your clearcase view.'
      default_command :sync

      global_option('-u', '--url STRING', 'Specifies the link to the third party site')

      command :sync do |cmd|
        cmd.syntax = 'sync [options]'
        cmd.description = 'sync to third party'
        cmd.action do |_args, options|

          if !options.abort
            fail 'The URL, the branch and the stream is mandatory' unless options.stream && options.url && options.branch
          else
            fail 'The stream is mandatory for an abort' unless options.stream
          end

          # Some code executed by my application
        end
      end

      run!
    end
  end
end

And my cucumber step is: I run myapp sync -u http://example.com

With that my sync command is called, but the options are missing, probably I have to inject them somehow

For example thor gem allows me to do something like that: MyCli::App.start(@argv) in the runner and everything works

So my concern is: how can I inject the options with in my runner ?

paul-mesnilgrente commented 4 years ago

I have the same issue, I don't want to use ARGV but an array I have in the code. Did you find a way around it?

tsetsik commented 4 years ago

Unfortunately not, but to me it's not relevant anymore

ggilder commented 4 years ago

Right now I think the best solution to this would be what Commander's own specs use - take a look at #new_command_runner in spec/spec_helper.rb which includes this line:

Commander::Runner.instance_variable_set :"@singleton", Commander::Runner.new(args)

That allows you to run specs with arbitrary arguments by passing them in to a setup method.

I know that's a little clunky — if you're motivated enough to submit a pull request to provide a better interface, I'd be glad to take a look!

Hope that helps!