Class: Luban::CLI::Base

Inherits:
Object
  • Object
show all
Defined in:
lib/luban/cli/base/dsl.rb,
lib/luban/cli/base/core.rb,
lib/luban/cli/base/parse.rb,
lib/luban/cli/base/commands.rb

Direct Known Subclasses

Application, Command

Defined Under Namespace

Classes: InvalidCommand, MissingCommand, MissingRequiredArguments, MissingRequiredOptions

Constant Summary collapse

DefaultSummaryWidth =
32
DefaultSummaryIndent =
4
DefaultTitleIndent =
2

Class Attribute Summary collapse

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(parent, action_name, prefix: default_prefix, auto_help: true, &config_blk) ⇒ Base

Returns a new instance of Base.



36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/luban/cli/base/core.rb', line 36

def initialize(parent, action_name, prefix: default_prefix, auto_help: true, &config_blk)
  @parent = parent
  @action_name = action_name
  @prefix = prefix
  @action_defined = false

  @program_name = default_program_name
  @options = {}
  @arguments = {}
  @summary = ''
  @description = ''
  @version = ''
  @default_argv = ARGV
  @result = { cmd: nil, argv: @default_argv, args: {}, opts: {} }
  @commands = {}

  @title_indent = DefaultTitleIndent
  @summary_width = DefaultSummaryWidth
  @summary_indent = DefaultSummaryIndent

  configure(&config_blk)
  setup_default_action unless @action_defined
  self.auto_help if auto_help
end

Class Attribute Details

.config_blkObject (readonly)

Returns the value of attribute config_blk.



13
14
15
# File 'lib/luban/cli/base/dsl.rb', line 13

def config_blk
  @config_blk
end

Instance Attribute Details

#argumentsObject (readonly)

Returns the value of attribute arguments.



24
25
26
# File 'lib/luban/cli/base/core.rb', line 24

def arguments
  @arguments
end

#commandsObject (readonly)

Returns the value of attribute commands.



30
31
32
# File 'lib/luban/cli/base/core.rb', line 30

def commands
  @commands
end

#default_argvObject (readonly)

Returns the value of attribute default_argv.



29
30
31
# File 'lib/luban/cli/base/core.rb', line 29

def default_argv
  @default_argv
end

#descriptionObject (readonly)

Returns the value of attribute description.



26
27
28
# File 'lib/luban/cli/base/core.rb', line 26

def description
  @description
end

#optionsObject (readonly)

Returns the value of attribute options.



23
24
25
# File 'lib/luban/cli/base/core.rb', line 23

def options
  @options
end

#parentObject (readonly)

Returns the value of attribute parent.



20
21
22
# File 'lib/luban/cli/base/core.rb', line 20

def parent
  @parent
end

#prefixObject (readonly)

Returns the value of attribute prefix.



21
22
23
# File 'lib/luban/cli/base/core.rb', line 21

def prefix
  @prefix
end

#program_nameObject (readonly)

Returns the value of attribute program_name.



22
23
24
# File 'lib/luban/cli/base/core.rb', line 22

def program_name
  @program_name
end

#resultObject (readonly)

Returns the value of attribute result.



28
29
30
# File 'lib/luban/cli/base/core.rb', line 28

def result
  @result
end

#summaryObject (readonly)

Returns the value of attribute summary.



25
26
27
# File 'lib/luban/cli/base/core.rb', line 25

def summary
  @summary
end

#summary_indentObject

Returns the value of attribute summary_indent.



34
35
36
# File 'lib/luban/cli/base/core.rb', line 34

def summary_indent
  @summary_indent
end

#summary_widthObject

Returns the value of attribute summary_width.



33
34
35
# File 'lib/luban/cli/base/core.rb', line 33

def summary_width
  @summary_width
end

#title_indentObject

Returns the value of attribute title_indent.



32
33
34
# File 'lib/luban/cli/base/core.rb', line 32

def title_indent
  @title_indent
end

#version(ver = nil, short: :v, desc: "Show #{program_name} version.", &blk) ⇒ Object (readonly)

Returns the value of attribute version.



81
82
83
84
85
86
87
88
# File 'lib/luban/cli/base/dsl.rb', line 81

def version(ver = nil, short: :v, desc: "Show #{program_name} version.", &blk)
  if ver.nil?
    @version
  else
    @version = ver.to_s
    switch :version, desc, short: short, &blk
  end
end

Class Method Details

.configure(&blk) ⇒ Object



15
# File 'lib/luban/cli/base/dsl.rb', line 15

def configure(&blk); @config_blk = blk; end

.inherited(subclass) ⇒ Object



5
6
7
8
9
10
11
# File 'lib/luban/cli/base/dsl.rb', line 5

def inherited(subclass)
  super
  # Ensure configuration block from base class
  # got inherited to its subclasses
  blk = instance_variable_get('@config_blk')
  subclass.instance_variable_set('@config_blk', blk.clone) unless blk.nil?
end

Instance Method Details

#action(method_name = nil, &blk) ⇒ Object



92
93
94
# File 'lib/luban/cli/base/dsl.rb', line 92

def action(method_name = nil, &blk)
  create_action(method_name, preserve_argv: true, &blk)
end

#action!(method_name = nil, &blk) ⇒ Object



96
97
98
# File 'lib/luban/cli/base/dsl.rb', line 96

def action!(method_name = nil, &blk)
  create_action(method_name, preserve_argv: false, &blk)
end

#action_methodObject



63
64
65
# File 'lib/luban/cli/base/core.rb', line 63

def action_method
  @action_method ||= "#{@prefix}#{@action_name.to_s.gsub(':', '_')}"
end

#alter(&blk) ⇒ Object



81
82
83
84
85
# File 'lib/luban/cli/base/core.rb', line 81

def alter(&blk)
  instance_eval(&blk)
  on_alter
  after_alter
end

#argument(name, desc, **config, &blk) ⇒ Object



46
47
48
# File 'lib/luban/cli/base/dsl.rb', line 46

def argument(name, desc, **config, &blk)
  @arguments[name] = Argument.new(name, desc, **config, &blk)
end

#command(cmd, base: Command, **opts, &blk) ⇒ Object



6
7
8
9
# File 'lib/luban/cli/base/commands.rb', line 6

def command(cmd, base: Command, **opts, &blk)
  cmd = cmd.to_sym
  @commands[cmd] = command_class(cmd, base).new(self, cmd, **opts, &blk)
end

#default_prefixObject



61
# File 'lib/luban/cli/base/core.rb', line 61

def default_prefix; ''; end

#default_program_nameObject



71
72
73
# File 'lib/luban/cli/base/core.rb', line 71

def default_program_name
  @default_program_name ||= File.basename($0, '.*')
end

#desc(string) ⇒ Object



22
23
24
# File 'lib/luban/cli/base/dsl.rb', line 22

def desc(string)
  @summary = string.to_s unless string.nil?
end

#has_command?(cmd) ⇒ Boolean

Returns:

  • (Boolean)


31
32
33
# File 'lib/luban/cli/base/commands.rb', line 31

def has_command?(cmd)
  @commands.has_key?(cmd.to_sym)
end

#has_commands?Boolean

Returns:

  • (Boolean)


35
36
37
# File 'lib/luban/cli/base/commands.rb', line 35

def has_commands?
  !@commands.empty?
end

#help(short: :h, desc: "Show this help message.", &blk) ⇒ Object Also known as: auto_help



50
51
52
# File 'lib/luban/cli/base/dsl.rb', line 50

def help(short: :h, desc: "Show this help message.", &blk)
  switch :help, desc, short: short, &blk
end

#help_command(**opts, &blk) ⇒ Object Also known as: auto_help_command



65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/luban/cli/base/dsl.rb', line 65

def help_command(**opts, &blk)
  if block_given?
    command(**opts, &blk)
  else
    validator = method(:has_command?)
    command(:help, **opts) do
      desc "List all commands or help for one command"
      argument :command, "Command to help for", 
                type: :symbol, required: false,
               assure: validator
      action :show_help_for_command
    end
  end
end

#list_commandsObject



27
28
29
# File 'lib/luban/cli/base/commands.rb', line 27

def list_commands
  @commands.keys
end

#long_desc(string) ⇒ Object



26
27
28
# File 'lib/luban/cli/base/dsl.rb', line 26

def long_desc(string)
  @description = string.to_s unless string.nil?
end

#option(name, desc, nullable: false, **config, &blk) ⇒ Object



30
31
32
33
34
35
36
# File 'lib/luban/cli/base/dsl.rb', line 30

def option(name, desc, nullable: false, **config, &blk)
  @options[name] = if nullable
                     NullableOption.new(name, desc, **config, &blk)
                   else
                     Option.new(name, desc, **config, &blk)
                   end
end

#parse(argv = default_argv) ⇒ Object



4
5
6
7
# File 'lib/luban/cli/base/parse.rb', line 4

def parse(argv=default_argv)
  argv = argv.dup
  parse!(argv)
end

#parse!(argv = default_argv) ⇒ Object



9
10
11
12
13
14
15
16
# File 'lib/luban/cli/base/parse.rb', line 9

def parse!(argv=default_argv)
  if commands.empty?
    parse_without_commands(argv)
  else
    parse_with_commands(argv)
  end
  update_result(argv)
end

#parserObject



67
68
69
# File 'lib/luban/cli/base/core.rb', line 67

def parser
  @parser ||= create_parser
end

#program(name) ⇒ Object



18
19
20
# File 'lib/luban/cli/base/dsl.rb', line 18

def program(name)
  @program_name = name.to_s unless name.nil? 
end

#resetObject



75
76
77
78
79
# File 'lib/luban/cli/base/core.rb', line 75

def reset
  @options.each_value { |o| o.reset }
  @arguments.each_value { |a| a.reset }
  @result = { cmd: nil, argv: @default_argv, args: {}, opts: {} }
end

#show_helpObject



55
# File 'lib/luban/cli/base/dsl.rb', line 55

def show_help; puts parser.help; end

#show_help_for_command(args:, **params) ⇒ Object



57
58
59
60
61
62
63
# File 'lib/luban/cli/base/dsl.rb', line 57

def show_help_for_command(args:, **params)
  if args[:command].nil?
    show_help
  else
    commands[args[:command]].show_help
  end
end

#show_versionObject



90
# File 'lib/luban/cli/base/dsl.rb', line 90

def show_version; puts parser.ver; end

#switch(name, desc, negatable: false, **config, &blk) ⇒ Object



38
39
40
41
42
43
44
# File 'lib/luban/cli/base/dsl.rb', line 38

def switch(name, desc, negatable: false, **config, &blk)
  @options[name] = if negatable
                     NegatableSwitch.new(name, desc, **config, &blk)
                   else
                     Switch.new(name, desc, **config, &blk)
                   end
end

#task(cmd, **opts, &blk) ⇒ Object



39
40
41
42
43
44
45
46
# File 'lib/luban/cli/base/commands.rb', line 39

def task(cmd, **opts, &blk)
  command(cmd, **opts, &blk).tap do |t|
    add_common_task_options(t)
    if !t.summary.nil? and t.description.empty?
      t.long_desc "#{t.summary} in #{self.class.name}"
    end
  end
end

#undef_command(cmd) ⇒ Object Also known as: undef_task



11
12
13
14
15
16
17
18
# File 'lib/luban/cli/base/commands.rb', line 11

def undef_command(cmd)
  c = @commands.delete(cmd.to_sym)
  if c.nil?
    raise RuntimeError, "Command #{cmd.inspect} is NOT defined."
  else
    undef_singleton_method(c.action_method)
  end
end

#use_commands(module_name, **opts, &blk) ⇒ Object



20
21
22
23
24
25
# File 'lib/luban/cli/base/commands.rb', line 20

def use_commands(module_name, **opts, &blk)
  module_class = Object.const_get(module_name.camelcase, false)
  module_class.constants(false).map { |c| module_class.const_get(c, false) }.each do |c|
    command(c.name.snakecase, base: c, **opts, &blk) if c < Command
  end
end