From bbac8958097b644ddad4a9762d4b8fd5939da566 Mon Sep 17 00:00:00 2001 From: Adam Doppelt Date: Tue, 19 Aug 2025 22:01:57 -0700 Subject: [PATCH 1/9] wip --- lib/image_optim.rb | 27 ++++++++++ lib/image_optim/benchmark.rb | 21 ++++++++ lib/image_optim/runner.rb | 64 ++++++++++++++++++++++-- lib/image_optim/runner/option_parser.rb | 5 ++ lib/image_optim/table.rb | 66 +++++++++++++++++++++++++ 5 files changed, 178 insertions(+), 5 deletions(-) create mode 100644 lib/image_optim/benchmark.rb create mode 100644 lib/image_optim/table.rb diff --git a/lib/image_optim.rb b/lib/image_optim.rb index 184d170e..49a558f7 100644 --- a/lib/image_optim.rb +++ b/lib/image_optim.rb @@ -1,5 +1,6 @@ # frozen_string_literal: true +require 'image_optim/benchmark' require 'image_optim/bin_resolver' require 'image_optim/cache' require 'image_optim/config' @@ -8,6 +9,7 @@ require 'image_optim/image_meta' require 'image_optim/optimized_path' require 'image_optim/path' +require 'image_optim/table' require 'image_optim/timer' require 'image_optim/worker' require 'in_threads' @@ -162,6 +164,27 @@ def optimize_image_data(original_data) end end + def benchmark_image(original) + src = Path.convert(original) + return unless (workers = workers_for_image(src)) + + timer = timeout && Timer.new(timeout) + workers.map do |worker| + start = ElapsedTime.now + dst = src.temp_path + begin + begin + worker.optimize(src, dst, timeout: timer) + rescue Errors::TimeoutExceeded + # nop + end + Benchmark.new(src: src, dst: dst, elapsed: (ElapsedTime.now - start), worker: worker) + ensure + dst.unlink + end + end + end + # Optimize multiple images # if block given yields path and result for each image and returns array of # yield results @@ -186,6 +209,10 @@ def optimize_images_data(datas, &block) run_method_for(datas, :optimize_image_data, &block) end + def benchmark_images(paths, &block) + run_method_for(paths, :benchmark_image, &block) + end + class << self # Optimization methods with default options def method_missing(method, *args, &block) diff --git a/lib/image_optim/benchmark.rb b/lib/image_optim/benchmark.rb new file mode 100644 index 00000000..968366a4 --- /dev/null +++ b/lib/image_optim/benchmark.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +class ImageOptim + # Benchmark result for one worker+src + class Benchmark + attr_reader :bytes, :elapsed, :worker + + def initialize(src:, dst:, elapsed:, worker:) + @bytes = bytes_saved(src, dst) + @elapsed = elapsed + @worker = worker.class.bin_sym.to_s + end + + def bytes_saved(src, dst) + src, dst = src.size, dst.size + return 0 if dst == 0 # failure + return 0 if dst > src # the file got bigger + src - dst + end + end +end diff --git a/lib/image_optim/runner.rb b/lib/image_optim/runner.rb index 94a8dba5..d0faf83e 100644 --- a/lib/image_optim/runner.rb +++ b/lib/image_optim/runner.rb @@ -45,10 +45,51 @@ def size_percent(size_a, size_b) end end + # files, elapsed, kb saved, kb/s + class BenchmarkResults + def initialize + @all = [] + end + + def add(_original, rows) + @all.concat(rows) + end + + def print + if @all.empty? + puts 'nothing to report' + return + end + + # group by worker + report = @all.group_by(&:worker).map do |name, results| + kb = (results.sum(&:bytes) / 1024.0) + elapsed = results.sum(&:elapsed) + { + 'name' => name, + 'files' => results.length, + 'elapsed' => elapsed, + 'kb saved' => kb, + 'kb/s' => (kb / elapsed), + } + end + + # sort + report = report.sort_by do |row| + [-row['kb/s'], row['name']] + end + + # output + puts "\nBENCHMARK RESULTS\n\n" + puts Table.new(report) + end + end + def initialize(options) options = HashHelpers.deep_symbolise_keys(options) @recursive = options.delete(:recursive) @progress = options.delete(:show_progress) != false + @benchmark = options.delete(:benchmark) @exclude_dir_globs, @exclude_file_globs = %w[dir file].map do |type| glob = options.delete(:"exclude_#{type}_glob") || '.*' GlobHelpers.expand_braces(glob) @@ -59,13 +100,21 @@ def initialize(options) def run!(args) # rubocop:disable Naming/PredicateMethod to_optimize = find_to_optimize(args) unless to_optimize.empty? - results = Results.new + if @benchmark + benchmark_results = BenchmarkResults.new + benchmark_images(to_optimize).each do |original, bm| + benchmark_results.add(original, bm) + end + benchmark_results.print + else + results = Results.new - optimize_images!(to_optimize).each do |original, optimized| - results.add(original, optimized) - end + optimize_images!(to_optimize).each do |original, optimized| + results.add(original, optimized) + end - results.print + results.print + end end !@warnings @@ -73,6 +122,11 @@ def run!(args) # rubocop:disable Naming/PredicateMethod private + def benchmark_images(to_optimize, &block) + to_optimize = to_optimize.with_progress('benchmarking') if @progress + @image_optim.benchmark_images(to_optimize, &block) + end + def optimize_images!(to_optimize, &block) to_optimize = to_optimize.with_progress('optimizing') if @progress @image_optim.optimize_images!(to_optimize, &block) diff --git a/lib/image_optim/runner/option_parser.rb b/lib/image_optim/runner/option_parser.rb index 3af60c52..f051d98e 100644 --- a/lib/image_optim/runner/option_parser.rb +++ b/lib/image_optim/runner/option_parser.rb @@ -153,6 +153,11 @@ def wrap_regex(width) options[:pack] = pack end + op.separator nil + op.on('--benchmark', 'Run in benchmark mode, to compare tools without modifying images') do + options[:benchmark] = true + end + op.separator nil op.separator ' Caching:' diff --git a/lib/image_optim/table.rb b/lib/image_optim/table.rb new file mode 100644 index 00000000..9cb8f1d2 --- /dev/null +++ b/lib/image_optim/table.rb @@ -0,0 +1,66 @@ +# frozen_string_literal: true + +class ImageOptim + # Handy class for pretty printing a table in the terminal. This is very simple, switch to Terminal + # Table, Table Tennis or similar if we need more. + class Table + attr_reader :rows + + def initialize(rows) + @rows = rows + end + + def to_s + lines = [] + lines << render_row(columns) + lines << render_sep + rows.each do |row| + lines << render_row(row.values) + end + lines.join("\n") + end + + protected + + # array of column names + def columns + @columns ||= rows.first.keys + end + + # should columns be justified left or right? + def justs + @justs ||= columns.map do |col| + rows.first[col].is_a?(Numeric) ? :rjust : :ljust + end + end + + # max width of each column + def widths + @widths ||= columns.map do |col| + values = rows.map{ |row| fmt(row[col]) } + ([col] + values).map(&:length).max + end + end + + # render an array of row values + def render_row(values) + values.map.with_index do |value, ii| + fmt(value).send(justs[ii], widths[ii]) + end.join(' ') + end + + # render a separator line + def render_sep + render_row(widths.map{ |width| '-' * width }) + end + + # format one cell value + def fmt(value) + if value.is_a?(Float) + format('%0.3f', value) + else + value.to_s + end + end + end +end From eb6e931eb54d8504a4427dbbfd47258942e8a8a1 Mon Sep 17 00:00:00 2001 From: Adam Doppelt Date: Wed, 20 Aug 2025 09:59:14 -0700 Subject: [PATCH 2/9] ruby 1.9 fix --- lib/image_optim/benchmark.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/image_optim/benchmark.rb b/lib/image_optim/benchmark.rb index 968366a4..143b6d35 100644 --- a/lib/image_optim/benchmark.rb +++ b/lib/image_optim/benchmark.rb @@ -5,7 +5,7 @@ class ImageOptim class Benchmark attr_reader :bytes, :elapsed, :worker - def initialize(src:, dst:, elapsed:, worker:) + def initialize(src: nil, dst: nil, elapsed: nil, worker: nil) @bytes = bytes_saved(src, dst) @elapsed = elapsed @worker = worker.class.bin_sym.to_s @@ -15,6 +15,7 @@ def bytes_saved(src, dst) src, dst = src.size, dst.size return 0 if dst == 0 # failure return 0 if dst > src # the file got bigger + src - dst end end From f631a4c46a17f933a02107c931f61dafb811fd25 Mon Sep 17 00:00:00 2001 From: Adam Doppelt Date: Wed, 20 Aug 2025 10:01:55 -0700 Subject: [PATCH 3/9] ruby 1.9 fix --- lib/image_optim.rb | 2 +- lib/image_optim/benchmark.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/image_optim.rb b/lib/image_optim.rb index 49a558f7..69920f3a 100644 --- a/lib/image_optim.rb +++ b/lib/image_optim.rb @@ -178,7 +178,7 @@ def benchmark_image(original) rescue Errors::TimeoutExceeded # nop end - Benchmark.new(src: src, dst: dst, elapsed: (ElapsedTime.now - start), worker: worker) + Benchmark.new(src, dst, ElapsedTime.now - start, worker) ensure dst.unlink end diff --git a/lib/image_optim/benchmark.rb b/lib/image_optim/benchmark.rb index 143b6d35..8bd7266e 100644 --- a/lib/image_optim/benchmark.rb +++ b/lib/image_optim/benchmark.rb @@ -5,7 +5,7 @@ class ImageOptim class Benchmark attr_reader :bytes, :elapsed, :worker - def initialize(src: nil, dst: nil, elapsed: nil, worker: nil) + def initialize(src, dst, elapsed, worker) @bytes = bytes_saved(src, dst) @elapsed = elapsed @worker = worker.class.bin_sym.to_s From b63e1dccc39ab3b08a86fca7952c33d053a68b65 Mon Sep 17 00:00:00 2001 From: Adam Doppelt Date: Wed, 3 Sep 2025 08:56:31 -0700 Subject: [PATCH 4/9] PR feedback --- CHANGELOG.markdown | 1 + README.markdown | 21 +++++++++++++++++++++ lib/image_optim.rb | 9 ++------- lib/image_optim/benchmark.rb | 4 +++- lib/image_optim/config.rb | 3 +++ lib/image_optim/runner.rb | 19 ++++++++++++++----- lib/image_optim/table.rb | 14 ++++++-------- spec/image_optim_spec.rb | 14 ++++++++++++++ 8 files changed, 64 insertions(+), 21 deletions(-) diff --git a/CHANGELOG.markdown b/CHANGELOG.markdown index 507fbd0c..965a74d1 100644 --- a/CHANGELOG.markdown +++ b/CHANGELOG.markdown @@ -3,6 +3,7 @@ ## unreleased * Correct environment variable to specify `jpeg-recompress` location [@toy](https://github.com/toy) +* Added --benchmark, to compare performance of each tool [#218] ## v0.31.4 (2024-11-19) diff --git a/README.markdown b/README.markdown index a6f46fbe..6edee407 100644 --- a/README.markdown +++ b/README.markdown @@ -301,6 +301,27 @@ optipng: `image_optim` uses standard ruby library for creating temporary files. Temporary directory can be changed using one of `TMPDIR`, `TMP` or `TEMP` environment variables. +### Benchmark + +Run with `--benchmark` to compare the performance of each individual tool on your images: + +``` +$ image_optim --benchmark -r /tmp/corpus/ + +benchmarking: 100.0% (elapsed: 3.9m) + +BENCHMARK RESULTS + +name files elapsed kb saved kb/s +-------- ----- ------- -------- ------- +oxipng 50 8.906 1867.253 209.664 +pngquant 50 1.980 214.597 108.386 +pngcrush 50 22.529 1753.704 77.841 +optipng 50 142.940 1641.101 11.481 +advpng 50 137.753 962.549 6.987 +pngout 50 426.706 444.679 1.042 +``` + ## Options * `:nice` — Nice level, priority of all used tools with higher value meaning lower priority, in range `-20..19`, negative values can be set only if run by root user *(defaults to `10`)* diff --git a/lib/image_optim.rb b/lib/image_optim.rb index 69920f3a..3c98f2ff 100644 --- a/lib/image_optim.rb +++ b/lib/image_optim.rb @@ -168,17 +168,12 @@ def benchmark_image(original) src = Path.convert(original) return unless (workers = workers_for_image(src)) - timer = timeout && Timer.new(timeout) workers.map do |worker| start = ElapsedTime.now dst = src.temp_path begin - begin - worker.optimize(src, dst, timeout: timer) - rescue Errors::TimeoutExceeded - # nop - end - Benchmark.new(src, dst, ElapsedTime.now - start, worker) + worker.optimize(src, dst) + BenchmarkResult.new(src, dst, ElapsedTime.now - start, worker) ensure dst.unlink end diff --git a/lib/image_optim/benchmark.rb b/lib/image_optim/benchmark.rb index 8bd7266e..81041bfb 100644 --- a/lib/image_optim/benchmark.rb +++ b/lib/image_optim/benchmark.rb @@ -2,7 +2,7 @@ class ImageOptim # Benchmark result for one worker+src - class Benchmark + class BenchmarkResult attr_reader :bytes, :elapsed, :worker def initialize(src, dst, elapsed, worker) @@ -11,6 +11,8 @@ def initialize(src, dst, elapsed, worker) @worker = worker.class.bin_sym.to_s end + private + def bytes_saved(src, dst) src, dst = src.size, dst.size return 0 if dst == 0 # failure diff --git a/lib/image_optim/config.rb b/lib/image_optim/config.rb index 9b27be09..048d16a8 100644 --- a/lib/image_optim/config.rb +++ b/lib/image_optim/config.rb @@ -117,6 +117,9 @@ def threads case threads when true, nil + # --benchmark defaults to one thread + return 1 if get!(:benchmark) + processor_count when false 1 diff --git a/lib/image_optim/runner.rb b/lib/image_optim/runner.rb index d0faf83e..19e692cc 100644 --- a/lib/image_optim/runner.rb +++ b/lib/image_optim/runner.rb @@ -51,7 +51,7 @@ def initialize @all = [] end - def add(_original, rows) + def add(rows) @all.concat(rows) end @@ -81,7 +81,7 @@ def print # output puts "\nBENCHMARK RESULTS\n\n" - puts Table.new(report) + Table.new(report).write($stdout) end end @@ -89,11 +89,20 @@ def initialize(options) options = HashHelpers.deep_symbolise_keys(options) @recursive = options.delete(:recursive) @progress = options.delete(:show_progress) != false - @benchmark = options.delete(:benchmark) @exclude_dir_globs, @exclude_file_globs = %w[dir file].map do |type| glob = options.delete(:"exclude_#{type}_glob") || '.*' GlobHelpers.expand_braces(glob) end + + # --benchmark + @benchmark = options.delete(:benchmark) + if @benchmark + options[:threads] = 1 # for consistency + if options[:timeout] + warning '--benchmark ignores --timeout' + end + end + @image_optim = ImageOptim.new(options) end @@ -102,8 +111,8 @@ def run!(args) # rubocop:disable Naming/PredicateMethod unless to_optimize.empty? if @benchmark benchmark_results = BenchmarkResults.new - benchmark_images(to_optimize).each do |original, bm| - benchmark_results.add(original, bm) + benchmark_images(to_optimize).each do |_original, rows| + benchmark_results.add(rows) end benchmark_results.print else diff --git a/lib/image_optim/table.rb b/lib/image_optim/table.rb index 9cb8f1d2..ec458485 100644 --- a/lib/image_optim/table.rb +++ b/lib/image_optim/table.rb @@ -10,14 +10,12 @@ def initialize(rows) @rows = rows end - def to_s - lines = [] - lines << render_row(columns) - lines << render_sep + def write(io) + io.puts render_row(columns) + io.puts render_sep rows.each do |row| - lines << render_row(row.values) + io.puts render_row(row.values) end - lines.join("\n") end protected @@ -44,8 +42,8 @@ def widths # render an array of row values def render_row(values) - values.map.with_index do |value, ii| - fmt(value).send(justs[ii], widths[ii]) + values.zip(justs, widths).map do |value, just, width| + fmt(value).send(just, width) end.join(' ') end diff --git a/spec/image_optim_spec.rb b/spec/image_optim_spec.rb index 6a651258..76d46586 100644 --- a/spec/image_optim_spec.rb +++ b/spec/image_optim_spec.rb @@ -269,6 +269,20 @@ def temp_copy(image) end end + describe 'benchmark_images' do + it 'does it' do + image_optim = ImageOptim.new + pairs = image_optim.benchmark_images(test_images) + test_images.zip(pairs).each do |original, (src, bm)| + expect(original).to equal(src) + expect(bm[0]).to be_a(ImageOptim::BenchmarkResult) + expect(bm[0].bytes).to be_a(Numeric) + expect(bm[0].elapsed).to be_a(Numeric) + expect(bm[0].worker).to be_a(String) + end + end + end + %w[ optimize_image optimize_image! From 49ad630821f51b0f3838c16d6de7f49b192bc9e0 Mon Sep 17 00:00:00 2001 From: Adam Doppelt Date: Wed, 3 Sep 2025 09:04:45 -0700 Subject: [PATCH 5/9] fix a rubocop warning --- lib/image_optim/runner.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/image_optim/runner.rb b/lib/image_optim/runner.rb index 19e692cc..20e19132 100644 --- a/lib/image_optim/runner.rb +++ b/lib/image_optim/runner.rb @@ -111,7 +111,7 @@ def run!(args) # rubocop:disable Naming/PredicateMethod unless to_optimize.empty? if @benchmark benchmark_results = BenchmarkResults.new - benchmark_images(to_optimize).each do |_original, rows| + benchmark_images(to_optimize).each do |_original, rows| # rubocop:disable Style/HashEachMethods benchmark_results.add(rows) end benchmark_results.print From c844f00bf64d111498e5d10769603768049773c9 Mon Sep 17 00:00:00 2001 From: Adam Doppelt Date: Tue, 23 Sep 2025 18:42:35 -0700 Subject: [PATCH 6/9] PR feedback round 2 --- CHANGELOG.markdown | 2 +- README.markdown | 4 +++- lib/image_optim.rb | 2 +- lib/image_optim/{benchmark.rb => benchmark_result.rb} | 0 lib/image_optim/config.rb | 3 --- lib/image_optim/runner.rb | 5 ++++- 6 files changed, 9 insertions(+), 7 deletions(-) rename lib/image_optim/{benchmark.rb => benchmark_result.rb} (100%) diff --git a/CHANGELOG.markdown b/CHANGELOG.markdown index 965a74d1..95efa3d9 100644 --- a/CHANGELOG.markdown +++ b/CHANGELOG.markdown @@ -3,7 +3,7 @@ ## unreleased * Correct environment variable to specify `jpeg-recompress` location [@toy](https://github.com/toy) -* Added --benchmark, to compare performance of each tool [#218] +* Added --benchmark, to compare performance of each tool [#217](https://github.com/toy/image_optim/issues/217) [#218](https://github.com/toy/image_optim/pull/218) [@gurgeous](https://github.com/gurgeous) ## v0.31.4 (2024-11-19) diff --git a/README.markdown b/README.markdown index 6edee407..7cbfe9b6 100644 --- a/README.markdown +++ b/README.markdown @@ -305,9 +305,11 @@ optipng: Run with `--benchmark` to compare the performance of each individual tool on your images: +```sh +image_optim --benchmark -r /tmp/corpus/ ``` -$ image_optim --benchmark -r /tmp/corpus/ +``` benchmarking: 100.0% (elapsed: 3.9m) BENCHMARK RESULTS diff --git a/lib/image_optim.rb b/lib/image_optim.rb index 3c98f2ff..dcf0e33c 100644 --- a/lib/image_optim.rb +++ b/lib/image_optim.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -require 'image_optim/benchmark' +require 'image_optim/benchmark_result' require 'image_optim/bin_resolver' require 'image_optim/cache' require 'image_optim/config' diff --git a/lib/image_optim/benchmark.rb b/lib/image_optim/benchmark_result.rb similarity index 100% rename from lib/image_optim/benchmark.rb rename to lib/image_optim/benchmark_result.rb diff --git a/lib/image_optim/config.rb b/lib/image_optim/config.rb index 048d16a8..9b27be09 100644 --- a/lib/image_optim/config.rb +++ b/lib/image_optim/config.rb @@ -117,9 +117,6 @@ def threads case threads when true, nil - # --benchmark defaults to one thread - return 1 if get!(:benchmark) - processor_count when false 1 diff --git a/lib/image_optim/runner.rb b/lib/image_optim/runner.rb index 20e19132..02cee96e 100644 --- a/lib/image_optim/runner.rb +++ b/lib/image_optim/runner.rb @@ -97,7 +97,10 @@ def initialize(options) # --benchmark @benchmark = options.delete(:benchmark) if @benchmark - options[:threads] = 1 # for consistency + unless options[:threads].nil? + warning '--benchmark ignores --threads' + options[:threads] = 1 # for consistency + end if options[:timeout] warning '--benchmark ignores --timeout' end From 78e1855508caef378151b965512076dbc65b3510 Mon Sep 17 00:00:00 2001 From: Adam Doppelt Date: Thu, 2 Oct 2025 08:17:49 -0700 Subject: [PATCH 7/9] --benchmark isolated --- lib/image_optim/runner/option_parser.rb | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/image_optim/runner/option_parser.rb b/lib/image_optim/runner/option_parser.rb index f051d98e..270d09e9 100644 --- a/lib/image_optim/runner/option_parser.rb +++ b/lib/image_optim/runner/option_parser.rb @@ -154,8 +154,12 @@ def wrap_regex(width) end op.separator nil - op.on('--benchmark', 'Run in benchmark mode, to compare tools without modifying images') do - options[:benchmark] = true + op.on('--benchmark [MODE]', String, 'Run benchmarks, to compare tools without modifying images (defaults ' \ + 'to `isolated` mode)') do |benchmark| + options[:benchmark] = benchmark || 'isolated' + if options[:benchmark] != 'isolated' + fail OptionParser::ParseError, '--benchmark must be `isolated`' + end end op.separator nil From ddcfe7536820101f2dfd3485be7ffd0819a96b2a Mon Sep 17 00:00:00 2001 From: Adam Doppelt Date: Sat, 4 Oct 2025 20:24:36 -0700 Subject: [PATCH 8/9] PR feedback --- lib/image_optim.rb | 2 ++ lib/image_optim/runner/option_parser.rb | 12 ++++++------ 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/lib/image_optim.rb b/lib/image_optim.rb index dcf0e33c..027f479a 100644 --- a/lib/image_optim.rb +++ b/lib/image_optim.rb @@ -25,6 +25,7 @@ end # Main interface +# rubocop:disable Metrics/ClassLength class ImageOptim # Nice level attr_reader :nice @@ -296,3 +297,4 @@ def apply_threading(enum) end end end +# rubocop:enable Metrics/ClassLength diff --git a/lib/image_optim/runner/option_parser.rb b/lib/image_optim/runner/option_parser.rb index 270d09e9..ad6a21f9 100644 --- a/lib/image_optim/runner/option_parser.rb +++ b/lib/image_optim/runner/option_parser.rb @@ -154,12 +154,12 @@ def wrap_regex(width) end op.separator nil - op.on('--benchmark [MODE]', String, 'Run benchmarks, to compare tools without modifying images (defaults ' \ - 'to `isolated` mode)') do |benchmark| - options[:benchmark] = benchmark || 'isolated' - if options[:benchmark] != 'isolated' - fail OptionParser::ParseError, '--benchmark must be `isolated`' - end + op.on( + '--benchmark TYPE', + [:isolated], + 'Run benchmarks, to compare tools without modifying images. `isolated` is the only supported type so far.' + ) do |benchmark| + options[:benchmark] = benchmark end op.separator nil From 419eff26c9fd814f58871a901f7b79b8fa074e10 Mon Sep 17 00:00:00 2001 From: Adam Doppelt Date: Sat, 4 Oct 2025 20:26:19 -0700 Subject: [PATCH 9/9] PR feedback --- .rubocop.yml | 2 ++ lib/image_optim.rb | 2 -- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index fe795817..2ef5056a 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -67,6 +67,8 @@ Metrics/BlockLength: - 'spec/**/*.rb' Metrics/ClassLength: + Exclude: + - 'lib/image_optim.rb' Max: 150 Metrics/CyclomaticComplexity: diff --git a/lib/image_optim.rb b/lib/image_optim.rb index 027f479a..dcf0e33c 100644 --- a/lib/image_optim.rb +++ b/lib/image_optim.rb @@ -25,7 +25,6 @@ end # Main interface -# rubocop:disable Metrics/ClassLength class ImageOptim # Nice level attr_reader :nice @@ -297,4 +296,3 @@ def apply_threading(enum) end end end -# rubocop:enable Metrics/ClassLength