module Twine::CLI
Constants
- ALL_FORMATS
- COMMANDS
- DEPRECATED_COMMAND_MAPPINGS
- OPTIONS
Public Class Methods
parse(args)
click to toggle source
# File lib/twine/cli.rb, line 241 def self.parse(args) command = args.select { |a| a[0] != '-' }[0] args = args.reject { |a| a == command } if args.any? { |a| a == '--version' } Twine::stdout.puts "Twine version #{Twine::VERSION}" return false end mapped_command = DEPRECATED_COMMAND_MAPPINGS[command] if mapped_command Twine::stdout.puts "WARNING: Twine commands names have changed. `#{command}` is now `#{mapped_command}`. The old command is deprecated and will soon stop working. For more information please check the documentation at https://github.com/mobiata/twine" command = mapped_command end if command.nil? print_help(args) return false elsif not COMMANDS.keys.include? command raise Twine::Error.new "Invalid command: #{command}" end parse_command_options(command, args) end
Private Class Methods
indent(string, first_line, following_lines)
click to toggle source
# File lib/twine/cli.rb, line 306 def self.indent(string, first_line, following_lines) lines = string.split("\n") indentation = ' ' * following_lines lines.map! { |line| indentation + line } result = lines.join("\n").strip ' ' * first_line + result end
parse_command_options(command_name, args)
click to toggle source
# File lib/twine/cli.rb, line 355 def self.parse_command_options(command_name, args) command = COMMANDS[command_name] result = { command: command_name } parser = OptionParser.new parser.banner = "Usage: twine #{command_name} #{command[:arguments].map { |c| "[#{c}]" }.join(' ')} [options]" [:required_options, :optional_options].each do |option_type| options = command[option_type] if options and options.size > 0 parser.separator '' parser.separator option_type.to_s.gsub('_', ' ').capitalize + ":" options.each do |option_name| option = OPTIONS[option_name] result[option_name] = option[:default] if option[:default] prepare_description!(option, parser.summary_width) parser.define(*option[:switch]) do |value| if option[:repeated] result[option_name] = (result[option_name] || []) << value else result[option_name] = value end end end end end parser.define('-h', '--help', 'Show this message.') do Twine::stdout.puts parser.help return false end parser.separator '' parser.separator 'Examples:' parser.separator '' parser.separator "> #{command[:example]}" begin parser.parse! args rescue OptionParser::ParseError => e raise Twine::Error.new e.message end arguments = args.reject { |a| a[0] == '-' } number_of_missing_arguments = command[:arguments].size - arguments.size if number_of_missing_arguments > 0 missing_arguments = command[:arguments][-number_of_missing_arguments, number_of_missing_arguments] raise Twine::Error.new "#{number_of_missing_arguments} missing argument#{number_of_missing_arguments > 1 ? "s" : ""}: #{missing_arguments.join(', ')}. Check `twine #{command_name} -h`" end if args.length > command[:arguments].size raise Twine::Error.new "Unknown argument: #{args[command[:arguments].size]}" end if command[:required_options] command[:required_options].each do |option_name| if result[option_name] == nil raise Twine::Error.new "missing option: #{OPTIONS[option_name][:switch][0]}" end end end command[:option_validation].call(result) if command[:option_validation] command[:arguments].each do |argument_name| result[argument_name] = args.shift end result end
prepare_description!(options, summary_width)
click to toggle source
ensure the description forms a neat block on the right
# File lib/twine/cli.rb, line 315 def self.prepare_description!(options, summary_width) lines = options[:description].split "\n" # remove leadinge HEREDOC spaces space_match = lines[0].match(/^\s+/) if space_match leading_spaces = space_match[0].length lines.map! { |l| l[leading_spaces..-1] } end merged_lines = [] lines.each do |line| # if the line is a continuation of the previous one if not merged_lines.empty? and (line[0] != ' ' or line[0, 4] == ' ') merged_lines[-1] += ' ' + line.strip else merged_lines << line.rstrip end end if IO.console console_width = IO.console.winsize[1] else console_width = 100 end summary_width += 7 # account for description padding max_description_width = console_width - summary_width merged_lines.map! do |line| if line[0] == ' ' line = word_wrap(line.strip, max_description_width - 2) line = indent(line, 2, 4) else line = word_wrap(line, max_description_width) end line end options[:switch] << indent(merged_lines.join("\n"), 0, summary_width) end
print_help(args)
click to toggle source
# File lib/twine/cli.rb, line 268 def self.print_help(args) verbose = false help_parser = OptionParser.new help_parser.banner = 'Usage: twine [command] [options]' help_parser.define('-h', '--help', 'Show this message.') help_parser.define('--verbose', 'More detailed help.') { verbose = true } help_parser.parse!(args) Twine::stdout.puts help_parser.help Twine::stdout.puts '' Twine::stdout.puts 'Commands:' COMMANDS.each do |name, properties| if verbose Twine::stdout.puts '' Twine::stdout.puts '' Twine::stdout.puts "# #{name}" Twine::stdout.puts '' Twine::stdout.puts properties[:description] else Twine::stdout.puts "- #{name}" end end Twine::stdout.puts '' Twine::stdout.puts 'type `twine [command] --help` for further information about a command.' end
word_wrap(s, width)
click to toggle source
source: www.safaribooksonline.com/library/view/ruby-cookbook/0596523696/ch01s15.html
# File lib/twine/cli.rb, line 302 def self.word_wrap(s, width) s.gsub(/(.{1,#{width}})(\s+|\Z)/, "\\1\n").rstrip end