image_optim 0.26.2 → 0.27.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (75) hide show
  1. checksums.yaml +4 -4
  2. data/.appveyor.yml +9 -2
  3. data/.rubocop.yml +38 -10
  4. data/.travis.yml +19 -15
  5. data/CHANGELOG.markdown +21 -0
  6. data/Gemfile +3 -1
  7. data/LICENSE.txt +1 -1
  8. data/README.markdown +9 -3
  9. data/Vagrantfile +2 -0
  10. data/bin/image_optim +1 -0
  11. data/image_optim.gemspec +5 -7
  12. data/lib/image_optim.rb +5 -0
  13. data/lib/image_optim/bin_resolver.rb +5 -0
  14. data/lib/image_optim/bin_resolver/bin.rb +45 -19
  15. data/lib/image_optim/bin_resolver/comparable_condition.rb +3 -0
  16. data/lib/image_optim/bin_resolver/error.rb +2 -0
  17. data/lib/image_optim/bin_resolver/simple_version.rb +2 -0
  18. data/lib/image_optim/cache.rb +3 -0
  19. data/lib/image_optim/cache_path.rb +21 -2
  20. data/lib/image_optim/cmd.rb +2 -0
  21. data/lib/image_optim/config.rb +7 -1
  22. data/lib/image_optim/configuration_error.rb +2 -0
  23. data/lib/image_optim/handler.rb +4 -0
  24. data/lib/image_optim/hash_helpers.rb +2 -0
  25. data/lib/image_optim/image_meta.rb +2 -0
  26. data/lib/image_optim/non_negative_integer_range.rb +2 -0
  27. data/lib/image_optim/optimized_path.rb +3 -1
  28. data/lib/image_optim/option_definition.rb +2 -0
  29. data/lib/image_optim/option_helpers.rb +2 -0
  30. data/lib/image_optim/path.rb +30 -5
  31. data/lib/image_optim/runner.rb +3 -0
  32. data/lib/image_optim/runner/glob_helpers.rb +3 -1
  33. data/lib/image_optim/runner/option_parser.rb +4 -2
  34. data/lib/image_optim/space.rb +3 -1
  35. data/lib/image_optim/true_false_nil.rb +2 -0
  36. data/lib/image_optim/worker.rb +5 -0
  37. data/lib/image_optim/worker/advpng.rb +2 -0
  38. data/lib/image_optim/worker/class_methods.rb +5 -0
  39. data/lib/image_optim/worker/gifsicle.rb +2 -0
  40. data/lib/image_optim/worker/jhead.rb +4 -1
  41. data/lib/image_optim/worker/jpegoptim.rb +2 -0
  42. data/lib/image_optim/worker/jpegrecompress.rb +2 -0
  43. data/lib/image_optim/worker/jpegtran.rb +2 -0
  44. data/lib/image_optim/worker/optipng.rb +4 -2
  45. data/lib/image_optim/worker/pngcrush.rb +4 -2
  46. data/lib/image_optim/worker/pngout.rb +3 -0
  47. data/lib/image_optim/worker/pngquant.rb +2 -0
  48. data/lib/image_optim/worker/svgo.rb +2 -0
  49. data/script/update_worker_options_in_readme +3 -2
  50. data/script/worker_analysis +13 -3
  51. data/spec/image_optim/bin_resolver/comparable_condition_spec.rb +2 -0
  52. data/spec/image_optim/bin_resolver/simple_version_spec.rb +2 -0
  53. data/spec/image_optim/bin_resolver_spec.rb +4 -2
  54. data/spec/image_optim/cache_path_spec.rb +71 -26
  55. data/spec/image_optim/cache_spec.rb +4 -0
  56. data/spec/image_optim/cmd_spec.rb +2 -0
  57. data/spec/image_optim/config_spec.rb +2 -0
  58. data/spec/image_optim/handler_spec.rb +2 -0
  59. data/spec/image_optim/hash_helpers_spec.rb +2 -0
  60. data/spec/image_optim/image_meta_spec.rb +2 -0
  61. data/spec/image_optim/optimized_path_spec.rb +2 -0
  62. data/spec/image_optim/option_definition_spec.rb +2 -0
  63. data/spec/image_optim/option_helpers_spec.rb +2 -0
  64. data/spec/image_optim/path_spec.rb +65 -24
  65. data/spec/image_optim/runner/glob_helpers_spec.rb +2 -0
  66. data/spec/image_optim/runner/option_parser_spec.rb +2 -0
  67. data/spec/image_optim/space_spec.rb +13 -11
  68. data/spec/image_optim/worker/optipng_spec.rb +2 -0
  69. data/spec/image_optim/worker/pngquant_spec.rb +2 -0
  70. data/spec/image_optim/worker_spec.rb +2 -0
  71. data/spec/image_optim_spec.rb +7 -4
  72. data/spec/images/invisiblepixels/generate +1 -0
  73. data/spec/images/quant/generate +3 -2
  74. data/spec/spec_helper.rb +3 -0
  75. metadata +18 -13
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 07b7d1d96cc0bc6f16e0a2b6a512c4ad06015eea55359dcc9c32c2b19714c786
4
- data.tar.gz: be1136efd362c8f13f8a286728fc3c49f62af439cdea90d60c68e4093c1be72a
3
+ metadata.gz: b8d7c83b1d36f1cb0c41866cf421a8477632c43137749f2011b2520854de859d
4
+ data.tar.gz: 3030f2377d510cc964025e3497dfb2bc860bd560fa88e33acc97e3caaa56614c
5
5
  SHA512:
6
- metadata.gz: 82ac7498fa95948f7e6a6380695be2da56436245d4fd595d704b4a8e78d59bb4c483690e8a8ac992ea5bf34fc0f37180ea1e103d76c8ac523975bd8a7690b1e5
7
- data.tar.gz: cb3d17d491ec5accbf9d94caac4725b849e5e42f212b464b1a08b1f0545f0844193154c8c2c141377193a5234e45b70a207fb4a642f2625e0668e08e8821f046
6
+ metadata.gz: 3df3a7cd3606e03dc16fd7aed023e40f61e5c4b688707a39240cc67b5432b9705fbb2c33df9ec8a1da96e4408d7a5270b6a181415647e53c686565f45b5c2bd4
7
+ data.tar.gz: b19684e4d13d29e6ac52e3ba5cddb38a6716f9acfae9946962ab45582a38e49c6c42018387d66e75a5f52d7153e12cf4a9e9dc10388f6d36bd4834d5a5e78ee0
@@ -3,6 +3,7 @@ install:
3
3
  - mkdir tmp\bin || exit 0
4
4
  - set PATH=C:\Ruby25-x64\bin;%cd%\tmp\bin;%PATH%
5
5
  - ruby --version
6
+ - gem --version
6
7
  - bundle package --all
7
8
 
8
9
  - ps: git --work-tree=tmp\bin checkout origin/windows-binaries -- '*.exe'
@@ -26,10 +27,16 @@ test_script:
26
27
  - ps: |
27
28
  $path = $env:Path
28
29
  $rubypaths = ls -Path C:\Ruby*\bin
29
- foreach ($rubypath in $rubypaths[-2, -1]) {
30
- echo "################################################################################"
30
+ foreach ($rubypath in $rubypaths) {
31
31
  $env:Path = "$rubypath;" + $path
32
+ ruby -e "abort unless RUBY_VERSION > '2.3'"
33
+ if ($LASTEXITCODE -gt 0) {
34
+ continue
35
+ }
36
+
37
+ echo "################################ $rubypath ################################"
32
38
  ruby --version
39
+ gem --version
33
40
  bundle package --all
34
41
  bundle install --local -j4
35
42
  bundle exec rspec
@@ -2,6 +2,7 @@ AllCops:
2
2
  Exclude:
3
3
  - '*.gemspec'
4
4
  - 'vendor/**/*'
5
+ NewCops: enable
5
6
 
6
7
  Bundler/OrderedGems:
7
8
  Enabled: false
@@ -9,6 +10,9 @@ Bundler/OrderedGems:
9
10
  Layout/AccessModifierIndentation:
10
11
  EnforcedStyle: outdent
11
12
 
13
+ Layout/AssignmentIndentation:
14
+ Enabled: false
15
+
12
16
  Layout/CaseIndentation:
13
17
  EnforcedStyle: end
14
18
 
@@ -18,16 +22,19 @@ Layout/DotPosition:
18
22
  Layout/EndAlignment:
19
23
  EnforcedStyleAlignWith: variable
20
24
 
21
- Layout/IndentArray:
25
+ Layout/FirstArrayElementIndentation:
22
26
  EnforcedStyle: consistent
23
27
 
24
- Layout/IndentAssignment:
28
+ Layout/FirstHashElementIndentation:
29
+ EnforcedStyle: consistent
30
+
31
+ Layout/HeredocIndentation:
25
32
  Enabled: false
26
33
 
27
- Layout/IndentHash:
28
- EnforcedStyle: consistent
34
+ Layout/LineLength:
35
+ Max: 120
29
36
 
30
- Layout/IndentHeredoc:
37
+ Layout/RescueEnsureAlignment:
31
38
  Enabled: false
32
39
 
33
40
  Layout/SpaceBeforeBlockBraces:
@@ -44,14 +51,14 @@ Lint/AmbiguousBlockAssociation:
44
51
  Lint/NestedPercentLiteral:
45
52
  Enabled: false
46
53
 
47
- Lint/UnneededRequireStatement:
54
+ Lint/RedundantRequireStatement:
48
55
  Enabled: false
49
56
 
50
- Lint/UnneededSplatExpansion:
57
+ Lint/RedundantSplatExpansion:
51
58
  Enabled: false
52
59
 
53
60
  Metrics/AbcSize:
54
- Max: 30
61
+ Max: 33
55
62
 
56
63
  Metrics/BlockLength:
57
64
  Exclude:
@@ -63,18 +70,21 @@ Metrics/ClassLength:
63
70
  Max: 150
64
71
 
65
72
  Metrics/CyclomaticComplexity:
66
- Max: 10
73
+ Max: 11
67
74
 
68
75
  Metrics/MethodLength:
69
76
  Max: 25
70
77
 
71
78
  Metrics/PerceivedComplexity:
72
- Max: 8
79
+ Max: 10
73
80
 
74
81
  Security/MarshalLoad:
75
82
  Exclude:
76
83
  - 'script/worker_analysis'
77
84
 
85
+ Style/AccessorGrouping:
86
+ Enabled: false
87
+
78
88
  Style/Alias:
79
89
  EnforcedStyle: prefer_alias_method
80
90
 
@@ -93,18 +103,36 @@ Style/ExpandPathArguments:
93
103
  Style/FormatStringToken:
94
104
  Enabled: false
95
105
 
106
+ Style/HashEachMethods:
107
+ Enabled: true
108
+
96
109
  Style/HashSyntax:
97
110
  EnforcedStyle: hash_rockets
98
111
 
112
+ Style/HashTransformKeys:
113
+ Enabled: false
114
+
115
+ Style/HashTransformValues:
116
+ Enabled: false
117
+
99
118
  Style/IfUnlessModifier:
100
119
  Enabled: false
101
120
 
121
+ Style/NumericPredicate:
122
+ EnforcedStyle: comparison
123
+
124
+ Style/OptionalBooleanParameter:
125
+ Enabled: false
126
+
102
127
  Style/ParallelAssignment:
103
128
  Enabled: false
104
129
 
105
130
  Style/RescueStandardError:
106
131
  EnforcedStyle: implicit
107
132
 
133
+ Style/SafeNavigation:
134
+ Enabled: false
135
+
108
136
  Style/Semicolon:
109
137
  AllowAsExpressionSeparator: true
110
138
 
@@ -1,4 +1,5 @@
1
1
  sudo: false
2
+ dist: trusty
2
3
  language: ruby
3
4
  cache:
4
5
  bundler: true
@@ -6,37 +7,40 @@ cache:
6
7
  - $(npm root)
7
8
  - ~/bin
8
9
  rvm:
9
- - '1.8.7-p371'
10
+ - '1.8.7-p374'
10
11
  - '1.9.3-p551'
11
12
  - '2.0.0-p648'
12
13
  - '2.1.10'
13
14
  - '2.2.10'
14
- - '2.3.7'
15
- - '2.4.4'
16
- - '2.5.1'
17
- - 'jruby-9.0.5.0'
18
- - 'jruby-9.1.9.0'
15
+ - '2.3.8'
16
+ - '2.4.10'
17
+ - '2.5.8'
18
+ - '2.6.6'
19
+ - '2.7.1'
20
+ - 'jruby-9.2.11.1'
19
21
  script:
20
22
  - bundle exec image_optim --info
21
23
  - bundle exec rspec
22
24
  before_install:
23
- - gem update --system
24
- - gem install bundler
25
+ - 'echo "gem: --no-ri --no-rdoc --no-document" > ~/.gemrc'
26
+ - gem install rubygems-update || gem install rubygems-update --version '< 3'
27
+ - update_rubygems
28
+ - gem install bundler || gem install bundler --version '< 2'
25
29
  - nvm install stable
26
30
  - mkdir -p ~/bin
27
31
  - command -v svgo || npm install -g svgo
28
- - command -v pngout || curl -L "http://static.jonof.id.au/dl/kenutils/pngout-20150319-linux.tar.gz" | tar -xz -C ~/bin --strip-components 2 --wildcards '*/x86_64/pngout'
32
+ - command -v pngout || curl -L "https://www.jonof.id.au/files/kenutils/pngout-20200115-linux.tar.gz" | tar -xz -C ~/bin --strip-components 2 --wildcards '*/amd64/pngout'
29
33
  matrix:
30
34
  include:
31
- - env: CODECLIMATE=✓
32
- rvm: '2.4.4'
35
+ - env: CODECLIMATE=1
36
+ rvm: '2.4.10'
33
37
  after_success: bundle exec codeclimate-test-reporter
34
- - env: RUBOCOP=✓
35
- rvm: '2.4.4'
38
+ - env: RUBOCOP=1
39
+ rvm: '2.4.10'
36
40
  script: bundle exec rubocop
37
41
  before_install: gem update --system && gem install bundler
38
- - env: CHECK_RUBIES=✓
39
- rvm: '2.4.4'
42
+ - env: CHECK_RUBIES=1
43
+ rvm: '2.4.10'
40
44
  script: bundle exec travis_check_rubies
41
45
  before_install: gem update --system && gem install bundler
42
46
  addons:
@@ -2,6 +2,27 @@
2
2
 
3
3
  ## unreleased
4
4
 
5
+ ## v0.27.1 (2020-09-30)
6
+
7
+ * Fixed atomic replacement for case when equal `File::Stat#dev` doesn't mean that file can be linked [#180](https://github.com/toy/image_optim/issues/180) [@toy](https://github.com/toy)
8
+
9
+ ## v0.27.0 (2020-08-27)
10
+
11
+ * Use `.tmp` as the extension for temporary file if it needs to be created for atomic replacement [#178](https://github.com/toy/image_optim/issues/178) [@toy](https://github.com/toy)
12
+ * Don't create a temporary file in destination directory for atomic replacement if temporary directory is on same device as destination [#178](https://github.com/toy/image_optim/issues/178) [@toy](https://github.com/toy)
13
+
14
+ ## v0.26.5 (2019-07-14)
15
+
16
+ * Remove deprecated `rubyforge_project` attribute from gemspec [rubygems/rubygems#2436](https://github.com/rubygems/rubygems/pull/2436) [@toy](https://github.com/toy)
17
+
18
+ ## v0.26.4 (2019-05-23)
19
+
20
+ * Enable frozen string literals [@toy](https://github.com/toy)
21
+
22
+ ## v0.26.3 (2018-10-13)
23
+
24
+ * Handle `vnone` version of `advpng` that was erroneously produced for `ubuntu` and `homebrew` [#165](https://github.com/toy/image_optim/issues/165) [@toy](https://github.com/toy)
25
+
5
26
  ## v0.26.2 (2018-08-15)
6
27
 
7
28
  * Ignore segmentation fault for `pngout` <= `20150920` [#158](https://github.com/toy/image_optim/issues/158) [@toy](https://github.com/toy)
data/Gemfile CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  source 'https://rubygems.org'
2
4
 
3
5
  gemspec
@@ -10,6 +12,6 @@ if ENV['CODECLIMATE']
10
12
  end
11
13
  end
12
14
 
13
- if RUBY_VERSION >= '2.0'
15
+ if ENV['CHECK_RUBIES']
14
16
  gem 'travis_check_rubies', '~> 0.2'
15
17
  end
@@ -1,4 +1,4 @@
1
- Copyright (c) 2012-2018 Ivan Kuchin
1
+ Copyright (c) 2012-2020 Ivan Kuchin
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
@@ -3,7 +3,7 @@
3
3
  [![AppVeyor Status](https://img.shields.io/appveyor/ci/toy/image-optim/master.svg?style=flat&label=windows)](https://ci.appveyor.com/project/toy/image-optim)
4
4
  [![Code Climate](https://img.shields.io/codeclimate/maintainability/toy/image_optim.svg?style=flat)](https://codeclimate.com/github/toy/image_optim)
5
5
  [![Code Climate Coverage](https://img.shields.io/codeclimate/c/toy/image_optim.svg?style=flat)](https://codeclimate.com/github/toy/image_optim)
6
- [![Dependency Status](https://img.shields.io/gemnasium/toy/image_optim.svg?style=flat)](https://gemnasium.com/toy/image_optim)
6
+ [![Depfu](https://badges.depfu.com/badges/221b4832fa96f613aa5401f7cb4030ac/overview.svg)](https://depfu.com/github/toy/image_optim)
7
7
  [![Inch CI](https://inch-ci.org/github/toy/image_optim.svg?branch=master&style=flat)](https://inch-ci.org/github/toy/image_optim)
8
8
 
9
9
  # image_optim
@@ -27,6 +27,8 @@ Based on [ImageOptim.app](http://imageoptim.com/).
27
27
 
28
28
  Documentation for [latest gem version](http://rubydoc.info/gems/image_optim/frames) and [master branch](http://rubydoc.info/github/toy/image_optim/master/frames).
29
29
 
30
+ A test application with latest `image_optim` and `image_optim_pack` is available on heroku: https://iopack.herokuapp.com/.
31
+
30
32
  ## Gem installation
31
33
 
32
34
  ```sh
@@ -58,7 +60,7 @@ With version:
58
60
 
59
61
  <!---<update-version>-->
60
62
  ```ruby
61
- gem 'image_optim', '~> 0.26'
63
+ gem 'image_optim', '~> 0.27'
62
64
  ```
63
65
  <!---</update-version>-->
64
66
 
@@ -275,6 +277,10 @@ optipng:
275
277
  level: 5
276
278
  ```
277
279
 
280
+ ### Temporary directory
281
+
282
+ `image_optim` uses standard ruby library for creating temporary files. Temporary directory can be changed using one of `TMPDIR`, `TMP` or `TEMP` environment variables.
283
+
278
284
  ## Options
279
285
 
280
286
  * `: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`)*
@@ -355,4 +361,4 @@ In separate file [CHANGELOG.markdown](CHANGELOG.markdown).
355
361
 
356
362
  ## Copyright
357
363
 
358
- Copyright (c) 2012-2018 Ivan Kuchin. See [LICENSE.txt](LICENSE.txt) for details.
364
+ Copyright (c) 2012-2020 Ivan Kuchin. See [LICENSE.txt](LICENSE.txt) for details.
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  Vagrant.configure('2') do |config|
2
4
  config.vm.box = 'ubuntu/precise64'
3
5
 
@@ -1,5 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
  # encoding: UTF-8
3
+ # frozen_string_literal: true
3
4
 
4
5
  require 'image_optim/runner'
5
6
  require 'image_optim/runner/option_parser'
@@ -2,17 +2,15 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = 'image_optim'
5
- s.version = '0.26.2'
5
+ s.version = '0.27.1'
6
6
  s.summary = %q{Command line tool and ruby interface to optimize (lossless compress, optionally lossy) jpeg, png, gif and svg images using external utilities (advpng, gifsicle, jhead, jpeg-recompress, jpegoptim, jpegrescan, jpegtran, optipng, pngcrush, pngout, pngquant, svgo)}
7
- s.homepage = "http://github.com/toy/#{s.name}"
7
+ s.homepage = "https://github.com/toy/#{s.name}"
8
8
  s.authors = ['Ivan Kuchin']
9
9
  s.license = 'MIT'
10
10
 
11
- s.rubyforge_project = s.name
12
-
13
11
  s.metadata = {
14
12
  'bug_tracker_uri' => "https://github.com/toy/#{s.name}/issues",
15
- 'changelog_uri' => "https://github.com/toy/#{s.name}/CHANGELOG.markdown",
13
+ 'changelog_uri' => "https://github.com/toy/#{s.name}/blob/master/CHANGELOG.markdown",
16
14
  'documentation_uri' => "https://www.rubydoc.info/gems/#{s.name}/#{s.version}",
17
15
  'source_code_uri' => "https://github.com/toy/#{s.name}",
18
16
  }
@@ -35,7 +33,7 @@ EOF
35
33
 
36
34
  s.add_development_dependency 'image_optim_pack', '~> 0.2', '>= 0.2.2'
37
35
  s.add_development_dependency 'rspec', '~> 3.0'
38
- if RUBY_VERSION >= '2.2'
39
- s.add_development_dependency 'rubocop', '~> 0.58'
36
+ if RUBY_VERSION >= '2.2' && !Gem.win_platform? && !defined?(JRUBY_VERSION)
37
+ s.add_development_dependency 'rubocop', '~> 0.59', '!= 0.78.0'
40
38
  end
41
39
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'image_optim/bin_resolver'
2
4
  require 'image_optim/cache'
3
5
  require 'image_optim/config'
@@ -118,6 +120,7 @@ class ImageOptim
118
120
  end
119
121
 
120
122
  return unless optimized
123
+
121
124
  OptimizedPath.new(optimized, original)
122
125
  end
123
126
 
@@ -126,6 +129,7 @@ class ImageOptim
126
129
  def optimize_image!(original)
127
130
  original = Path.convert(original)
128
131
  return unless (result = optimize_image(original))
132
+
129
133
  result.replace(original)
130
134
  OptimizedPath.new(original, result.original_size)
131
135
  end
@@ -134,6 +138,7 @@ class ImageOptim
134
138
  def optimize_image_data(original_data)
135
139
  format = ImageMeta.format_for_data(original_data)
136
140
  return unless format
141
+
137
142
  Path.temp_file %W[image_optim .#{format}] do |temp|
138
143
  temp.binmode
139
144
  temp.write(original_data)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'thread'
2
4
  require 'fspath'
3
5
  require 'image_optim/bin_resolver/error'
@@ -97,6 +99,7 @@ class ImageOptim
97
99
  # Double-checked locking
98
100
  def resolving(name)
99
101
  return if @bins.include?(name)
102
+
100
103
  @lock.synchronize do
101
104
  yield unless @bins.include?(name)
102
105
  end
@@ -108,11 +111,13 @@ class ImageOptim
108
111
  env_name = "#{name}_bin".upcase
109
112
  path = ENV[env_name]
110
113
  return unless path
114
+
111
115
  path = File.expand_path(path)
112
116
  desc = "`#{path}` specified in #{env_name}"
113
117
  fail "#{desc} doesn\'t exist" unless File.exist?(path)
114
118
  fail "#{desc} is not a file" unless File.file?(path)
115
119
  fail "#{desc} is not executable" unless File.executable?(path)
120
+
116
121
  if @image_optim.verbose
117
122
  $stderr << "Custom path for #{name} specified in #{env_name}: #{path}\n"
118
123
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'image_optim/bin_resolver/error'
2
4
  require 'image_optim/bin_resolver/simple_version'
3
5
  require 'image_optim/bin_resolver/comparable_condition'
@@ -15,6 +17,7 @@ class ImageOptim
15
17
  class BadVersion < Error; end
16
18
 
17
19
  attr_reader :name, :path, :version
20
+
18
21
  def initialize(name, path)
19
22
  @name = name.to_sym
20
23
  @path = path.to_s
@@ -23,6 +26,7 @@ class ImageOptim
23
26
 
24
27
  def digest
25
28
  return @digest if defined?(@digest)
29
+
26
30
  @digest = File.exist?(@path) && Digest::SHA1.file(@path).hexdigest
27
31
  end
28
32
 
@@ -32,20 +36,34 @@ class ImageOptim
32
36
 
33
37
  is = ComparableCondition.is
34
38
 
35
- FAIL_CHECKS = [
36
- [:pngcrush, is.between?('1.7.60', '1.7.65'), 'is known to produce '\
37
- 'broken pngs'],
38
- [:pngcrush, is == '1.7.80', 'loses one color in indexed images'],
39
- [:pngquant, is < '2.0', 'is not supported'],
40
- ].freeze
41
-
42
- WARN_CHECKS = [
43
- [:advpng, is < '1.17', 'does not use zopfli'],
44
- [:gifsicle, is < '1.85', 'does not support removing extension blocks'],
45
- [:pngcrush, is < '1.7.38', 'does not have blacken flag'],
46
- [:pngquant, is < '2.1', 'may be lossy even with quality `100-`'],
47
- [:optipng, is < '0.7', 'does not support -strip option'],
48
- ].freeze
39
+ FAIL_CHECKS = {
40
+ :pngcrush => [
41
+ [is.between?('1.7.60', '1.7.65'), 'is known to produce broken pngs'],
42
+ [is == '1.7.80', 'loses one color in indexed images'],
43
+ ],
44
+ :pngquant => [
45
+ [is < '2.0', 'is not supported'],
46
+ ],
47
+ }.freeze
48
+
49
+ WARN_CHECKS = {
50
+ :advpng => [
51
+ [is == 'none', 'is of unknown version'],
52
+ [is < '1.17', 'does not use zopfli'],
53
+ ],
54
+ :gifsicle => [
55
+ [is < '1.85', 'does not support removing extension blocks'],
56
+ ],
57
+ :pngcrush => [
58
+ [is < '1.7.38', 'does not have blacken flag'],
59
+ ],
60
+ :pngquant => [
61
+ [is < '2.1', 'may be lossy even with quality `100-`'],
62
+ ],
63
+ :optipng => [
64
+ [is < '0.7', 'does not support -strip option'],
65
+ ],
66
+ }.freeze
49
67
 
50
68
  # Fail if version will not work properly
51
69
  def check_fail!
@@ -53,9 +71,11 @@ class ImageOptim
53
71
  fail UnknownVersion, "could not get version of #{name} at #{path}"
54
72
  end
55
73
 
56
- FAIL_CHECKS.each do |bin_name, matcher, message|
57
- next unless bin_name == name
74
+ return unless FAIL_CHECKS[name]
75
+
76
+ FAIL_CHECKS[name].each do |matcher, message|
58
77
  next unless matcher.match(version)
78
+
59
79
  fail BadVersion, "#{self} (#{matcher}) #{message}"
60
80
  end
61
81
  end
@@ -64,10 +84,14 @@ class ImageOptim
64
84
  def check!
65
85
  check_fail!
66
86
 
67
- WARN_CHECKS.each do |bin_name, matcher, message|
68
- next unless bin_name == name
87
+ return unless WARN_CHECKS[name]
88
+
89
+ WARN_CHECKS[name].each do |matcher, message|
69
90
  next unless matcher.match(version)
91
+
70
92
  warn "WARN: #{self} (#{matcher}) #{message}"
93
+
94
+ break
71
95
  end
72
96
  end
73
97
 
@@ -82,7 +106,9 @@ class ImageOptim
82
106
  # Getting version of bin, will fail for an unknown name
83
107
  def version_string
84
108
  case name
85
- when :advpng, :gifsicle, :jpegoptim, :optipng
109
+ when :advpng
110
+ capture("#{escaped_path} --version 2> #{Path::NULL}")[/\bv(\d+(\.\d+)+|none)/, 1]
111
+ when :gifsicle, :jpegoptim, :optipng
86
112
  capture("#{escaped_path} --version 2> #{Path::NULL}")[/\d+(\.\d+)+/]
87
113
  when :svgo, :pngquant
88
114
  capture("#{escaped_path} --version 2>&1")[/\d+(\.\d+)+/]