diff --git a/lib/middleman-imageoptim/extension.rb b/lib/middleman-imageoptim/extension.rb index 1c14ce8..3d02560 100644 --- a/lib/middleman-imageoptim/extension.rb +++ b/lib/middleman-imageoptim/extension.rb @@ -4,6 +4,25 @@ module Middleman # Middleman extension entry point module Imageoptim class Extension < Middleman::Extension + if Gem::Version.new(Middleman::VERSION) >= Gem::Version.new('4.0.0') + option :advpng, { level: 4 }, '' + option :allow_lossy, false, '' + option :gifsicle, { interlace: false }, '' + option :image_extensions, %w(.png .jpg .jpeg .gif .svg), '' + option :jpegoptim, { strip: ['all'], max_quality: 100 }, '' + option :jpegtran, { copy_chunks: false, progressive: true, jpegrescan: true }, '' + option :nice, true, '' + option :manifest, true, '' + option :optipng, { level: 6, interlace: false }, '' + option :pack, true, '' + option :pngcrush, { chunks: ['alla'], fix: false, brute: false }, '' + option :pngout, { copy_chunks: false, strategy: 0 }, '' + option :skip_missing_workers, true, '' + option :svgo, {}, '' + option :threads, true, '' + option :verbose, false, '' + end + def after_build(builder) Middleman::Imageoptim::Optimizer.optimize!(app, builder, options) end @@ -16,9 +35,13 @@ def manipulate_resource_list(resources) private def setup_options(options_hash = {}, &_block) - @options = Middleman::Imageoptim::Options.new(options_hash) - yield @options if block_given? - @options.freeze + if Gem::Version.new(Middleman::VERSION) >= Gem::Version.new('4.0.0') + super + else + @options = Middleman::Imageoptim::Options.new(options_hash) + yield @options if block_given? + @options.freeze + end end end end diff --git a/lib/middleman-imageoptim/optimizer.rb b/lib/middleman-imageoptim/optimizer.rb index cda579d..52bd750 100644 --- a/lib/middleman-imageoptim/optimizer.rb +++ b/lib/middleman-imageoptim/optimizer.rb @@ -96,7 +96,15 @@ def builder_thor end def optimizer - @optimizer ||= ImageOptim.new(options.imageoptim_options) + @optimizer ||= begin + imageoptim_options = if Gem::Version.new(Middleman::VERSION) >= Gem::Version.new('4.0.0') + options.to_h.except(:image_extensions, :manifest) + else + options.imageoptim_options + end + + ImageOptim.new(imageoptim_options) + end end def manifest diff --git a/lib/middleman-imageoptim/options.rb b/lib/middleman-imageoptim/options.rb index c29995a..2d2a83f 100644 --- a/lib/middleman-imageoptim/options.rb +++ b/lib/middleman-imageoptim/options.rb @@ -1,53 +1,55 @@ -module Middleman - module Imageoptim - # An options store that handles default options will accept user defined - # overrides - class Options - # Mapping of valid option names to default values - EXTENSION_OPTIONS = [ - :image_extensions, - :manifest - ].freeze - OPTIONS = { - advpng: { level: 4 }, - allow_lossy: false, - gifsicle: { interlace: false }, - image_extensions: %w(.png .jpg .jpeg .gif .svg), - jpegoptim: { strip: ['all'], max_quality: 100 }, - jpegtran: { copy_chunks: false, progressive: true, jpegrescan: true }, - nice: true, - manifest: true, - optipng: { level: 6, interlace: false }, - pack: true, - pngcrush: { chunks: ['alla'], fix: false, brute: false }, - pngout: { copy_chunks: false, strategy: 0 }, - skip_missing_workers: true, - svgo: {}, - threads: true, - verbose: false - }.freeze +if Gem::Version.new(Middleman::VERSION) < Gem::Version.new('4.0.0') + module Middleman + module Imageoptim + # An options store that handles default options will accept user defined + # overrides + class Options + # Mapping of valid option names to default values + EXTENSION_OPTIONS = [ + :image_extensions, + :manifest + ].freeze + OPTIONS = { + advpng: { level: 4 }, + allow_lossy: false, + gifsicle: { interlace: false }, + image_extensions: %w(.png .jpg .jpeg .gif .svg), + jpegoptim: { strip: ['all'], max_quality: 100 }, + jpegtran: { copy_chunks: false, progressive: true, jpegrescan: true }, + nice: true, + manifest: true, + optipng: { level: 6, interlace: false }, + pack: true, + pngcrush: { chunks: ['alla'], fix: false, brute: false }, + pngout: { copy_chunks: false, strategy: 0 }, + skip_missing_workers: true, + svgo: {}, + threads: true, + verbose: false + }.freeze - attr_accessor *OPTIONS.keys.map(&:to_sym) + attr_accessor *OPTIONS.keys.map(&:to_sym) - def initialize(user_options = {}) - set_options(user_options) - end + def initialize(user_options = {}) + set_options(user_options) + end - def imageoptim_options - Hash[instance_variables.map do |name| - [symbolize_key(name), instance_variable_get(name)] - end].reject { |key| EXTENSION_OPTIONS.include?(key) } - end + def imageoptim_options + Hash[instance_variables.map do |name| + [symbolize_key(name), instance_variable_get(name)] + end].reject { |key| EXTENSION_OPTIONS.include?(key) } + end - private + private - def symbolize_key(key) - key.to_s[1..-1].to_sym - end + def symbolize_key(key) + key.to_s[1..-1].to_sym + end - def set_options(user_options) - OPTIONS.keys.each do |name| - instance_variable_set(:"@#{name}", user_options.fetch(name, OPTIONS[name])) + def set_options(user_options) + OPTIONS.keys.each do |name| + instance_variable_set(:"@#{name}", user_options.fetch(name, OPTIONS[name])) + end end end end diff --git a/spec/unit/options_spec.rb b/spec/unit/options_spec.rb index 251dad3..5e92d5b 100644 --- a/spec/unit/options_spec.rb +++ b/spec/unit/options_spec.rb @@ -1,126 +1,128 @@ -require 'spec_helper' -require_relative '../../lib/middleman-imageoptim/options' +if Gem::Version.new(Middleman::VERSION) < Gem::Version.new('4.0.0') + require 'spec_helper' + require_relative '../../lib/middleman-imageoptim/options' -describe Middleman::Imageoptim::Options do - let(:options_hash) { {} } - let(:instance) { described_class.new(options_hash) } - subject { instance } + describe Middleman::Imageoptim::Options do + let(:options_hash) { {} } + let(:instance) { described_class.new(options_hash) } + subject { instance } - describe 'default options' do - its(:verbose) { should be_falsey } - its(:nice) { should be_truthy } - its(:threads) { should be_truthy } - its(:skip_missing_workers) { should be_truthy } - its(:allow_lossy) { should be_falsey } - its(:image_extensions) { should == ['.png', '.jpg', '.jpeg', '.gif', '.svg'] } - its(:pngcrush) { should == { chunks: ['alla'], fix: false, brute: false } } - its(:pngout) { should == { copy_chunks: false, strategy: 0 } } - its(:optipng) { should == { level: 6, interlace: false } } - its(:advpng) { should == { level: 4 } } - its(:jpegoptim) { should == { strip: ['all'], max_quality: 100 } } - its(:jpegtran) { should == { copy_chunks: false, progressive: true, jpegrescan: true } } - its(:gifsicle) { should == { interlace: false } } - its(:svgo) { should == {} } - end + describe 'default options' do + its(:verbose) { should be_falsey } + its(:nice) { should be_truthy } + its(:threads) { should be_truthy } + its(:skip_missing_workers) { should be_truthy } + its(:allow_lossy) { should be_falsey } + its(:image_extensions) { should == ['.png', '.jpg', '.jpeg', '.gif', '.svg'] } + its(:pngcrush) { should == { chunks: ['alla'], fix: false, brute: false } } + its(:pngout) { should == { copy_chunks: false, strategy: 0 } } + its(:optipng) { should == { level: 6, interlace: false } } + its(:advpng) { should == { level: 4 } } + its(:jpegoptim) { should == { strip: ['all'], max_quality: 100 } } + its(:jpegtran) { should == { copy_chunks: false, progressive: true, jpegrescan: true } } + its(:gifsicle) { should == { interlace: false } } + its(:svgo) { should == {} } + end - describe 'getting options for imageoptim' do - describe '#imageoptim_options' do - subject { instance.imageoptim_options } - let(:options_hash) do - { verbose: true, manifest: false, image_extensions: ['.gif'] } - end - it do - is_expected.to eql( - advpng: { level: 4 }, - allow_lossy: false, - gifsicle: { interlace: false }, - jpegoptim: { strip: ['all'], max_quality: 100 }, - jpegtran: { copy_chunks: false, progressive: true, jpegrescan: true }, - nice: true, - optipng: { level: 6, interlace: false }, - pack: true, - pngcrush: { chunks: ['alla'], fix: false, brute: false }, - pngout: { copy_chunks: false, strategy: 0 }, - skip_missing_workers: true, - svgo: {}, - threads: true, - verbose: true - ) + describe 'getting options for imageoptim' do + describe '#imageoptim_options' do + subject { instance.imageoptim_options } + let(:options_hash) do + { verbose: true, manifest: false, image_extensions: ['.gif'] } + end + it do + is_expected.to eql( + advpng: { level: 4 }, + allow_lossy: false, + gifsicle: { interlace: false }, + jpegoptim: { strip: ['all'], max_quality: 100 }, + jpegtran: { copy_chunks: false, progressive: true, jpegrescan: true }, + nice: true, + optipng: { level: 6, interlace: false }, + pack: true, + pngcrush: { chunks: ['alla'], fix: false, brute: false }, + pngout: { copy_chunks: false, strategy: 0 }, + skip_missing_workers: true, + svgo: {}, + threads: true, + verbose: true + ) + end end end - end - describe 'with user options' do - describe '#verbose' do - subject { instance.verbose } - let(:options_hash) { { verbose: true } } - it { is_expected.to be_truthy } - end + describe 'with user options' do + describe '#verbose' do + subject { instance.verbose } + let(:options_hash) { { verbose: true } } + it { is_expected.to be_truthy } + end - describe '#nice' do - subject { instance.nice } - let(:options_hash) { { nice: false } } - it { is_expected.to be_falsey } - end + describe '#nice' do + subject { instance.nice } + let(:options_hash) { { nice: false } } + it { is_expected.to be_falsey } + end - describe '#threads' do - subject { instance.threads } - let(:options_hash) { { threads: false } } - it { is_expected.to be_falsey } - end + describe '#threads' do + subject { instance.threads } + let(:options_hash) { { threads: false } } + it { is_expected.to be_falsey } + end - describe '#image_extensions' do - subject { instance.image_extensions } - let(:options_hash) { { image_extensions: ['.gif'] } } - it { is_expected.to eq(['.gif']) } - end + describe '#image_extensions' do + subject { instance.image_extensions } + let(:options_hash) { { image_extensions: ['.gif'] } } + it { is_expected.to eq(['.gif']) } + end - describe '#pngcrush_options' do - subject { instance.pngcrush } - let(:options_hash) { { pngcrush: { foo: 'bar' } } } - it { is_expected.to eq(foo: 'bar') } - end + describe '#pngcrush_options' do + subject { instance.pngcrush } + let(:options_hash) { { pngcrush: { foo: 'bar' } } } + it { is_expected.to eq(foo: 'bar') } + end - describe '#pngout' do - subject { instance.pngout } - let(:options_hash) { { pngout: { foo: 'bar' } } } - it { is_expected.to eq(foo: 'bar') } - end + describe '#pngout' do + subject { instance.pngout } + let(:options_hash) { { pngout: { foo: 'bar' } } } + it { is_expected.to eq(foo: 'bar') } + end - describe '#optipng' do - subject { instance.optipng } - let(:options_hash) { { optipng: { foo: 'bar' } } } - it { is_expected.to eq(foo: 'bar') } - end + describe '#optipng' do + subject { instance.optipng } + let(:options_hash) { { optipng: { foo: 'bar' } } } + it { is_expected.to eq(foo: 'bar') } + end - describe '#advpng' do - subject { instance.advpng } - let(:options_hash) { { advpng: { foo: 'bar' } } } - it { is_expected.to eq(foo: 'bar') } - end + describe '#advpng' do + subject { instance.advpng } + let(:options_hash) { { advpng: { foo: 'bar' } } } + it { is_expected.to eq(foo: 'bar') } + end - describe '#jpegoptim' do - subject { instance.jpegoptim } - let(:options_hash) { { jpegoptim: { foo: 'bar' } } } - it { is_expected.to eq(foo: 'bar') } - end + describe '#jpegoptim' do + subject { instance.jpegoptim } + let(:options_hash) { { jpegoptim: { foo: 'bar' } } } + it { is_expected.to eq(foo: 'bar') } + end - describe '#jpegtran' do - subject { instance.jpegtran } - let(:options_hash) { { jpegtran: { foo: 'bar' } } } - it { is_expected.to eq(foo: 'bar') } - end + describe '#jpegtran' do + subject { instance.jpegtran } + let(:options_hash) { { jpegtran: { foo: 'bar' } } } + it { is_expected.to eq(foo: 'bar') } + end - describe '#gifsicle' do - subject { instance.gifsicle } - let(:options_hash) { { gifsicle: { foo: 'bar' } } } - it { is_expected.to eq(foo: 'bar') } - end + describe '#gifsicle' do + subject { instance.gifsicle } + let(:options_hash) { { gifsicle: { foo: 'bar' } } } + it { is_expected.to eq(foo: 'bar') } + end - describe '#svgo' do - subject { instance.svgo } - let(:options_hash) { { svgo: { foo: 'bar' } } } - it { is_expected.to eq(foo: 'bar') } + describe '#svgo' do + subject { instance.svgo } + let(:options_hash) { { svgo: { foo: 'bar' } } } + it { is_expected.to eq(foo: 'bar') } + end end end end