thoughtbot / cocaine

A small library for doing (command) lines.
https://robots.thoughtbot.com
Other
785 stars 55 forks source link

How to deal with command line option that takes a list of arguments #54

Closed andi-dev closed 11 years ago

andi-dev commented 11 years ago

To be specific, I couldn't find a way to run the following command:

pdftk in1.pdf in2.pdf in3.pdf cat output out.pdf

with a line like this:

@line = Cocaine::CommandLine.new("pdftk", ":in cat output :out")

calling

@line.run(:in => "in1.pdf in2.pdf", :out => "out.pdf") 

will not work, because the produced command looks like this:

pdftk 'in1.pdf in2.pdf in3.pdf' cat output 'out.pdf'

and pdftk takes the entire first string as a file name (which sure doesn't exist).

Is there any option / way to go I missed?

sshaw commented 11 years ago

Just encountered this problem, here's what I did :see_no_evil:

files = %w[file1 file2 fileN]
keys = 1.upto(files.size).map { |n| "{file#{n}}" }
options = Hash[keys.zip(files)]

line  = Cocaine::CommandLine.new("your_command", keys.map { |key| ":#{key}" }.join(" "))
line.run(options)

Note that due to the nature of this regex it's necessary to wrap your interpolation key in {}.

jyurek commented 11 years ago

This isn't something that was a need of mine when I wrote this, so it doesn't natively handle it now. But I would definitely be interested in a patch that handles this case correctly. I'm going to close this for now since I don't intend on adding it myself, but if you make a PR that would be awesome.

sshaw commented 11 years ago

I'll throw something together in a few days, I'm thinking something like:

line = Cocaine::CommandLine.new("ls", ":files")
line.run(:files => %w[a b c])   # `ls a b c`
jyurek commented 11 years ago

The correct case here should be ls 'a' 'b' 'c', which you'd get from shell_quote. But, yeah, that's approximately what I expected the syntax to be.