Module: Backticks::CLI::Getopt

Defined in:
lib/backticks/cli.rb

Overview

Command-line parameter generator that relies on traditional *nix getopt conventions. Getopt doesn’t know about GNU conventions such as short and long options; it doesn’t know about abbreviations; it doesn’t know about conventions such as ‘–X` vs. `–no-X` or `-d` vs. `-D`.

Although Getopt is simple, it has the tremendous advantage of being compatible with a wide range of other schemes including GNU getopt-long, golang flags, and most Java utilities. It’s a great choice of default CLI.

Class Method Summary collapse

Class Method Details

.options(kwargs = {}) ⇒ Array

Translate Ruby keyword arguments into command-line parameters using a notation that is compatible with traditional Unix getopt. Command lines generated by this method are also mostly compatible with the following:

- GNU getopt
- Ruby trollop gem
- Golang flags package

This method accepts an unbounded set of keyword arguments (i.e. you can pass it any valid Ruby symbol as a kwarg). Each kwarg has a value; the key/value pair is translated into a CLI option using the following heuristic:

1) Snake-case keys are hyphenated, e.g. :no_foo => "--no-foo"
2) boolean values indicate a CLI flag; true includes the flag, false or nil omits it
3) all other values indicate a CLI option that has a value.
4) single character keys are passed as short options; {X: V} becomes "-X V"
5) multi-character keys are passed as long options; {Xxx: V} becomes "--XXX=V"

The generic translator doesn’t know about short vs. long option names, abbreviations, or the GNU “X vs. no-X” convention, so it does not produce the most idiomatic or compact command line for a given program; its output is, however, almost always valid for utilities that use Unix-like parameters.

Returns:

  • (Array)

    list of String command-line options



73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
# File 'lib/backticks/cli.rb', line 73

def self.options(kwargs={})
  flags = []

  # Transform opts into golang flags-style command line parameters;
  # append them to the command.
  kwargs.each do |kw, arg|
    if kw.length == 1
      if arg == true
        # true: boolean flag
        flags << "-#{kw}"
      elsif arg
        # truthey: option that has a value
        flags << "-#{kw}" << arg.to_s
      else
        # falsey: omit boolean flag
      end
    else
      kw = kw.to_s.gsub('_','-')
      if arg == true
        # true: boolean flag
        flags << "--#{kw}"
      elsif arg
        # truthey: option that has a value
        flags << "--#{kw}=#{arg}"
      else
        # falsey: omit boolean flag
      end
    end
  end

  flags
end

.parameters(*sugar) ⇒ Array

Translate a series Ruby positional and keyword arguments into command- parameters consisting of words and options.

Each positional argument can be a Hash, an Array, or another object. They are handled as follows:

- Hash is translated to a sequence of options; see #options
- Array is appended to the command line as a sequence of words
- other objects are turned into a string with #to_s and appended to the command line as a single word

Examples:

recursively find all text files

parameters('ls', l:true, R:true, '*.txt') => 'ls -l -R *.txt

install your favorite gem

parameters('gem', 'install', no_document:true, 'backticks')

Returns:

  • (Array)

    list of String words and options



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/backticks/cli.rb', line 29

def self.parameters(*sugar)
  argv = []

  sugar.each do |item|
    case item
    when Array
      # list of words to append to argv
      argv.concat(item.map { |e| e.to_s })
    when Hash
      # list of options to convert to CLI parameters
      argv.concat(options(item))
    else
      # single word to append to argv
      argv << item.to_s
    end
  end

  argv
end