Is There a Command Line Framework for Ruby

Is there a command line framework for ruby?

Judging from your questions it sounds like your like looking for curses-based frameworks. But in case that you're not, here are some console/irb-related gems I've written that may be useful:

  • hirb - view framework for associating classes with views
  • bond - custom readline completion made easy
  • boson - console command framework

Now to answer your questions:

  1. Though I don't know how to do it, there is this nice curses app whose source code you could read.
  2. require 'readline' gives you those keybindings
  3. require 'highline'; answer = HighLine.new.ask('ask something') {|e| e.character = true }

Ruby command line MVC framework?

You should take a look at boson and hirb [2d] menus. First one for creation of commands, second one - for A,B,C options and custom/dynamic views for outputting data.

Which testing technology to use for a command-line Ruby app?

Perhaps it might help to address HOW to write tests. There are lots of test frameworks, and lots of philosophies of how we should write tests but I try to keep it simple. I generally start with these:

  • Test to see I got back nil or an object first.
  • Test to see if the object is the right type.
  • Test to see if mandatory attributes are set, then if they're the right types.

Once I've got those out of the way I'll start antagonizing the code, throwing out-of-bounds and evil values at it, forcing it to raise its exceptions if it's supposed to do that.

Then, as further use/testing reveal bugs I'd add specific tests to check to see those don't reappear as I screw around with the code. ("Code screwing-around" is gonna happen, so its important I know I didn't make the program go out in flames.)

ZenTest has the autotest command which looks for a change in your test files and runs the tests automatically. It makes it really easy to make sure I haven't borked things, because in a separate console window autotest will be doing its thing each time I save. It's a great-big safety net you'll get used to having very quickly. From the docs:

autotest is a continous testing facility meant to be used during
development. As soon as you save a file, autotest will run the
corresponding dependent tests.

Writing tests are a necessary evil. They'll double your code-writing load, but they're very important to start early and continue maintaining. Trying to add them later to a large code base is a major problem, causing too many apps to never have unit tests. Icky.

How to provide config file for Ruby command line utility written in Ruby?

To evaluate code within the context of an instance, which is what you want to do, you need the instance_eval() method. Never, ever, use normal eval. Ever. Anyway, here's how you'd load your fingi file and get the data:

config = ConfigData.new
config.instance_eval(File.read("Myconfig"))
#Access configuration data here from the config object

That simple. After you've loaded the object in that way, you can access values of the object.

WARNING: This is not very secure. This is actually a gaping security hole. Here's the secure version:

f = Fiber.new {str = File.read("Myconfig"); $SAFE = 4; config = ConfigData.new; config.instance_eval(str); Fiber.yield config}
confdata = f.resume
#Access configuration data here from confdata.

This executes the external code in a (sort of) sandbox, so that it can't do anything dastardly.


Also, why don't you just use a YAML config? Unless configuration needs to run code like pwd or access RUBY_VERSION, YAML is much simpler and more secure, in addition to being more failproof.

How do I write a command line application in Ruby with RSpec?

You should look at aruba, which allows you to drive command-line app development using Cucumber, which, under the covers, uses RSpec. It handles executing programs and capturing their output and exit status, which can be kindof a pain to do on your own. As an example:

Given the file "foo.txt" exists
When I successfully execute `cp foo.txt bar.txt`
Then a file named "bar.txt" should exist
And the file "bar.txt" should the same contents as "foo.txt"

Aruba provides you the second and third steps, you provide the others:

CONTENTS = 'some contents'

Given /^the file "([^"]*)" exists$/ do |file|
File.open(file,'w') { |file| file.puts(CONTENTS) }
end
Then /^the file "([^"]*)" should the same contents as "([^"]*)"$/ do |dest_file,source_file|
contents = File.read(dest_file)
contents.should == CONTENTS
end

There's a lot more tricky stuff to testing command-line apps, but aruba is a big help

Ruby C Extensions - Add System Frameworks

To use a framework in a Ruby extension, you need to use the have_framework method in your extconf.rb. This will add the appropriate command line options in the Makefile.

In your case you want:

have_framework('Accelerate')

ruby Test::Unit Command line options?

ruby /path/to/foo_test.rb --name test_should_do_something_really_spiffy

That will call the test defined by the method test_should_do_something_really_spiffy in that file.

EDIT: That's for the Test::Unit framework that most ruby tests are written with. I am assuming you meant the same.

Override ENV['HOME'] for development of a Ruby command line app

The way I would do this would be to keep any development specific stuff out of the actual application code, but to have a Rakefile to use for testing during development. In there you could make sure the environment is set up appropriately, something like:

desc "Run the app"
task :exec do
ENV['HOME']= "somewhere else"
exec "./bin/your_binary"
end

You would then run rake exec (or give the task a better name) to run the development version, whilst still being able to run the real version. If you keep your development bin directory of your PATH there shouldn’t be any chance to mix up the two commands.

If you do want to be able to run the development version directly you could use the fact that when you run a gems binary the actual file that is executed is the wrapper file that Rubygems creates. You could check for this with the __FILE__ == $0 idiom in the top of your executable:

if __FILE == $0
# executing directly, probably in dev environment
ENV['HOME'] = "somewhere else"
end

When calling your file directly the environment will be replaced, when calling an installed gem $0 will be the wrapper file so the original environment will be used.

The “normal” way to do this is to just set the environment from your shell, e.g. in Bash:

$ HOME='somewhere else' ./bin/the_executable

The danger here of course is that you might forget to set the environment, causing you to trash some of you files. You could get round that by setting the new environment for your whole seesion:

$ export HOME='somewhere else'
$ ./bin/the_executable

but this will likely effect other tools that use HOME so it’s not advisable.

My advice would be to go for the Rakefile option, with the __FILE == $0 option as second choice.



Related Topics



Leave a reply



Submit