image_optim 0.17.1 → 0.18.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.
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)