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 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 for images') do |recursive|\n    options[:recursive] = recursive\n  end\n\n  op.on(\"--exclude-dir 'GLOB'\", 'Glob for excluding directories (defaults to .*)') do |glob|\n    options[:exclude_dir_glob] = glob\n  end\n\n  op.on(\"--exclude-file 'GLOB'\", 'Glob for excluding files (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 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 (defaults to number of processors)') do |threads|\n    options[:threads] = threads\n  end\n\n  op.on(\n    '--[no-]nice N',\n    Integer,\n    'Nice level, priority of all used tools 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)'\n  ) do |nice|\n    options[:nice] = nice\n  end\n\n  op.on(\n    '--[no-]pack',\n    'Require image_optim_pack or disable it, by default image_optim_pack will be used if available, will turn on ' \\\n    'skip-missing-workers unless explicitly disabled'\n  ) 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 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 (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 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 optimizations') do |allow_lossy|\n    options[:allow_lossy] = allow_lossy\n  end\n\n  op.on('--timeout N', Float, 'Maximum time in seconds to spend on one image') do |timeout|\n    options[:timeout] = timeout\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\n    op.separator nil unless i == 0\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 type <= Integer\n        [Integer, 'N']\n      when type <= Array\n        [Array, 'a,b,c']\n      when type <= String\n        [String, 'S']\n      when type == ImageOptim::NonNegativeIntegerRange\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(\n    '-v',\n    '--verbose',\n    'Verbose output (show global and worker config, binary resolution log, information about each tool invocation, ' \\\n    'backtrace of exception)'\n  ) 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



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

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



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

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



34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/image_optim/runner/option_parser.rb', line 34

def help
  text = super

  # reserve one column and limit to 120
  columns = [terminal_columns - 1, 120].min
  # 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(text, wrapped_width, wrapped_indent, columns)
end