image_optim 0.27.1 → 0.31.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 +4 -4
- data/.appveyor.yml +2 -0
- data/.github/workflows/check.yml +59 -0
- data/.pre-commit-hooks.yaml +9 -0
- data/.rubocop.yml +6 -3
- data/CHANGELOG.markdown +22 -0
- data/CONTRIBUTING.markdown +5 -2
- data/Gemfile +1 -7
- data/LICENSE.txt +1 -1
- data/README.markdown +21 -10
- data/Vagrantfile +1 -1
- data/image_optim.gemspec +7 -4
- data/lib/image_optim/bin_resolver/bin.rb +10 -9
- data/lib/image_optim/cache.rb +6 -0
- data/lib/image_optim/cmd.rb +45 -6
- data/lib/image_optim/config.rb +14 -8
- data/lib/image_optim/elapsed_time.rb +26 -0
- data/lib/image_optim/errors.rb +9 -0
- data/lib/image_optim/path.rb +1 -1
- data/lib/image_optim/runner/option_parser.rb +24 -18
- data/lib/image_optim/runner.rb +1 -1
- data/lib/image_optim/timer.rb +25 -0
- data/lib/image_optim/worker/advpng.rb +7 -7
- data/lib/image_optim/worker/gifsicle.rb +11 -11
- data/lib/image_optim/worker/jhead.rb +2 -2
- data/lib/image_optim/worker/jpegoptim.rb +13 -11
- data/lib/image_optim/worker/jpegrecompress.rb +17 -2
- data/lib/image_optim/worker/jpegtran.rb +4 -4
- data/lib/image_optim/worker/optipng.rb +7 -7
- data/lib/image_optim/worker/oxipng.rb +53 -0
- data/lib/image_optim/worker/pngcrush.rb +6 -6
- data/lib/image_optim/worker/pngout.rb +7 -7
- data/lib/image_optim/worker/pngquant.rb +10 -9
- data/lib/image_optim/worker/svgo.rb +2 -2
- data/lib/image_optim/worker.rb +32 -29
- data/lib/image_optim.rb +16 -10
- data/script/update_worker_options_in_readme +2 -2
- data/script/worker_analysis +16 -18
- data/spec/image_optim/bin_resolver_spec.rb +5 -5
- data/spec/image_optim/cache_path_spec.rb +7 -10
- data/spec/image_optim/cache_spec.rb +8 -8
- data/spec/image_optim/cmd_spec.rb +64 -6
- data/spec/image_optim/config_spec.rb +36 -20
- data/spec/image_optim/elapsed_time_spec.rb +14 -0
- data/spec/image_optim/handler_spec.rb +1 -1
- data/spec/image_optim/hash_helpers_spec.rb +18 -18
- data/spec/image_optim/option_definition_spec.rb +6 -6
- data/spec/image_optim/path_spec.rb +8 -11
- data/spec/image_optim/runner/option_parser_spec.rb +4 -4
- data/spec/image_optim/timer_spec.rb +32 -0
- data/spec/image_optim/worker/jpegrecompress_spec.rb +32 -0
- data/spec/image_optim/worker/optipng_spec.rb +11 -11
- data/spec/image_optim/worker/oxipng_spec.rb +89 -0
- data/spec/image_optim/worker/pngquant_spec.rb +5 -5
- data/spec/image_optim/worker_spec.rb +17 -17
- data/spec/image_optim_spec.rb +47 -10
- data/spec/images/invisiblepixels/generate +1 -1
- data/spec/spec_helper.rb +18 -17
- metadata +36 -15
- data/.travis.yml +0 -49
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e80e82d67e3434476f0bdf332b14b6369601010aaeef7ab7b901515d0c03565c
|
4
|
+
data.tar.gz: 16f304385c879cf1afc0073d7d037fb548d6c260f57e2b94cdcdd974f3cd4b4e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b0395980a804453e3273f779c1217d5dd5b9b7c522e74964070b43f2b3ac433f9f39d5f997a3e9c6594f22d244752910eea1697ac2e570de34e6b0641555b9e8
|
7
|
+
data.tar.gz: 9de0bebe89071d3aa7bd506b02dc684b53d998dcfccab1debad72bdc244e6fbae6eb0ac2d5871359fe2ffa5cb9e7c5ae8a7dc98829e00e8abef49c017ac3b00c
|
data/.appveyor.yml
CHANGED
@@ -0,0 +1,59 @@
|
|
1
|
+
name: check
|
2
|
+
on:
|
3
|
+
push:
|
4
|
+
pull_request:
|
5
|
+
schedule:
|
6
|
+
- cron: 45 4 * * 2
|
7
|
+
jobs:
|
8
|
+
check:
|
9
|
+
runs-on: ubuntu-latest
|
10
|
+
strategy:
|
11
|
+
matrix:
|
12
|
+
ruby:
|
13
|
+
- '2.0'
|
14
|
+
- '2.1'
|
15
|
+
- '2.2'
|
16
|
+
- '2.3'
|
17
|
+
- '2.4'
|
18
|
+
- '2.5'
|
19
|
+
- '2.6'
|
20
|
+
- '2.7'
|
21
|
+
- '3.0'
|
22
|
+
- jruby-9.2
|
23
|
+
fail-fast: false
|
24
|
+
steps:
|
25
|
+
- uses: actions/checkout@v2
|
26
|
+
- uses: ruby/setup-ruby@v1
|
27
|
+
with:
|
28
|
+
ruby-version: "${{ matrix.ruby }}"
|
29
|
+
bundler-cache: true
|
30
|
+
- run: sudo npm install -g svgo
|
31
|
+
- run: curl -L "https://www.jonof.id.au/files/kenutils/pngout-20200115-linux.tar.gz" | sudo tar -xz -C /usr/local/bin --strip-components 2 --wildcards '*/amd64/pngout'
|
32
|
+
- run: curl -L "https://github.com/shssoichiro/oxipng/releases/download/v4.0.3/oxipng-4.0.3-x86_64-unknown-linux-musl.tar.gz" | tar -xz -C /usr/local/bin --strip-components 1 --wildcards '*oxipng'
|
33
|
+
- run: bundle exec image_optim --info
|
34
|
+
- run: bundle exec rspec
|
35
|
+
coverage:
|
36
|
+
runs-on: ubuntu-latest
|
37
|
+
env:
|
38
|
+
CC_TEST_REPORTER_ID: b433c6540d220a2da0663670c9b260806bafdb3a43c6f22b2e81bfb1f87b12fe
|
39
|
+
steps:
|
40
|
+
- uses: actions/checkout@v2
|
41
|
+
- uses: ruby/setup-ruby@v1
|
42
|
+
with:
|
43
|
+
ruby-version: '3.0'
|
44
|
+
bundler-cache: true
|
45
|
+
- run: sudo npm install -g svgo
|
46
|
+
- run: curl -L "https://www.jonof.id.au/files/kenutils/pngout-20200115-linux.tar.gz" | sudo tar -xz -C /usr/local/bin --strip-components 2 --wildcards '*/amd64/pngout'
|
47
|
+
- run: curl -L "https://github.com/shssoichiro/oxipng/releases/download/v4.0.3/oxipng-4.0.3-x86_64-unknown-linux-musl.tar.gz" | tar -xz -C /usr/local/bin --strip-components 1 --wildcards '*oxipng'
|
48
|
+
- uses: paambaati/codeclimate-action@v2.7.5
|
49
|
+
with:
|
50
|
+
coverageCommand: bundle exec rspec
|
51
|
+
rubocop:
|
52
|
+
runs-on: ubuntu-latest
|
53
|
+
steps:
|
54
|
+
- uses: actions/checkout@v2
|
55
|
+
- uses: ruby/setup-ruby@v1
|
56
|
+
with:
|
57
|
+
ruby-version: '3.0'
|
58
|
+
bundler-cache: true
|
59
|
+
- run: bundle exec rubocop
|
data/.rubocop.yml
CHANGED
@@ -103,12 +103,12 @@ Style/ExpandPathArguments:
|
|
103
103
|
Style/FormatStringToken:
|
104
104
|
Enabled: false
|
105
105
|
|
106
|
+
Style/HashConversion:
|
107
|
+
Enabled: false
|
108
|
+
|
106
109
|
Style/HashEachMethods:
|
107
110
|
Enabled: true
|
108
111
|
|
109
|
-
Style/HashSyntax:
|
110
|
-
EnforcedStyle: hash_rockets
|
111
|
-
|
112
112
|
Style/HashTransformKeys:
|
113
113
|
Enabled: false
|
114
114
|
|
@@ -127,6 +127,9 @@ Style/OptionalBooleanParameter:
|
|
127
127
|
Style/ParallelAssignment:
|
128
128
|
Enabled: false
|
129
129
|
|
130
|
+
Style/RedundantBegin:
|
131
|
+
Enabled: false
|
132
|
+
|
130
133
|
Style/RescueStandardError:
|
131
134
|
EnforcedStyle: implicit
|
132
135
|
|
data/CHANGELOG.markdown
CHANGED
@@ -2,6 +2,28 @@
|
|
2
2
|
|
3
3
|
## unreleased
|
4
4
|
|
5
|
+
## v0.31.0 (2021-10-03)
|
6
|
+
|
7
|
+
* Add support for Oxipng [#167](https://github.com/toy/image_optim/issues/167) [#190](https://github.com/toy/image_optim/pull/190) [@oblakeerickson](https://github.com/oblakeerickson)
|
8
|
+
* Fix `TypeError: can't convert ImageOptim::Timer into Float` with Ruby 3 [#194](https://github.com/toy/image_optim/pull/194) [@yahonda](https://github.com/yahonda)
|
9
|
+
|
10
|
+
## v0.30.0 (2021-05-11)
|
11
|
+
|
12
|
+
* Add `timeout` option to restrict maximum time spent on every image [#21](https://github.com/toy/image_optim/issues/21) [#148](https://github.com/toy/image_optim/pull/148) [#149](https://github.com/toy/image_optim/pull/149) [#162](https://github.com/toy/image_optim/pull/162) [#184](https://github.com/toy/image_optim/pull/184) [#189](https://github.com/toy/image_optim/pull/189) [@tgxworld](https://github.com/tgxworld) [@oblakeerickson](https://github.com/oblakeerickson) [@toy](https://github.com/toy)
|
13
|
+
|
14
|
+
## v0.29.0 (2021-04-28)
|
15
|
+
|
16
|
+
* Require at least ruby 1.9.3 [@toy](https://github.com/toy)
|
17
|
+
* Add support for use as [pre-commit](https://pre-commit.com/) hook [#192](https://github.com/toy/image_optim/pull/192) [@proinsias](https://github.com/proinsias)
|
18
|
+
* Fix `Path#copy_metadata` by rescuing also `Errno::EACCES` as it is done in `fileutils` [#187](https://github.com/toy/image_optim/issues/187) [@toy](https://github.com/toy)
|
19
|
+
* More precise regular expression for capturing svgo version [@toy](https://github.com/toy)
|
20
|
+
|
21
|
+
## v0.28.0 (2020-12-18)
|
22
|
+
|
23
|
+
* Fix and update list of markers in jpegoptim worker: allow to pass `com` instead of incorrect `comments` and add missing `xmp` and `none` [#188](https://github.com/toy/image_optim/issues/188) [@toy](https://github.com/toy)
|
24
|
+
* Add `--skip-if-larger` flag to pngquant worker. The pngquant worker already does this, but this will make it fail faster. [#125](https://github.com/toy/image_optim/pull/125) [#181](https://github.com/toy/image_optim/pull/181) [@iggant](https://github.com/iggant) [@oblakeerickson](https://github.com/oblakeerickson)
|
25
|
+
* Add `method` option for jpegrecompress, default to `ssim` [#102](https://github.com/toy/image_optim/issues/102) [#103](https://github.com/toy/image_optim/pull/103) [#182](https://github.com/toy/image_optim/pull/182) [@ramiroaraujo](https://github.com/ramiroaraujo) [@oblakeerickson](https://github.com/oblakeerickson)
|
26
|
+
|
5
27
|
## v0.27.1 (2020-09-30)
|
6
28
|
|
7
29
|
* 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)
|
data/CONTRIBUTING.markdown
CHANGED
@@ -2,10 +2,13 @@
|
|
2
2
|
|
3
3
|
* Create topic/feature branch: `git checkout -b awesome-changes`
|
4
4
|
* Commit…
|
5
|
-
* Add entry at the top of [ChangeLog](CHANGELOG.markdown)
|
5
|
+
* Add an entry at the top (after ## unreleased) of [ChangeLog](CHANGELOG.markdown), include:
|
6
|
+
* Issues (`[#123](https://github.com/toy/image_optim/issues/123)`)
|
7
|
+
* Pull requests (`[#123](https://github.com/toy/image_optim/pull/123)`)
|
8
|
+
* Authors (`[@octocat](https://github.com/octocat)`)
|
6
9
|
* Run tests: `bundle exec rspec`
|
7
10
|
* Check code style: `bundle exec rubocop`
|
8
11
|
* Rebase on master and squash commits to logical units
|
9
12
|
* Push your branch: `git push origin awesome-changes`
|
10
13
|
* Create pull request
|
11
|
-
* Check if [
|
14
|
+
* Check if [github actions workflow is happy](https://github.com/toy/image_optim_pack/actions/workflows/check.yml)
|
data/Gemfile
CHANGED
@@ -4,14 +4,8 @@ source 'https://rubygems.org'
|
|
4
4
|
|
5
5
|
gemspec
|
6
6
|
|
7
|
-
if ENV['
|
7
|
+
if ENV['CC_TEST_REPORTER_ID']
|
8
8
|
group :test do
|
9
9
|
gem 'simplecov'
|
10
|
-
|
11
|
-
gem 'codeclimate-test-reporter'
|
12
10
|
end
|
13
11
|
end
|
14
|
-
|
15
|
-
if ENV['CHECK_RUBIES']
|
16
|
-
gem 'travis_check_rubies', '~> 0.2'
|
17
|
-
end
|
data/LICENSE.txt
CHANGED
data/README.markdown
CHANGED
@@ -1,10 +1,10 @@
|
|
1
|
-
[](https://rubygems.org/gems/image_optim)
|
2
|
+
[](https://github.com/toy/image_optim/actions/workflows/check.yml)
|
3
|
+
[](https://ci.appveyor.com/project/toy/image-optim)
|
4
|
+
[](https://codeclimate.com/github/toy/image_optim)
|
5
|
+
[](https://codeclimate.com/github/toy/image_optim)
|
6
|
+
[](https://depfu.com/github/toy/image_optim)
|
7
|
+
[](https://inch-ci.org/github/toy/image_optim)
|
8
8
|
|
9
9
|
# image_optim
|
10
10
|
|
@@ -18,6 +18,7 @@ Command line tool and ruby interface to optimize (lossless compress, optionally
|
|
18
18
|
* [jpeg-recompress](https://github.com/danielgtaylor/jpeg-archive#jpeg-recompress)
|
19
19
|
* jpegtran from [Independent JPEG Group's JPEG library](http://www.ijg.org/)
|
20
20
|
* [optipng](http://optipng.sourceforge.net/)
|
21
|
+
* [oxipng](https://github.com/shssoichiro/oxipng)
|
21
22
|
* [pngcrush](http://pmt.sourceforge.net/pngcrush/)
|
22
23
|
* [pngout](http://www.advsys.net/ken/util/pngout.htm)
|
23
24
|
* [pngquant](http://pngquant.org/)
|
@@ -60,7 +61,7 @@ With version:
|
|
60
61
|
|
61
62
|
<!---<update-version>-->
|
62
63
|
```ruby
|
63
|
-
gem 'image_optim', '~> 0.
|
64
|
+
gem 'image_optim', '~> 0.31'
|
64
65
|
```
|
65
66
|
<!---</update-version>-->
|
66
67
|
|
@@ -166,6 +167,14 @@ sudo port install advancecomp gifsicle jhead jpegoptim jpeg optipng pngcrush png
|
|
166
167
|
brew install advancecomp gifsicle jhead jpegoptim jpeg optipng pngcrush pngquant jonof/kenutils/pngout
|
167
168
|
```
|
168
169
|
|
170
|
+
### oxipng installation (optional)
|
171
|
+
|
172
|
+
Unless it is available in your chosen package manager, can be installed using cargo:
|
173
|
+
|
174
|
+
```bash
|
175
|
+
cargo install oxipng
|
176
|
+
```
|
177
|
+
|
169
178
|
### pngout installation (optional)
|
170
179
|
|
171
180
|
If you installed the dependencies via brew, pngout should be installed already. Otherwise, you can install `pngout` by downloading and installing the [binary versions](http://www.jonof.id.au/kenutils).
|
@@ -291,6 +300,7 @@ optipng:
|
|
291
300
|
* `:allow_lossy` — Allow lossy workers and optimizations *(defaults to `false`)*
|
292
301
|
* `:cache_dir` — Configure cache directory
|
293
302
|
* `:cache_worker_digests` - Also cache worker digests along with original file digest and worker options: updating workers invalidates cache
|
303
|
+
* `:timeout` — Maximum time in seconds to spend on one image, note multithreading and cache *(defaults to unlimited)*
|
294
304
|
|
295
305
|
Worker can be disabled by passing `false` instead of options hash or by setting option `:disable` to `true`.
|
296
306
|
|
@@ -310,12 +320,13 @@ Worker has no options
|
|
310
320
|
|
311
321
|
### jpegoptim:
|
312
322
|
* `:allow_lossy` — Allow limiting maximum quality *(defaults to `false`)*
|
313
|
-
* `:strip` — List of
|
323
|
+
* `:strip` — List of markers to strip: `:com`, `:exif`, `:iptc`, `:icc`, `:xmp`, `:none` or `:all` *(defaults to `:all`)*
|
314
324
|
* `:max_quality` — Maximum image quality factor `0`..`100`, ignored in default/lossless mode *(defaults to `100`)*
|
315
325
|
|
316
326
|
### jpegrecompress:
|
317
327
|
* `:allow_lossy` — Allow worker, it is always lossy *(defaults to `false`)*
|
318
328
|
* `:quality` — JPEG quality preset: `0` - low, `1` - medium, `2` - high, `3` - veryhigh *(defaults to `3`)*
|
329
|
+
* `:method` — Comparison Metric: `mpe` - Mean pixel error, `ssim` - Structural similarity, `ms-ssim` - Multi-scale structural similarity (slow!), `smallfry` - Linear-weighted BBCQ-like (may be patented) *(defaults to ssim)*
|
319
330
|
|
320
331
|
### jpegtran:
|
321
332
|
* `:copy_chunks` — Copy all chunks *(defaults to `false`)*
|
@@ -361,4 +372,4 @@ In separate file [CHANGELOG.markdown](CHANGELOG.markdown).
|
|
361
372
|
|
362
373
|
## Copyright
|
363
374
|
|
364
|
-
Copyright (c) 2012-
|
375
|
+
Copyright (c) 2012-2021 Ivan Kuchin. See [LICENSE.txt](LICENSE.txt) for details.
|
data/Vagrantfile
CHANGED
data/image_optim.gemspec
CHANGED
@@ -2,12 +2,14 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = 'image_optim'
|
5
|
-
s.version = '0.
|
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)}
|
5
|
+
s.version = '0.31.0'
|
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, oxipng, pngcrush, pngout, pngquant, svgo)}
|
7
7
|
s.homepage = "https://github.com/toy/#{s.name}"
|
8
8
|
s.authors = ['Ivan Kuchin']
|
9
9
|
s.license = 'MIT'
|
10
10
|
|
11
|
+
s.required_ruby_version = '>= 1.9.3'
|
12
|
+
|
11
13
|
s.metadata = {
|
12
14
|
'bug_tracker_uri' => "https://github.com/toy/#{s.name}/issues",
|
13
15
|
'changelog_uri' => "https://github.com/toy/#{s.name}/blob/master/CHANGELOG.markdown",
|
@@ -33,7 +35,8 @@ EOF
|
|
33
35
|
|
34
36
|
s.add_development_dependency 'image_optim_pack', '~> 0.2', '>= 0.2.2'
|
35
37
|
s.add_development_dependency 'rspec', '~> 3.0'
|
36
|
-
if RUBY_VERSION >= '2.
|
37
|
-
s.add_development_dependency 'rubocop', '~>
|
38
|
+
if RUBY_VERSION >= '2.4' && !Gem.win_platform? && !defined?(JRUBY_VERSION)
|
39
|
+
s.add_development_dependency 'rubocop', '~> 1.0'
|
40
|
+
s.add_development_dependency 'rubocop-rspec', '~> 2.0'
|
38
41
|
end
|
39
42
|
end
|
@@ -14,6 +14,7 @@ class ImageOptim
|
|
14
14
|
# Holds bin name and path, gets version
|
15
15
|
class Bin
|
16
16
|
class UnknownVersion < Error; end
|
17
|
+
|
17
18
|
class BadVersion < Error; end
|
18
19
|
|
19
20
|
attr_reader :name, :path, :version
|
@@ -37,30 +38,30 @@ class ImageOptim
|
|
37
38
|
is = ComparableCondition.is
|
38
39
|
|
39
40
|
FAIL_CHECKS = {
|
40
|
-
:
|
41
|
+
pngcrush: [
|
41
42
|
[is.between?('1.7.60', '1.7.65'), 'is known to produce broken pngs'],
|
42
43
|
[is == '1.7.80', 'loses one color in indexed images'],
|
43
44
|
],
|
44
|
-
:
|
45
|
+
pngquant: [
|
45
46
|
[is < '2.0', 'is not supported'],
|
46
47
|
],
|
47
48
|
}.freeze
|
48
49
|
|
49
50
|
WARN_CHECKS = {
|
50
|
-
:
|
51
|
+
advpng: [
|
51
52
|
[is == 'none', 'is of unknown version'],
|
52
53
|
[is < '1.17', 'does not use zopfli'],
|
53
54
|
],
|
54
|
-
:
|
55
|
+
gifsicle: [
|
55
56
|
[is < '1.85', 'does not support removing extension blocks'],
|
56
57
|
],
|
57
|
-
:
|
58
|
+
pngcrush: [
|
58
59
|
[is < '1.7.38', 'does not have blacken flag'],
|
59
60
|
],
|
60
|
-
:
|
61
|
+
pngquant: [
|
61
62
|
[is < '2.1', 'may be lossy even with quality `100-`'],
|
62
63
|
],
|
63
|
-
:
|
64
|
+
optipng: [
|
64
65
|
[is < '0.7', 'does not support -strip option'],
|
65
66
|
],
|
66
67
|
}.freeze
|
@@ -108,10 +109,10 @@ class ImageOptim
|
|
108
109
|
case name
|
109
110
|
when :advpng
|
110
111
|
capture("#{escaped_path} --version 2> #{Path::NULL}")[/\bv(\d+(\.\d+)+|none)/, 1]
|
111
|
-
when :gifsicle, :jpegoptim, :optipng
|
112
|
+
when :gifsicle, :jpegoptim, :optipng, :oxipng
|
112
113
|
capture("#{escaped_path} --version 2> #{Path::NULL}")[/\d+(\.\d+)+/]
|
113
114
|
when :svgo, :pngquant
|
114
|
-
capture("#{escaped_path} --version 2>&1")[/\d+(\.\d+)+/]
|
115
|
+
capture("#{escaped_path} --version 2>&1")[/\A\d+(\.\d+)+/]
|
115
116
|
when :jhead, :'jpeg-recompress'
|
116
117
|
capture("#{escaped_path} -V 2> #{Path::NULL}")[/\d+(\.\d+)+/]
|
117
118
|
when :jpegtran
|
data/lib/image_optim/cache.rb
CHANGED
@@ -21,6 +21,11 @@ class ImageOptim
|
|
21
21
|
"#{bin.name}[#{bin.digest}]"
|
22
22
|
end.sort!.uniq.join(', ')]
|
23
23
|
end]
|
24
|
+
@global_options = begin
|
25
|
+
options = {}
|
26
|
+
options[:timeout] = image_optim.timeout if image_optim.timeout
|
27
|
+
options.empty? ? '' : options.inspect
|
28
|
+
end
|
24
29
|
end
|
25
30
|
|
26
31
|
def fetch(original)
|
@@ -68,6 +73,7 @@ class ImageOptim
|
|
68
73
|
digest = Digest::SHA1.file(path)
|
69
74
|
digest.update options_by_format(format)
|
70
75
|
digest.update bins_by_format(format) if @cache_worker_digests
|
76
|
+
digest.update @global_options
|
71
77
|
s = digest.hexdigest
|
72
78
|
"#{s[0..1]}/#{s[2..-1]}"
|
73
79
|
end
|
data/lib/image_optim/cmd.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'image_optim/errors'
|
3
4
|
require 'English'
|
4
5
|
|
5
6
|
class ImageOptim
|
@@ -10,11 +11,30 @@ class ImageOptim
|
|
10
11
|
# Return success status
|
11
12
|
# Will raise SignalException if process was interrupted
|
12
13
|
def run(*args)
|
13
|
-
|
14
|
+
if args.last.is_a?(Hash) && (timeout = args.last.delete(:timeout))
|
15
|
+
args.last[Gem.win_platform? ? :new_pgroup : :pgroup] = true
|
14
16
|
|
15
|
-
|
17
|
+
pid = Process.spawn(*args)
|
18
|
+
|
19
|
+
waiter = Process.detach(pid)
|
20
|
+
if waiter.join(timeout.to_f)
|
21
|
+
status = waiter.value
|
22
|
+
|
23
|
+
check_status!(status)
|
24
|
+
|
25
|
+
status.success?
|
26
|
+
else
|
27
|
+
cleanup(pid, waiter)
|
16
28
|
|
17
|
-
|
29
|
+
fail Errors::TimeoutExceeded
|
30
|
+
end
|
31
|
+
else
|
32
|
+
success = system(*args)
|
33
|
+
|
34
|
+
check_status!
|
35
|
+
|
36
|
+
success
|
37
|
+
end
|
18
38
|
end
|
19
39
|
|
20
40
|
# Run using backtick
|
@@ -30,9 +50,7 @@ class ImageOptim
|
|
30
50
|
|
31
51
|
private
|
32
52
|
|
33
|
-
def check_status!
|
34
|
-
status = $CHILD_STATUS
|
35
|
-
|
53
|
+
def check_status!(status = $CHILD_STATUS)
|
36
54
|
return unless status.signaled?
|
37
55
|
|
38
56
|
# jruby incorrectly returns true for `signaled?` if process exits with
|
@@ -46,6 +64,27 @@ class ImageOptim
|
|
46
64
|
|
47
65
|
fail SignalException, status.termsig
|
48
66
|
end
|
67
|
+
|
68
|
+
def cleanup(pid, waiter)
|
69
|
+
if Gem.win_platform?
|
70
|
+
kill('KILL', pid)
|
71
|
+
else
|
72
|
+
kill('-TERM', pid)
|
73
|
+
|
74
|
+
# Allow 10 seconds for the process to exit
|
75
|
+
waiter.join(10)
|
76
|
+
|
77
|
+
kill('-KILL', pid)
|
78
|
+
end
|
79
|
+
|
80
|
+
waiter.join
|
81
|
+
end
|
82
|
+
|
83
|
+
def kill(signal, pid)
|
84
|
+
Process.kill(signal, pid)
|
85
|
+
rescue Errno::ESRCH, Errno::EPERM
|
86
|
+
# expected
|
87
|
+
end
|
49
88
|
end
|
50
89
|
end
|
51
90
|
end
|
data/lib/image_optim/config.rb
CHANGED
@@ -15,9 +15,7 @@ class ImageOptim
|
|
15
15
|
|
16
16
|
# Global config path at `$XDG_CONFIG_HOME/image_optim.yml` (by default
|
17
17
|
# `~/.config/image_optim.yml`)
|
18
|
-
GLOBAL_PATH =
|
19
|
-
File.join(ENV['XDG_CONFIG_HOME'] || '~/.config', 'image_optim.yml')
|
20
|
-
end
|
18
|
+
GLOBAL_PATH = File.join(ENV['XDG_CONFIG_HOME'] || '~/.config', 'image_optim.yml')
|
21
19
|
|
22
20
|
# Local config path at `./.image_optim.yml`
|
23
21
|
LOCAL_PATH = './.image_optim.yml'
|
@@ -119,6 +117,14 @@ class ImageOptim
|
|
119
117
|
end
|
120
118
|
end
|
121
119
|
|
120
|
+
# Timeout in seconds for each image:
|
121
|
+
# * not set by default and for `nil`
|
122
|
+
# * otherwise converted to float
|
123
|
+
def timeout
|
124
|
+
timeout = get!(:timeout)
|
125
|
+
timeout ? timeout.to_f : nil
|
126
|
+
end
|
127
|
+
|
122
128
|
# Verbose mode, converted to boolean
|
123
129
|
def verbose
|
124
130
|
!!get!(:verbose)
|
@@ -177,10 +183,10 @@ class ImageOptim
|
|
177
183
|
when true, nil
|
178
184
|
{}
|
179
185
|
when false
|
180
|
-
{:
|
186
|
+
{disable: true}
|
181
187
|
else
|
182
188
|
fail ConfigurationError, "Got #{worker_options.inspect} for "\
|
183
|
-
|
189
|
+
"#{klass.name} options"
|
184
190
|
end
|
185
191
|
end
|
186
192
|
|
@@ -197,10 +203,10 @@ class ImageOptim
|
|
197
203
|
when /darwin9/
|
198
204
|
Cmd.capture 'hwprefs cpu_count'
|
199
205
|
when /darwin/
|
200
|
-
if (Cmd.capture 'which hwprefs')
|
201
|
-
Cmd.capture 'hwprefs thread_count'
|
202
|
-
else
|
206
|
+
if (Cmd.capture 'which hwprefs') == ''
|
203
207
|
Cmd.capture 'sysctl -n hw.ncpu'
|
208
|
+
else
|
209
|
+
Cmd.capture 'hwprefs thread_count'
|
204
210
|
end
|
205
211
|
when /linux/
|
206
212
|
Cmd.capture 'grep -c processor /proc/cpuinfo'
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class ImageOptim
|
4
|
+
# Use Process.clock_gettime if available to get time more fitting to calculate elapsed time
|
5
|
+
module ElapsedTime
|
6
|
+
CLOCK_NAME = %w[
|
7
|
+
CLOCK_UPTIME_RAW
|
8
|
+
CLOCK_UPTIME
|
9
|
+
CLOCK_MONOTONIC_RAW
|
10
|
+
CLOCK_MONOTONIC
|
11
|
+
CLOCK_REALTIME
|
12
|
+
].find{ |name| Process.const_defined?(name) }
|
13
|
+
|
14
|
+
CLOCK_ID = CLOCK_NAME && Process.const_get(CLOCK_NAME)
|
15
|
+
|
16
|
+
module_function
|
17
|
+
|
18
|
+
def now
|
19
|
+
if CLOCK_ID
|
20
|
+
Process.clock_gettime(CLOCK_ID)
|
21
|
+
else
|
22
|
+
Time.now.to_f
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
data/lib/image_optim/path.rb
CHANGED