middleman-imageoptim 0.1.4 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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