middleman-imageoptim 0.1.4 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1a614256397db9fad85c5420cd82494e86601865
4
- data.tar.gz: 31242425727e75d2159c44e6b89ef71c42426532
3
+ metadata.gz: 139f5d4341e9f282b48469c083333f52954d41c2
4
+ data.tar.gz: c43cb5965b95b8628f66e5f7472b7cee64cfe26f
5
5
  SHA512:
6
- metadata.gz: 6f4d987028e5253337be3dadcf1ae59b501022b35d71a11be84052eb7c8bc1b91bb4bdccf6ae5d7efd1cbb374f75d1750b702384170e7187db4130dd72927388
7
- data.tar.gz: 64321b6ca80e4220b7bc0f63a3592c3ded2c39c74d36750b52a3ec67ed3eea3e3e04286205e07b341e46149b9dadffefb7a49f443b28c3257537c722111498a5
6
+ metadata.gz: 84a90a10b3d1867a69b8a99adfd43e407bd80950e52f56e75b03b30fd9add3e9b14ff17a4a85cfcbbf6f6d67530650fbcc5a6de01f7951cb5cdfb3c33ad01fb3
7
+ data.tar.gz: 6cf1a88f097cb595b7db35204fabaa6c21532550132720d63adbed7b53bb5688435c211d3beee32f5a7e3742e1824b8fb1437e2b7ff8af3a15a7f7e2f6ad0af4
data/.gitignore CHANGED
@@ -4,3 +4,5 @@ pkg
4
4
  .bundle
5
5
  bin
6
6
  coverage
7
+ tmp
8
+ fixtures/*/build
@@ -0,0 +1,5 @@
1
+ inherit_from: .rubocop_todo.yml
2
+ AllCops:
3
+ Exclude:
4
+ - 'bin/**/*'
5
+ - 'pkg/**/*'
@@ -0,0 +1,46 @@
1
+ # This configuration was generated by `rubocop --auto-gen-config`
2
+ # on 2015-01-05 15:23:36 +1100 using RuboCop version 0.27.1.
3
+ # The point is for the user to remove these configuration records
4
+ # one by one as the offenses are removed from the code base.
5
+ # Note that changes in the inspected code, or installation of new
6
+ # versions of RuboCop, may require this file to be generated again.
7
+
8
+ # Offense count: 1
9
+ Lint/AmbiguousOperator:
10
+ Enabled: false
11
+
12
+ # Offense count: 1
13
+ Lint/AmbiguousRegexpLiteral:
14
+ Enabled: false
15
+
16
+ # Offense count: 11
17
+ # Configuration parameters: AllowURI, URISchemes.
18
+ Metrics/LineLength:
19
+ Max: 133
20
+
21
+ # Offense count: 1
22
+ # Configuration parameters: CountComments.
23
+ Metrics/MethodLength:
24
+ Max: 11
25
+
26
+ # Offense count: 1
27
+ Style/AccessorMethodName:
28
+ Enabled: false
29
+
30
+ # Offense count: 7
31
+ Style/Documentation:
32
+ Enabled: false
33
+
34
+ # Offense count: 1
35
+ Style/EachWithObject:
36
+ Enabled: false
37
+
38
+ # Offense count: 1
39
+ # Configuration parameters: Exclude.
40
+ Style/FileName:
41
+ Enabled: false
42
+
43
+ # Offense count: 1
44
+ # Configuration parameters: EnforcedStyle, SupportedStyles.
45
+ Style/FormatString:
46
+ Enabled: false
@@ -0,0 +1,7 @@
1
+ SimpleCov.start do
2
+ FileUtils.rm_rf 'coverage'
3
+
4
+ refuse_coverage_drop
5
+ add_filter '/spec/'
6
+ add_filter '/features/'
7
+ end
@@ -1,10 +1,9 @@
1
1
  language: ruby
2
2
  bundler_args: --binstubs
3
3
  rvm:
4
+ - 2.1.0
4
5
  - 2.0.0
5
6
  - 1.9.3
6
- after_success:
7
- - script/quality
8
7
  matrix:
9
8
  include:
10
9
  - rvm: 2.0.0
data/Gemfile CHANGED
@@ -1,12 +1,2 @@
1
- # If you have OpenSSL installed, we recommend updating
2
- # the following line to use "https"
3
- source 'http://rubygems.org'
4
-
5
- # Specify your gem's dependencies in middleman-imageoptim.gemspec
1
+ source 'https://rubygems.org'
6
2
  gemspec
7
-
8
- group :development do
9
- gem "rake", "~> 0.9.2"
10
- gem "rdoc", "~> 3.9"
11
- gem "yard", "~> 0.8.0"
12
- end
data/README.md CHANGED
@@ -5,10 +5,12 @@
5
5
  Serving big images is for numb-skulls! Compress and optimise your imagery during `middleman build` by running [image_optim](https://github.com/toy/image_optim) over it. Aww yiss!
6
6
 
7
7
  [![Build Status](https://travis-ci.org/plasticine/middleman-imageoptim.png?branch=master)](https://travis-ci.org/plasticine/middleman-imageoptim)
8
- [![Coverage Status](https://coveralls.io/repos/plasticine/middleman-imageoptim/badge.png)](https://coveralls.io/r/plasticine/middleman-imageoptim)
8
+ [![Code Climate](https://codeclimate.com/github/plasticine/middleman-imageoptim.png)](https://codeclimate.com/github/plasticine/middleman-imageoptim)
9
9
  [![Gem Version](https://badge.fury.io/rb/middleman-imageoptim.png)](http://badge.fury.io/rb/middleman-imageoptim)
10
10
  [![Dependency Status](https://gemnasium.com/plasticine/middleman-imageoptim.png)](https://gemnasium.com/plasticine/middleman-imageoptim)
11
11
 
12
+ * * *
13
+
12
14
  ![](http://cl.ly/image/0h0b330F2p3C/Terminal%20%E2%80%94%20zsh%20%E2%80%94%20109%C3%9712.png)
13
15
 
14
16
  ## Installation
@@ -16,7 +18,7 @@ Serving big images is for numb-skulls! Compress and optimise your imagery during
16
18
  Go set up the [image_optim](https://github.com/toy/image_optim) external utilities, then;
17
19
 
18
20
  ```ruby
19
- gem "middleman-imageoptim", "~> 0.1.4"
21
+ gem 'middleman-imageoptim'
20
22
  ```
21
23
 
22
24
  ## Usage
@@ -30,7 +32,13 @@ Below is the default configuration showing all available options;
30
32
 
31
33
  ```ruby
32
34
  activate :imageoptim do |options|
33
- # print out skipped images
35
+ # Use a build manifest to prevent re-compressing images between builds
36
+ options.manifest = true
37
+
38
+ # Silence problematic image_optim workers
39
+ options.skip_missing_workers = true
40
+
41
+ # Cause image_optim to be in shouty-mode
34
42
  options.verbose = false
35
43
 
36
44
  # Setting these to true or nil will let options determine them (recommended)
@@ -38,17 +46,18 @@ activate :imageoptim do |options|
38
46
  options.threads = true
39
47
 
40
48
  # Image extensions to attempt to compress
41
- options.image_extensions = %w(.png .jpg .gif)
49
+ options.image_extensions = %w(.png .jpg .gif .svg)
42
50
 
43
- # compressor worker options, individual optimisers can be disabled by passing
51
+ # Compressor worker options, individual optimisers can be disabled by passing
44
52
  # false instead of a hash
45
- options.pngcrush_options = {:chunks => ['alla'], :fix => false, :brute => false}
46
- options.pngout_options = {:copy_chunks => false, :strategy => 0}
47
- options.optipng_options = {:level => 6, :interlace => false}
48
- options.advpng_options = {:level => 4}
49
- options.jpegoptim_options = {:strip => ['all'], :max_quality => 100}
50
- options.jpegtran_options = {:copy_chunks => false, :progressive => true, :jpegrescan => true}
51
- options.gifsicle_options = {:interlace => false}
53
+ options.advpng = { :level => 4 }
54
+ options.gifsicle = { :interlace => false }
55
+ options.jpegoptim = { :strip => ['all'], :max_quality => 100 }
56
+ options.jpegtran = { :copy_chunks => false, :progressive => true, :jpegrescan => true }
57
+ options.optipng = { :level => 6, :interlace => false }
58
+ options.pngcrush = { :chunks => ['alla'], :fix => false, :brute => false }
59
+ options.pngout = { :copy_chunks => false, :strategy => 0 }
60
+ options.svgo = {}
52
61
  end
53
62
  ```
54
63
 
@@ -56,19 +65,26 @@ end
56
65
 
57
66
  ## Changelog
58
67
 
68
+ ##### `0.2.0`
69
+ - Big cleanup to codebase.
70
+ - More tests.
71
+ - Caching between builds using a manifest file to skip over already-compressed assets (thanks for your work on this @jagthedrummer).
72
+ - Updates `image_optim` gem to latest version (`0.20.2`).
73
+ - Adds dependency on `image_optim_pack` to ensure that binaries are available.
74
+
59
75
  ##### `0.1.4`
60
- - Respect plugin ordering in config.rb (thanks @jeffutter) [#8](https://github.com/plasticine/middleman-imageoptim/pull/8)
76
+ - Respect plugin ordering in config.rb (thanks @jeffutter) [#8](https://github.com/plasticine/middleman-imageoptim/pull/8).
61
77
 
62
78
  ##### `0.1.3`
63
- - fix missing license in gemspec
79
+ - Fix missing license in gemspec.
64
80
 
65
81
  ##### `0.1.2`
66
- - minor bugfix
82
+ - Minor bugfix.
67
83
 
68
84
  ##### `0.1.1`
69
- - remove legacy requirement for padrino
85
+ - Remove legacy requirement for padrino.
70
86
 
71
87
  ##### `0.1.0`
72
- - complete refactor and clean-up
73
- - introduced an options class. options now work (lol, yay!), thanks @andrew-aladev for your help there
74
- - change of extension activation name from `:image_optim` to `:imageoptim` for consistency with internal naming
88
+ - Complete refactor and clean-up.
89
+ - Introduced an options class. options now work (lol, yay!), thanks @andrew-aladev for your help there.
90
+ - Change of extension activation name from `:image_optim` to `:imageoptim` for consistency with internal naming.
data/Rakefile CHANGED
@@ -5,29 +5,21 @@ Bundler::GemHelper.install_tasks
5
5
 
6
6
  require 'rake/clean'
7
7
  require 'rspec/core/rake_task'
8
+ require 'cucumber'
9
+ require 'cucumber/rake/task'
8
10
 
9
11
  namespace :spec do
10
- begin
11
- require 'cane/rake_task'
12
- desc "Run cane to check quality metrics"
13
- Cane::RakeTask.new(:quality) do |cane|
14
- cane.abc_max = 10
15
- cane.add_threshold 'coverage/covered_percent', :>=, 74
16
- cane.no_style = true
17
- cane.abc_exclude = %w(Middleman::Imageoptim::Optimizer#optimizer)
18
- end
19
-
20
- task :default => :quality
21
- rescue LoadError
22
- warn "cane not available, quality task not provided."
12
+ desc 'Run unit specs'
13
+ RSpec::Core::RakeTask.new(:unit) do |config|
14
+ config.pattern = 'spec/unit/*_spec.rb'
15
+ config.rspec_opts = '--require spec_helper'
23
16
  end
24
17
 
25
- desc 'Run unit specs'
26
- RSpec::Core::RakeTask.new(:unit) do |spec|
27
- spec.pattern = "spec/unit/*_spec.rb"
28
- spec.rspec_opts = "--require spec_helper"
18
+ desc 'Run feature tests'
19
+ Cucumber::Rake::Task.new(:features) do |config|
20
+ config.cucumber_opts = 'features --format pretty'
29
21
  end
30
22
  end
31
23
 
32
- desc 'Default: run unit tests.'
33
- task :default => ['spec:unit']
24
+ desc 'Default: run the tests.'
25
+ task default: ['spec:unit', 'spec:features']
@@ -0,0 +1,31 @@
1
+ Feature: Manifest
2
+ Scenario: Don't reoptimize images that have already been optimized
3
+ Given a fixture app "basic-app"
4
+ Given a successfully built app at "basic-app" with flags "--verbose"
5
+ Then the following files should exist:
6
+ | build/imageoptim.manifest.yml |
7
+ Then the manifest should have the right timestamp for "build/images/table.jpg"
8
+
9
+ Scenario: Don't write a manifest file if it is disabled
10
+ Given a fixture app "basic-app"
11
+ And app "basic-app" is using config "disabled-manifest"
12
+ Given a successfully built app at "basic-app" with flags "--verbose"
13
+ Then the following files should not exist:
14
+ | build/imageoptim.manifest.yml |
15
+
16
+ Scenario: Skipping optimization when the timestamp hasn't changed
17
+ Given a fixture app "basic-app"
18
+ Given a successfully built app at "basic-app" with flags "--verbose"
19
+ Given a modification time for a file named "build/images/table.jpg"
20
+ Given some time has passed
21
+ Given a successfully built app at "basic-app" with flags "--verbose"
22
+ Then the file "build/images/table.jpg" should not have been updated
23
+
24
+ Scenario: Regenerating the build image if the source has changed
25
+ Given a fixture app "basic-app"
26
+ Given a successfully built app at "basic-app" with flags "--verbose"
27
+ Given a modification time for a file named "build/images/table.jpg"
28
+ Given some time has passed
29
+ Given an updated file at "source/images/table.jpg"
30
+ Given a successfully built app at "basic-app" with flags "--verbose"
31
+ Then the file "build/images/table.jpg" should have been updated
@@ -0,0 +1,10 @@
1
+ Feature: Optimization
2
+ Scenario: Basic optimization
3
+ Given a fixture app "basic-app"
4
+ Then the following files should exist:
5
+ | source/images/table.jpg |
6
+ Then the file "source/images/table.jpg" should be 225252 bytes
7
+ Given a successfully built app at "basic-app" with flags "--verbose"
8
+ Then the following files should exist:
9
+ | build/images/table.jpg |
10
+ Then the file "build/images/table.jpg" should be less than 225252 bytes
@@ -0,0 +1,14 @@
1
+ Feature: Permissions
2
+ Scenario: Preserving permissions
3
+ Given a fixture app "basic-app"
4
+ Then the following files should exist:
5
+ | source/images/table.jpg |
6
+ | source/images/oh_my_glob.gif |
7
+ Then the mode of filesystem object "source/images/table.jpg" should match "0644"
8
+ Then the mode of filesystem object "source/images/oh_my_glob.gif" should match "0644"
9
+ Given a successfully built app at "basic-app" with flags "--verbose"
10
+ Then the following files should exist:
11
+ | build/images/table.jpg |
12
+ | build/images/oh_my_glob.gif |
13
+ Then the mode of filesystem object "build/images/table.jpg" should match "0644"
14
+ Then the mode of filesystem object "build/images/oh_my_glob.gif" should match "0644"
@@ -0,0 +1,7 @@
1
+ ENV['TEST'] = 'true'
2
+ ENV['AUTOLOAD_SPROCKETS'] = 'false'
3
+
4
+ PROJECT_ROOT_PATH = File.dirname(File.dirname(File.dirname(__FILE__)))
5
+ require 'middleman-core'
6
+ require 'middleman-core/step_definitions'
7
+ require 'middleman-imageoptim'
@@ -0,0 +1,39 @@
1
+ Then(/^the file "(.*?)" should be (\d+) bytes$/) do |img, size|
2
+ expect(File.size(File.join(current_dir, img))).to eql(size.to_i)
3
+ end
4
+
5
+ Then(/^the file "(.*?)" should be less than (\d+) bytes$/) do |img, size|
6
+ expect(File.size(File.join(current_dir, img))).to be < size.to_i
7
+ end
8
+
9
+ Then(/^the manifest should have the right timestamp for "(.*?)"$/) do |file|
10
+ manifest = YAML.load(File.read(manifest_path))
11
+ file_stamp = File.mtime(File.join(current_dir, file))
12
+ expect(manifest[file]).to eql(file_stamp)
13
+ end
14
+
15
+ Given(/^a primed manifest for "(.*?)"$/) do |file|
16
+ manifest = { file: File.mtime(File.join(current_dir, file)) }
17
+ File.open(path, 'w') do |manifest_file|
18
+ manifest_file.write(YAML.dump(manifest))
19
+ end
20
+ end
21
+
22
+ Given(/^some time has passed$/) do
23
+ # this needs to be > 1 to get out of the single second resolution of a
24
+ # file timestamp
25
+ sleep(1.5)
26
+ end
27
+
28
+ Given(/^an updated file at "(.*?)"$/) do |file|
29
+ FileUtils.touch(File.join(current_dir, file))
30
+ end
31
+
32
+ Then(/^the file "([^\"]*)" should have been updated$/) do |file|
33
+ target = File.join(current_dir, file)
34
+ expect(File.mtime(target)).not_to eql(@modification_times[target])
35
+ end
36
+
37
+ def manifest_path
38
+ File.join(current_dir, 'build', 'imageoptim.manifest.yml')
39
+ end
@@ -0,0 +1,3 @@
1
+ activate :imageoptim do |options|
2
+ options.manifest = false
3
+ end
@@ -0,0 +1 @@
1
+ activate :imageoptim
@@ -1,15 +1,19 @@
1
- require "middleman-core"
2
- require "middleman-imageoptim/optimizer"
3
- require "middleman-imageoptim/options"
1
+ require 'middleman-core'
2
+ require 'middleman-imageoptim/optimizer'
3
+ require 'middleman-imageoptim/options'
4
+ require 'middleman-imageoptim/resource_list'
5
+ require 'middleman-imageoptim/utils'
6
+ require 'middleman-imageoptim/manifest'
7
+ require 'middleman-imageoptim/manifest_resource'
4
8
 
5
9
  ::Middleman::Extensions.register(:imageoptim) do
6
- require "middleman-imageoptim/extension"
7
- ::Middleman::Imageoptim
10
+ require 'middleman-imageoptim/extension'
11
+ ::Middleman::Imageoptim::Extension
8
12
  end
9
13
 
10
14
  ::Middleman::Extensions.register(:image_optim) do
11
- warn ":image_optim is deprecated. Please use `:imageoptim` instead."
15
+ warn ':image_optim is deprecated. Please use `:imageoptim` instead.'
12
16
 
13
- require "middleman-imageoptim/extension"
14
- ::Middleman::Imageoptim
17
+ require 'middleman-imageoptim/extension'
18
+ ::Middleman::Imageoptim::Extension
15
19
  end
@@ -1,24 +1,25 @@
1
- require "middleman-core"
1
+ require 'middleman-core'
2
2
 
3
3
  module Middleman
4
-
5
4
  # Middleman extension entry point
6
5
  module Imageoptim
7
- class << self
8
- def registered(app, options_hash = {}, &block)
9
- options = Middleman::Imageoptim::Options.new(options_hash)
10
- yield options.user_options if block_given?
11
-
12
- app.after_configuration do
6
+ class Extension < Middleman::Extension
7
+ def after_build(builder)
8
+ Middleman::Imageoptim::Optimizer.optimize!(app, builder, options)
9
+ end
13
10
 
14
- app.after_build do |builder|
15
- Middleman::Imageoptim::Optimizer.new(app, builder, options).optimize!
16
- end
11
+ def manipulate_resource_list(resources)
12
+ return resources unless options.manifest
13
+ Middleman::Imageoptim::ResourceList.manipulate(app, resources, options)
14
+ end
17
15
 
18
- end
16
+ private
19
17
 
18
+ def setup_options(options_hash = {}, &_block)
19
+ @options = Middleman::Imageoptim::Options.new(options_hash)
20
+ yield @options if block_given?
21
+ @options.freeze
20
22
  end
21
- alias :included :registered
22
23
  end
23
24
  end
24
25
  end
@@ -0,0 +1,52 @@
1
+ module Middleman
2
+ module Imageoptim
3
+ class Manifest
4
+ MANIFEST_FILENAME = 'imageoptim.manifest.yml'
5
+
6
+ attr_reader :app
7
+
8
+ def initialize(app)
9
+ @app = app
10
+ end
11
+
12
+ def path
13
+ File.join(app.build_dir, MANIFEST_FILENAME)
14
+ end
15
+
16
+ def build_and_write(new_resources)
17
+ write(dump(build(new_resources)))
18
+ end
19
+
20
+ def resource(key)
21
+ resources[key.to_s]
22
+ end
23
+
24
+ private
25
+
26
+ def resources
27
+ @resources ||= load(path)
28
+ end
29
+
30
+ def dump(source)
31
+ YAML.dump(source)
32
+ end
33
+
34
+ def load(path)
35
+ YAML.load(File.read(path))
36
+ end
37
+
38
+ def build(resources)
39
+ resources.inject({}) do |new_manifest, resource|
40
+ new_manifest[resource.to_s] = File.mtime(resource)
41
+ new_manifest
42
+ end
43
+ end
44
+
45
+ def write(manifest)
46
+ File.open(path, 'w') do |manifest_file|
47
+ manifest_file.write(manifest)
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end