Class: ImageOptim::Runner::OptionParser

Inherits:
OptionParser
  • Object
show all
Defined in:
lib/image_optim/runner/option_parser.rb

Overview

Parse options from arguments to image_optim binary

Constant Summary collapse

DEFINE =
proc do |op, options|
  unless op.is_a?(OptionParser)
    fail ArgumentError, "expected instance of OptionParser, got #{op.inspect}"
  end
  unless options.is_a?(Hash)
    fail ArgumentError, "expected instance of Hash, got #{options.inspect}"
  end

  ImageOptim::TrueFalseNil.add_to_option_parser(op)
  ImageOptim::NonNegativeIntegerRange.add_to_option_parser(op)

  op.banner = "    |\#{ImageOptim.full_version}\n    |\n    |Usage:\n    |  \#{op.program_name} [options] image_path \u2026\n    |\n    |Configuration will be read and prepended to options from two paths:\n    |  \#{ImageOptim::Config::GLOBAL_PATH}\n    |  \#{ImageOptim::Config::LOCAL_PATH}\n    |\n  TEXT\n\n  op.on('--config-paths PATH1,PATH2', Array, 'Config paths to use instead of '\\\n      'default ones') do |paths|\n    options[:config_paths] = paths\n  end\n\n  op.separator nil\n\n  op.on('-r', '-R', '--recursive', 'Recursively scan directories '\\\n      'for images') do |recursive|\n    options[:recursive] = recursive\n  end\n\n  op.on(\"--exclude-dir 'GLOB'\", 'Glob for excluding directories '\\\n      '(defaults to .*)') do |glob|\n    options[:exclude_dir_glob] = glob\n  end\n\n  op.on(\"--exclude-file 'GLOB'\", 'Glob for excluding files '\\\n      '(defaults to .*)') do |glob|\n    options[:exclude_file_glob] = glob\n  end\n\n  op.on(\"--exclude 'GLOB'\", 'Set glob for excluding both directories and '\\\n      'files') do |glob|\n    options[:exclude_file_glob] = options[:exclude_dir_glob] = glob\n  end\n\n  op.separator nil\n\n  op.on('--no-progress', 'Disable showing progress') do |show_progress|\n    options[:show_progress] = show_progress\n  end\n\n  op.on('--[no-]threads N', Integer, 'Number of threads or disable '\\\n      '(defaults to number of processors)') do |threads|\n    options[:threads] = threads\n  end\n\n  op.on('--[no-]nice N', Integer, 'Nice level, priority of all used tools '\\\n      'with higher value meaning lower priority, in range -20..19, negative '\\\n      'values can be set only if run by root user (defaults to 10)') do |nice|\n    options[:nice] = nice\n  end\n\n  op.on('--[no-]pack', 'Require image_optim_pack or disable it, '\\\n      'by default image_optim_pack will be used if available, '\\\n      'will turn on skip-missing-workers unless explicitly disabled') do |pack|\n    options[:pack] = pack\n  end\n\n  op.separator nil\n  op.separator '  Caching:'\n\n  op.on('--cache-dir DIR', 'Cache optimized images '\\\n        'into the specified directory') do |cache_dir|\n    options[:cache_dir] = cache_dir\n  end\n\n  op.on('--cache-worker-digests', 'Cache worker digests '\\\n        '(updating workers invalidates cache)') do |cache_worker_digests|\n    options[:cache_worker_digests] = cache_worker_digests\n  end\n\n  op.separator nil\n  op.separator '  Disabling workers:'\n\n  op.on('--[no-]skip-missing-workers', 'Skip workers with missing or '\\\n      'problematic binaries') do |skip|\n    options[:skip_missing_workers] = skip\n  end\n\n  ImageOptim::Worker.klasses.each do |klass|\n    bin = klass.bin_sym\n    op.on(\"--no-\#{bin}\", \"disable \#{bin} worker\") do |enable|\n      options[bin] = enable\n    end\n  end\n\n  op.separator nil\n  op.separator '  Worker options:'\n\n  op.on('--allow-lossy', 'Allow lossy workers and '\\\n      'optimizations') do |allow_lossy|\n    options[:allow_lossy] = allow_lossy\n  end\n\n  op.on('--timeout N', 'Sets a timeout for workers') do |timeout|\n    options[:timeout] = timeout.to_i\n  end\n\n  op.separator nil\n\n  ImageOptim::Worker.klasses.each_with_index do |klass, i|\n    next if klass.option_definitions.empty?\n    op.separator nil unless i.zero?\n\n    bin = klass.bin_sym\n    klass.option_definitions.each do |option_definition|\n      name = option_definition.name.to_s.tr('_', '-')\n      default = option_definition.default_description\n      type = option_definition.type\n\n      type, marking = case\n      when [TrueClass, FalseClass, ImageOptim::TrueFalseNil].include?(type)\n        [type, 'B']\n      when Integer >= type\n        [Integer, 'N']\n      when Array >= type\n        [Array, 'a,b,c']\n      when ImageOptim::NonNegativeIntegerRange == type\n        [type, 'M-N']\n      else\n        fail \"Unknown type \#{type}\"\n      end\n\n      description = option_definition.description.gsub(' - ', '\u00A0-\u00A0')\n      unless description['(defaults']\n        description << \" (defaults\u00A0to\u00A0\#{default})\"\n      end\n\n      op.on(\"--\#{bin}-\#{name} \#{marking}\", type, description) do |value|\n        options[bin] = {} unless options[bin].is_a?(Hash)\n        options[bin][option_definition.name.to_sym] = value\n      end\n    end\n  end\n\n  op.separator nil\n  op.separator '  Common options:'\n\n  op.on_tail('-v', '--verbose', 'Verbose output') do\n    options[:verbose] = true\n  end\n\n  op.on_tail('-h', '--help', 'Show help and exit') do\n    puts op.help\n    exit\n  end\n\n  op.on_tail('--version', 'Show version and exit') do\n    puts ImageOptim.version\n    exit\n  end\n\n  op.on_tail('--info', 'Show environment info and exit') do\n    options[:verbose] = true\n    options[:only_info] = true\n  end\nend\n".gsub(/^\s*\|/, '')

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options) ⇒ OptionParser

After initialization passes self and options to DEFINE



27
28
29
30
# File 'lib/image_optim/runner/option_parser.rb', line 27

def initialize(options)
  super
  DEFINE.call(self, options)
end

Class Method Details

.parse!(args) ⇒ Object

Parse and remove options from args, return options Hash Calls abort in case of parse error



14
15
16
17
18
19
20
21
22
23
24
# File 'lib/image_optim/runner/option_parser.rb', line 14

def self.parse!(args)
  # assume -v to be a request to print version if it is the only argument
  args = %w[--version] if args == %w[-v]

  options = {}
  parser = new(options)
  parser.parse!(args)
  options
rescue OptionParser::ParseError => e
  abort "#{e}\n\n#{parser.help}"
end

Instance Method Details

#helpObject

Wraps and indents lines of overriden method



33
34
35
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/image_optim/runner/option_parser.rb', line 33

def help
  text = super

  # reserve one column
  columns = terminal_columns - 1
  # 1 for distance between summary and description
  # 2 for additional indent
  wrapped_indent = summary_indent + ' ' * (summary_width + 1 + 2)
  wrapped_width = columns - wrapped_indent.length
  # don't try to wrap if there is too little space for description
  return text if wrapped_width < 20

  wrapped = ''
  text.split("\n").each do |line|
    if line.length <= columns
      wrapped << line << "\n"
    else
      indented = line =~ /^\s/
      wrapped << line.slice!(wrap_regex(columns)) << "\n"
      line.scan(wrap_regex(wrapped_width)) do |part|
        wrapped << wrapped_indent if indented
        wrapped << part << "\n"
      end
    end
  end
  wrapped
end