Class: Command::CommandBase

Inherits:
Object
  • Object
show all
Defined in:
lib/commandbase.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(postfixies = " ") ⇒ CommandBase

postfixies は改行で区切ることで2パターン以上記述できる



23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/commandbase.rb', line 23

def initialize(postfixies = " ")
  self.stream_io = $stdout
  @opt = OptionParser.new(nil, 20)
  command_name = self.class.to_s.scan(/::(.+)$/)[0][0].downcase
  banner = postfixies.split("\n").map.with_index { |postfix, i|
    (i == 0 ? "Usage: " : "   or: ") + "narou #{command_name} #{postfix}"
  }.join("\n")
  @opt.banner = "<bold><green>#{TermColorLight.escape(banner)}</green></bold>".termcolor
  @options = {}
  # ヘルプを見やすく色付け
  def @opt.help
    msg = super
    # 見出し部分
    msg.gsub!(/((?:Examples|Options|Configuration|[^\s]+? Variable List):)/) do
      "<underline><bold>#{$1}</bold></underline>".termcolor
    end
    # Examples のコメント部分
    msg.gsub!(/(#.+)$/) do
      "<cyan>#{TermColorLight.escape($1)}</cyan>".termcolor
    end
    # 文字列部分
    msg.gsub!(/(".+?")/) do
      "<yellow>#{TermColorLight.escape($1)}</yellow>".termcolor
    end
    msg
  end
end

Instance Attribute Details

#stream_ioObject

Returns the value of attribute stream_io.



20
21
22
# File 'lib/commandbase.rb', line 20

def stream_io
  @stream_io
end

Class Method Details

.execute!(*argv, io: $stdout) ⇒ Object



132
133
134
135
# File 'lib/commandbase.rb', line 132

def self.execute!(*argv, io: $stdout)
  cmd = new
  cmd.execute!(*argv, io: io)
end

.helpObject

ヘルプを見やすく色付け



33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/commandbase.rb', line 33

def @opt.help
  msg = super
  # 見出し部分
  msg.gsub!(/((?:Examples|Options|Configuration|[^\s]+? Variable List):)/) do
    "<underline><bold>#{$1}</bold></underline>".termcolor
  end
  # Examples のコメント部分
  msg.gsub!(/(#.+)$/) do
    "<cyan>#{TermColorLight.escape($1)}</cyan>".termcolor
  end
  # 文字列部分
  msg.gsub!(/(".+?")/) do
    "<yellow>#{TermColorLight.escape($1)}</yellow>".termcolor
  end
  msg
end

.oneline_helpObject



137
138
139
# File 'lib/commandbase.rb', line 137

def self.oneline_help
  raise "implement #{self}.oneline_help"
end

Instance Method Details

#disable_loggingObject

コマンド出力のログ保存を抑制する

コマンドの中で、stream_io に対して出力している必要がある



177
178
179
# File 'lib/commandbase.rb', line 177

def disable_logging
  self.stream_io = stream_io.dup_with_disabled_logging
end

#display_help!Object



51
52
53
54
# File 'lib/commandbase.rb', line 51

def display_help!
  STDOUT.puts @opt.help
  exit
end

#execute(argv) ⇒ Object



56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/commandbase.rb', line 56

def execute(argv)
  @options.clear
  load_local_settings
  @opt.parse!(argv)
rescue OptionParser::InvalidOption => e
  error "不明なオプションです(#{e})"
  exit Narou::EXIT_ERROR_CODE
rescue OptionParser::InvalidArgument => e
  error "オプションの引数が正しくありません(#{e})"
  exit Narou::EXIT_ERROR_CODE
rescue OptionParser::MissingArgument => e
  error "オプションの引数が指定されていないか正しくありません(#{e})"
  exit Narou::EXIT_ERROR_CODE
rescue OptionParser::AmbiguousOption => e
  error "曖昧な省略オプションです(#{e})"
  exit Narou::EXIT_ERROR_CODE
end

#execute!(*argv, io: $stdout) ⇒ Object

コマンドを実行するが、アプリケーションは終了させない (SystemExit を補足し、終了コードを返り値とする)



122
123
124
125
126
127
128
129
130
# File 'lib/commandbase.rb', line 122

def execute!(*argv, io: $stdout)
  self.stream_io = io
  argv.flatten!
  execute(argv)
rescue SystemExit => e
  e.status
else
  0
end

#force_change_settings_function(pairs) ⇒ Object

設定の強制設定



159
160
161
162
163
164
165
166
167
168
169
170
# File 'lib/commandbase.rb', line 159

def force_change_settings_function(pairs)
  settings = Inventory.load("local_setting")
  modified = false
  pairs.each do |name, value|
    if settings[name].nil? || settings[name] != value
      settings[name] = value
      puts "<bold><cyan>#{name}#{value} に強制変更しました</cyan></bold>".termcolor
      modified = true
    end
  end
  settings.save if modified
end

#hook_call(target_method, *argv) ⇒ Object

指定したメソッドを呼び出す際に、フック関数があればそれ経由で呼ぶ

指定したメソッドは存在しなくてもいい。存在しなければ空のProcが作られる



146
147
148
149
150
151
152
153
154
# File 'lib/commandbase.rb', line 146

def hook_call(target_method, *argv)
  hook = "hook_#{target_method}"
  target_method_proc = self.method(target_method) rescue ->{}
  if respond_to?(hook)
    self.__send__(hook, *argv, &target_method_proc)
  else
    target_method_proc.call(*argv)
  end
end

#load_local_settingsObject



74
75
76
77
78
79
80
81
82
# File 'lib/commandbase.rb', line 74

def load_local_settings
  command_prefix = self.class.to_s.scan(/[^:]+$/)[0].downcase
  local_settings = Inventory.load("local_setting")
  local_settings.each do |name, value|
    if name =~ /^#{command_prefix}\.(.+)$/
      @options[$1] = value
    end
  end
end

#tagname_to_ids(array) ⇒ Object

タグ情報をID情報に展開する



87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# File 'lib/commandbase.rb', line 87

def tagname_to_ids(array)
  database = Database.instance
  tag_index = database.tag_indexies
  all_ids = database.ids
  expanded_array = array.map { |arg|
    if arg =~ /\A\d+\z/
      # 優先度はID>タグのため、数字のみ指定されたら
      # そのIDが存在した場合はIDとみなす
      id = arg.to_i
      next id if database[id]
    end
    ids =
      case arg
      when /\Atag:(.+)\z/
        # tag:タグ名 は直接タグと指定できる形式
        # (数字タグとIDがかぶった場合にタグを指定出来るようにするもの)
        arg = $1
        tag_index[$1]
      when /\A\^tag:(.+)\z/
        # ^tag:タグ名 は除外タグ指定
        arg = $1
        indexies = tag_index[$1]
        indexies.empty? ? [] : all_ids - indexies
      else
        tag_index[arg]
      end
    ids.empty? ? arg : ids
  }.flatten.uniq
  array.replace(expanded_array)
end