image_optim 0.17.1 → 0.18.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. checksums.yaml +8 -8
  2. data/.gitignore +1 -0
  3. data/.travis.yml +5 -18
  4. data/CHANGELOG.markdown +10 -0
  5. data/README.markdown +31 -1
  6. data/bin/image_optim +3 -137
  7. data/image_optim.gemspec +6 -3
  8. data/lib/image_optim.rb +20 -3
  9. data/lib/image_optim/bin_resolver.rb +28 -1
  10. data/lib/image_optim/bin_resolver/bin.rb +17 -7
  11. data/lib/image_optim/cmd.rb +49 -0
  12. data/lib/image_optim/config.rb +64 -4
  13. data/lib/image_optim/image_path.rb +5 -0
  14. data/lib/image_optim/option_definition.rb +5 -3
  15. data/lib/image_optim/runner.rb +1 -2
  16. data/lib/image_optim/runner/option_parser.rb +216 -0
  17. data/lib/image_optim/worker.rb +32 -17
  18. data/lib/image_optim/worker/advpng.rb +7 -1
  19. data/lib/image_optim/worker/gifsicle.rb +16 -3
  20. data/lib/image_optim/worker/jhead.rb +15 -8
  21. data/lib/image_optim/worker/jpegoptim.rb +6 -2
  22. data/lib/image_optim/worker/jpegtran.rb +10 -3
  23. data/lib/image_optim/worker/optipng.rb +6 -1
  24. data/lib/image_optim/worker/pngcrush.rb +8 -1
  25. data/lib/image_optim/worker/pngout.rb +8 -1
  26. data/lib/image_optim/worker/svgo.rb +4 -1
  27. data/script/worker_analysis +523 -0
  28. data/script/worker_analysis.haml +153 -0
  29. data/spec/image_optim/bin_resolver/comparable_condition_spec.rb +4 -5
  30. data/spec/image_optim/bin_resolver/simple_version_spec.rb +44 -21
  31. data/spec/image_optim/bin_resolver_spec.rb +63 -29
  32. data/spec/image_optim/cmd_spec.rb +66 -0
  33. data/spec/image_optim/config_spec.rb +38 -38
  34. data/spec/image_optim/handler_spec.rb +15 -12
  35. data/spec/image_optim/hash_helpers_spec.rb +14 -13
  36. data/spec/image_optim/image_path_spec.rb +22 -7
  37. data/spec/image_optim/runner/glob_helpers_spec.rb +6 -5
  38. data/spec/image_optim/runner/option_parser_spec.rb +99 -0
  39. data/spec/image_optim/space_spec.rb +5 -4
  40. data/spec/image_optim/worker_spec.rb +6 -5
  41. data/spec/image_optim_spec.rb +209 -237
  42. data/spec/spec_helper.rb +3 -0
  43. metadata +43 -11
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- ZTM0NDFkYmE3MDIyOTgyMGNkMzEzNDk4NTk1NWI3MjM0ODU1NTJkYQ==
4
+ ZDYwZDFmNGU4YjcwY2NmYmY1OTA5MjRmOTQ1NzhkNjM1MjhjYmUwZQ==
5
5
  data.tar.gz: !binary |-
6
- N2FlNDFjZmNhMDRhOTliOTdkYzA3MjcxMTE0Y2NiMjNiNTdiYWUxYQ==
6
+ ZTNhOTFlMjYxMGU4MjczMThiNDhiZDlkMDI2MGY4ZGM5OTlkOGFhOQ==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- OTBlZDI2NjQwMTkyMjNlYzg3YWUwNjI0NzgxMjgzY2M5ZjI1ZjdjZTg1MDlk
10
- NjQ0MWExMzI1MGM2YjNkYjkwMDVmMjNhNTc5NWQ3MTk5YzY4ZGU5YTM0YTUy
11
- YjhmOWUzMjg1Yzg0YWIxZGJjMzcxODY5NWYyMDRhMDQ2YzFiN2Y=
9
+ NTkyZDBhMTUxYTAxOTBlNjBjYWIxZWUyZGQwYTJlNDExNmJlMWMxNzc1NmE5
10
+ MmFlYzE2NjBjNGFkZWI4MzU1NzQwOTA3M2M0MDk3MjIyMTc1ODYyMzA3OWE0
11
+ NTMwNDEwMWM5ODI1MDlmZDk0NzdiNzBmYWQ2YmVhN2VkYjM4OTg=
12
12
  data.tar.gz: !binary |-
13
- OGI2OWRiNzAxZjhjMzM4N2QyZGFkMDc2N2U1NDM1N2YwNGM2NGJjYTE1MDg4
14
- YmNkMTE1MGNlZTk3ODk5MWMwODVlY2UyYWUwYWIyNzllOTViMDA2NWYxNjI2
15
- MjIxMDUzNmVlZTg4YTQxYWE1MWQ2NGMwNjYwMGQ5NDU5NzM3YmE=
13
+ NjkwMzgyYWNkNmYwYjhkMmJiYzY2NzNkY2QwMmZhNDFhZWFmYjhhMzk5ZmM2
14
+ YmNjOTQ2MWY5ZDY3ZGEwYzJmNGZiY2I4OTViNzNjYmNkZmE1YmZhNmFkMjM4
15
+ MzAwZWFlYzBlNTM2OWVjNjRiZjg1MmNlMTJkMTIxMjEzOWNlNDE=
data/.gitignore CHANGED
@@ -13,3 +13,4 @@ Makefile
13
13
  /tmp/
14
14
 
15
15
  /analysis/
16
+ /.analysis_variants.yml
@@ -1,5 +1,4 @@
1
- language:
2
- - ruby
1
+ language: ruby
3
2
  rvm:
4
3
  - 1.8.7
5
4
  - 1.9.2
@@ -12,30 +11,18 @@ rvm:
12
11
  - jruby-head
13
12
  - ree
14
13
  script:
14
+ - bundle exec image_optim --info
15
15
  - bundle exec rspec
16
16
  - '! bundle show rubocop || bundle exec rubocop' # run rubocop only if it is bundled
17
17
  before_install:
18
- - sudo apt-get update -qq
19
- - sudo apt-get install -qq gifsicle jhead jpegoptim libjpeg-progs optipng pngcrush
20
- - npm install -g svgo
21
18
  - mkdir ~/bin
22
19
 
23
- - echo 'Installing advancecomp(advpng):'
24
- - ADVANCECOMP_VERSION=1.19
25
- - wget http://downloads.sourceforge.net/project/advancemame/advancecomp/$ADVANCECOMP_VERSION/advancecomp-$ADVANCECOMP_VERSION.tar.gz
26
- - tar -xzf advancecomp-$ADVANCECOMP_VERSION.tar.gz
27
- - (cd advancecomp-$ADVANCECOMP_VERSION && ./configure && make)
28
- - mv advancecomp-$ADVANCECOMP_VERSION/advpng ~/bin
29
-
30
- - echo 'Installing pngquant:'
31
- - git clone git://github.com/pornel/pngquant.git
32
- - (cd pngquant && git checkout $(git describe --tags --abbrev=0) && make)
33
- - mv pngquant/pngquant ~/bin
20
+ - echo 'Installing svgo:'
21
+ - npm install -g svgo
34
22
 
35
23
  - echo 'Installing pngout:'
36
24
  - PNGOUT_VERSION=20130221
37
- - wget http://static.jonof.id.au/dl/kenutils/pngout-$PNGOUT_VERSION-linux.tar.gz
38
- - tar -xzf pngout-$PNGOUT_VERSION-linux.tar.gz
25
+ - curl -L "http://static.jonof.id.au/dl/kenutils/pngout-$PNGOUT_VERSION-linux.tar.gz" | tar -xz
39
26
  - mv pngout-$PNGOUT_VERSION-linux/x86_64/pngout ~/bin
40
27
  env:
41
28
  - PATH=~/bin:$PATH
@@ -2,6 +2,16 @@
2
2
 
3
3
  ## unreleased
4
4
 
5
+ ## v0.18.0 (2014-11-01)
6
+
7
+ * Add interface to `image_optim_pack` [@toy](https://github.com/toy)
8
+ * Use `in_threads ~> 1.3` [@toy](https://github.com/toy)
9
+ * Added options to Gifsicle, specifically --careful (for compatibility) and --optimize for granularity [#51](https://github.com/toy/image_optim/issues/51) [@kaspergrubbe](https://github.com/kaspergrubbe)
10
+ * `:skip_missing_workers` option to skip workers with missing or problematic binaries [#66](https://github.com/toy/image_optim/issues/66) [@toy](https://github.com/toy)
11
+ * Speedup specs (~8x) [#60](https://github.com/toy/image_optim/issues/60) [@toy](https://github.com/toy)
12
+ * `script/worker_analysis` to compare worker chains by optimization, time and losslessness [@toy](https://github.com/toy)
13
+ * `Cmd` module to ensure interrupted commands can't go unnoticed [@toy](https://github.com/toy)
14
+
5
15
  ## v0.17.1 (2014-10-06)
6
16
 
7
17
  * Fix bin path resolving method missing vendor directory [@toy](https://github.com/toy)
@@ -3,7 +3,6 @@
3
3
  [![Code Climate](https://img.shields.io/codeclimate/github/toy/image_optim.svg?style=flat)](https://codeclimate.com/github/toy/image_optim)
4
4
  [![Dependency Status](https://img.shields.io/gemnasium/toy/image_optim.svg?style=flat)](https://gemnasium.com/toy/image_optim)
5
5
  [![Inch CI](http://inch-ci.org/github/toy/image_optim.svg?branch=master&style=flat)](http://inch-ci.org/github/toy/image_optim)
6
- [![Gittip](https://img.shields.io/gittip/toy.svg?style=flat)](https://www.gittip.com/toy/)
7
6
 
8
7
  # image_optim
9
8
 
@@ -31,6 +30,12 @@ Documentation for [latest version](http://rubydoc.info/gems/image_optim/frames)
31
30
  gem install image_optim
32
31
  ```
33
32
 
33
+ You may also want to install [`image_optim_pack`](https://github.com/toy/image_optim_pack) (see [Binaries pack](#binaries-pack)).
34
+
35
+ ```sh
36
+ gem install image_optim_pack
37
+ ```
38
+
34
39
  ### Bundler
35
40
 
36
41
  Add to your `Gemfile`:
@@ -39,6 +44,13 @@ Add to your `Gemfile`:
39
44
  gem 'image_optim'
40
45
  ```
41
46
 
47
+ With `image_optim_pack`:
48
+
49
+ ```ruby
50
+ gem 'image_optim'
51
+ gem 'image_optim_pack'
52
+ ```
53
+
42
54
  With version:
43
55
 
44
56
  ```ruby
@@ -79,6 +91,14 @@ Besides permanently setting environment variables in `~/.profile`, `~/.bash_prof
79
91
 
80
92
  ## Binaries installation
81
93
 
94
+ ### Binaries pack
95
+
96
+ Easiest way to get latest versions of most binaries for `image_optim` for Linux and Mac OS X is by installing [`image_optim_pack`](https://github.com/toy/image_optim_pack) gem.
97
+
98
+ Check installation instructions in [Gem installation](#gem-installation) section.
99
+
100
+ Pack doesn't include `pngout` and `svgo` binaries, their installation instructions are provided below.
101
+
82
102
  ### Linux - Debian/Ubuntu
83
103
 
84
104
  ```bash
@@ -241,6 +261,8 @@ optipng:
241
261
  * `:nice` — Nice level *(defaults to `10`)*
242
262
  * `:threads` — Number of threads or disable *(defaults to number of processors)*
243
263
  * `:verbose` — Verbose output *(defaults to `false`)*
264
+ * `:pack` — Require image\_optim\_pack or disable it, by default image\_optim\_pack will be used if available, will turn on `:skip-missing-workers` unless explicitly disabled *(defaults to `nil`)*
265
+ * `:skip_missing_workers` — Skip workers with missing or problematic binaries *(defaults to `false`)*
244
266
 
245
267
  Worker can be disabled by passing `false` instead of options hash.
246
268
 
@@ -252,6 +274,8 @@ Worker can be disabled by passing `false` instead of options hash.
252
274
 
253
275
  ### :gifsicle =>
254
276
  * `:interlace` — Turn interlacing on *(defaults to `false`)*
277
+ * `:level` — Compression level: `1` - light and fast, `2` - normal, `3` - heavy (slower) *(defaults to `3`)*
278
+ * `:careful` — Avoid bugs with some software *(defaults to `false`)*
255
279
 
256
280
  ### :jhead =>
257
281
  Worker has no options
@@ -289,8 +313,14 @@ Worker has no options
289
313
 
290
314
  ## Contributing
291
315
 
316
+ [List](https://github.com/toy/image_optim/graphs/contributors) of contributors to `image_optim`.
317
+
292
318
  If you would like to contribute - that is great and you are very welcome. Please check few notes in file [CONTRIBUTING.markdown](CONTRIBUTING.markdown).
293
319
 
320
+ Financial contributions can be made via [gratipay](https://gratipay.com/toy/).
321
+
322
+ [![Support via Gratipay](https://cdn.rawgit.com/gratipay/gratipay-badge/2.1.2/dist/gratipay.png)](https://gratipay.com/toy/)
323
+
294
324
  ## ChangeLog
295
325
 
296
326
  In separate file [CHANGELOG.markdown](CHANGELOG.markdown).
@@ -2,145 +2,13 @@
2
2
  # encoding: UTF-8
3
3
 
4
4
  require 'image_optim/runner'
5
- require 'image_optim/true_false_nil'
6
- require 'image_optim/non_negative_integer_range'
5
+ require 'image_optim/runner/option_parser'
7
6
 
8
- options = {}
7
+ args = ARGV.dup
9
8
 
10
- option_parser = OptionParser.new do |op|
11
- ImageOptim::TrueFalseNil.add_to_option_parser(op)
12
- ImageOptim::NonNegativeIntegerRange.add_to_option_parser(op)
13
-
14
- op.banner = <<-TEXT.gsub(/^\s*\|/, '')
15
- |#{ImageOptim.full_version}
16
- |
17
- |Usege:
18
- | #{op.program_name} [options] image_path …
19
- |
20
- |Configuration will be read and prepanded to options from two paths:
21
- | #{ImageOptim::Config::GLOBAL_PATH}
22
- | #{ImageOptim::Config::LOCAL_PATH}
23
- |
24
- TEXT
25
-
26
- op.on('--config-paths PATH1,PATH2', Array, 'Config paths to use instead of '\
27
- 'default ones') do |paths|
28
- options[:config_paths] = paths
29
- end
30
-
31
- op.separator nil
32
-
33
- op.on('-r', '-R', '--recursive', 'Recursively scan directories '\
34
- 'for images') do |recursive|
35
- options[:recursive] = recursive
36
- end
37
-
38
- op.on("--exclude-dir 'GLOB'", 'Glob for excluding directories '\
39
- '(defaults to .*)') do |glob|
40
- options[:exclude_dir_glob] = glob
41
- end
42
-
43
- op.on("--exclude-file 'GLOB'", 'Glob for excluding files '\
44
- '(defaults to .*)') do |glob|
45
- options[:exclude_file_glob] = glob
46
- end
47
-
48
- op.on("--exclude 'GLOB'", 'Set glob for excluding both directories and '\
49
- 'files') do |glob|
50
- options[:exclude_file_glob] = options[:exclude_dir_glob] = glob
51
- end
52
-
53
- op.separator nil
54
-
55
- op.on('--[no-]threads N', Integer, 'Number of threads or disable '\
56
- '(defaults to number of processors)') do |threads|
57
- options[:threads] = threads
58
- end
59
-
60
- op.on('--[no-]nice N', Integer, 'Nice level (defaults to 10)') do |nice|
61
- options[:nice] = nice
62
- end
63
-
64
- op.separator nil
65
- op.separator ' Disabling workers:'
66
-
67
- ImageOptim::Worker.klasses.each do |klass|
68
- bin = klass.bin_sym
69
- op.on("--no-#{bin}", "disable #{bin} worker") do |enable|
70
- options[bin] = enable
71
- end
72
- end
73
-
74
- op.separator nil
75
- op.separator ' Worker options:'
76
-
77
- ImageOptim::Worker.klasses.each_with_index do |klass, i|
78
- op.separator nil unless i.zero?
79
-
80
- bin = klass.bin_sym
81
- klass.option_definitions.each do |option_definition|
82
- name = option_definition.name.to_s.gsub('_', '-')
83
- default = option_definition.default
84
- type = option_definition.type
85
-
86
- type, marking = case
87
- when [TrueClass, FalseClass, ImageOptim::TrueFalseNil].include?(type)
88
- [type, 'B']
89
- when Integer >= type
90
- [Integer, 'N']
91
- when Array >= type
92
- [Array, 'a,b,c']
93
- when ImageOptim::NonNegativeIntegerRange == type
94
- [type, 'M-N']
95
- else
96
- fail "Unknown type #{type}"
97
- end
98
-
99
- description_lines = %W[
100
- #{option_definition.description.gsub(' - ', ' - ')}
101
- (defaults to #{default})
102
- ].join(' ').
103
- scan(/.*?.{1,60}(?:\s|\z)/).
104
- join("\n ").
105
- split("\n")
106
-
107
- op.on("--#{bin}-#{name} #{marking}", type, *description_lines) do |value|
108
- options[bin] = {} unless options[bin].is_a?(Hash)
109
- options[bin][option_definition.name.to_sym] = value
110
- end
111
- end
112
- end
113
-
114
- op.separator nil
115
- op.separator ' Common options:'
116
-
117
- op.on('-v', '--verbose', 'Verbose output') do
118
- options[:verbose] = true
119
- end
120
-
121
- op.on_tail('-h', '--help', 'Show help and exit') do
122
- puts op.help
123
- exit
124
- end
125
-
126
- op.on_tail('--version', 'Show version and exit') do
127
- puts ImageOptim.version
128
- exit
129
- end
130
-
131
- op.on_tail('--info', 'Show environment info and exit') do
132
- options[:verbose] = true
133
- options[:only_info] = true
134
- end
135
- end
9
+ options = ImageOptim::Runner::OptionParser.parse!(args)
136
10
 
137
11
  begin
138
- args = ARGV.dup
139
-
140
- # assume -v to be a request to print version if it is the only argument
141
- args = %w[--version] if args == %w[-v]
142
-
143
- option_parser.parse!(args)
144
12
  if options[:verbose]
145
13
  $stderr.puts ImageOptim.full_version
146
14
  end
@@ -151,8 +19,6 @@ begin
151
19
  abort 'specify paths to optimize' if args.empty?
152
20
  abort unless runner.run!(args)
153
21
  end
154
- rescue OptionParser::ParseError => e
155
- abort "#{e}\n\n#{option_parser.help}"
156
22
  rescue => e
157
23
  if options[:verbose]
158
24
  abort "#{e}\n#{e.backtrace.join("\n")}"
@@ -2,8 +2,8 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = 'image_optim'
5
- s.version = '0.17.1'
6
- s.summary = %q{Optimize (lossless compress) images (jpeg, png, gif, svg) using external utilities (advpng, gifsicle, jpegoptim, jpegtran, optipng, pngcrush, pngout, pngquant, svgo)}
5
+ s.version = '0.18.0'
6
+ s.summary = %q{Optimize (lossless compress) images (jpeg, png, gif, svg) using external utilities (advpng, gifsicle, jhead, jpegoptim, jpegrescan, jpegtran, optipng, pngcrush, pngout, pngquant, svgo)}
7
7
  s.homepage = "http://github.com/toy/#{s.name}"
8
8
  s.authors = ['Ivan Kuchin']
9
9
  s.license = 'MIT'
@@ -19,9 +19,12 @@ Gem::Specification.new do |s|
19
19
  s.add_dependency 'image_size', '~> 1.3'
20
20
  s.add_dependency 'exifr', '~> 1.1', '>= 1.1.3'
21
21
  s.add_dependency 'progress', '~> 3.0', '>= 3.0.1'
22
- s.add_dependency 'in_threads', '~> 1.2', '>= 1.2.2'
22
+ s.add_dependency 'in_threads', '~> 1.3'
23
+
24
+ s.add_development_dependency 'image_optim_pack', '~> 0.1'
23
25
  s.add_development_dependency 'rspec', '~> 3.0'
24
26
  if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('1.9.3')
25
27
  s.add_development_dependency 'rubocop', '~> 0.26.0'
26
28
  end
29
+ s.add_development_dependency 'haml', '~> 4.0'
27
30
  end
@@ -18,6 +18,12 @@ class ImageOptim
18
18
  # Verbose output?
19
19
  attr_reader :verbose
20
20
 
21
+ # Use image_optim_pack
22
+ attr_reader :pack
23
+
24
+ # Skip workers with missing or problematic binaries
25
+ attr_reader :skip_missing_workers
26
+
21
27
  # Initialize workers, specify options using worker underscored name:
22
28
  #
23
29
  # pass false to disable worker
@@ -42,11 +48,18 @@ class ImageOptim
42
48
  @nice = config.nice
43
49
  @threads = config.threads
44
50
  @verbose = config.verbose
51
+ @pack = config.pack
52
+ @skip_missing_workers = config.skip_missing_workers
45
53
 
46
54
  if verbose
47
- $stderr << config
55
+ $stderr << "config:\n"
56
+ config.to_s.each_line do |line|
57
+ $stderr << " #{line}"
58
+ end
48
59
  $stderr << "nice: #{nice}\n"
49
60
  $stderr << "threads: #{threads}\n"
61
+ $stderr << "pack: #{pack}\n"
62
+ $stderr << "skip_missing_workers: #{skip_missing_workers}\n"
50
63
  end
51
64
 
52
65
  @bin_resolver = BinResolver.new(self)
@@ -100,7 +113,7 @@ class ImageOptim
100
113
  temp.close
101
114
 
102
115
  if (result = optimize_image(temp.path))
103
- result.open('rb', &:read)
116
+ result.binread
104
117
  end
105
118
  end
106
119
  end
@@ -183,7 +196,11 @@ private
183
196
  def create_workers_by_format(&options_proc)
184
197
  by_format = {}
185
198
  workers = Worker.create_all(self, &options_proc)
186
- Worker.resolve_all!(workers)
199
+ if skip_missing_workers
200
+ workers = Worker.reject_missing(workers)
201
+ else
202
+ Worker.resolve_all!(workers)
203
+ end
187
204
  sorted = workers.sort_by.with_index{ |worker, i| [worker.run_order, i] }
188
205
  sorted.each do |worker|
189
206
  worker.image_formats.each do |format|
@@ -15,14 +15,19 @@ class ImageOptim
15
15
  # Directory for symlinks to bins if XXX_BIN was used
16
16
  attr_reader :dir
17
17
 
18
+ # Path to pack from image_optim_pack if used
19
+ attr_reader :pack_path
20
+
18
21
  def initialize(image_optim)
19
22
  @image_optim = image_optim
20
23
  @bins = {}
21
24
  @lock = Mutex.new
25
+ init_pack
22
26
  end
23
27
 
24
28
  # Binary resolving: create symlink if there is XXX_BIN environment variable,
25
29
  # build Bin with full path, check binary version
30
+ # Return Bin instance
26
31
  def resolve!(name)
27
32
  name = name.to_sym
28
33
 
@@ -42,6 +47,8 @@ class ImageOptim
42
47
  else
43
48
  fail BinNotFound, "`#{name}` not found"
44
49
  end
50
+
51
+ @bins[name]
45
52
  end
46
53
 
47
54
  # Path to vendor at root of image_optim
@@ -49,7 +56,12 @@ class ImageOptim
49
56
 
50
57
  # Prepand `dir` and append `VENDOR_PATH` to `PATH` from environment
51
58
  def env_path
52
- [dir, ENV['PATH'], VENDOR_PATH].compact.join(File::PATH_SEPARATOR)
59
+ [
60
+ dir,
61
+ pack_path,
62
+ ENV['PATH'],
63
+ VENDOR_PATH,
64
+ ].compact.join(File::PATH_SEPARATOR)
53
65
  end
54
66
 
55
67
  # Collect resolving errors when running block over items of enumerable
@@ -67,6 +79,21 @@ class ImageOptim
67
79
 
68
80
  private
69
81
 
82
+ def init_pack
83
+ return unless @image_optim.pack
84
+
85
+ @pack_path = if @image_optim.verbose
86
+ Pack.path do |message|
87
+ $stderr << "#{message}\n"
88
+ end
89
+ else
90
+ Pack.path
91
+ end
92
+ return if @pack_path
93
+
94
+ warn 'No pack for this OS and/or ARCH, check verbose output'
95
+ end
96
+
70
97
  # Double-checked locking
71
98
  def resolving(name)
72
99
  return if @bins.include?(name)