mini_portile2 2.2.0.rc1 → 2.5.1

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
- SHA1:
3
- metadata.gz: 7085b002833202ee7455beb829f9fb787bca8129
4
- data.tar.gz: 097a89cc3ffe2a742947a3310c284d518ab8a9f6
2
+ SHA256:
3
+ metadata.gz: 1f30e371678c82b2de1219ec842fa298bf1e6acc47b2f210ebfda77939aed190
4
+ data.tar.gz: 7ac927dc6453bf1532db4e55677cebefa115b17fffc43358ef68b8d80c967210
5
5
  SHA512:
6
- metadata.gz: 033fb41be5b3c882e6a02eb806695a22db54ce2b8ef2253b9475822f4bb5764157d411cb2a2da143da8c10ca887e65fc85a0dd60c741867d700ce07afa688e20
7
- data.tar.gz: 6b0df87be823d602b38508a924f85de1d1923840d184484bddb7ccf05542e8d9895919593c6e8870c5515b320ddd640aec5f20470ad1b19dd348ff28f1605fac
6
+ metadata.gz: df62e128fdb0a950c7f6eb45ba97bdab7793b6e8b6e4a139dd5fe93913bffee194a5505114dfe421f6d64efb25ad17215eb8f1ecd8fdc1d40969aa2b888bebee
7
+ data.tar.gz: c05f9262bdbb32fcdcda598c8ae0f16962219f39306ae9d4433b1e13af6e2c2ec181c33864ee99284ebe5f82828940ce3d96a9bb9a4ce00947ab56b7d3699252
@@ -0,0 +1 @@
1
+ tidelift: "rubygems/mini_portile2"
@@ -0,0 +1,62 @@
1
+ name: Continuous Integration
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ types: [opened, synchronize]
8
+ branches: [main]
9
+ schedule:
10
+ - cron: "0 8 * * 5" # At 08:00 on Friday # https://crontab.guru/#0_8_*_*_5
11
+ workflow_dispatch:
12
+
13
+ jobs:
14
+ test-unit:
15
+ env:
16
+ MAKEFLAGS: -j2
17
+ strategy:
18
+ matrix:
19
+ platform: [ubuntu-latest, windows-latest]
20
+ ruby: ["2.5", "2.6", "2.7", "3.0"]
21
+ runs-on: ${{ matrix.platform }}
22
+ steps:
23
+ - name: configure git crlf on windows
24
+ if: matrix.platform == 'windows-latest'
25
+ run: |
26
+ git config --system core.autocrlf false
27
+ git config --system core.eol lf
28
+ - uses: actions/checkout@v2
29
+ - uses: MSP-Greg/setup-ruby-pkgs@v1
30
+ with:
31
+ apt-get: _update_ build-essential cmake
32
+ mingw: _upgrade_ cmake
33
+ ruby-version: ${{ matrix.ruby }}
34
+ bundler-cache: true
35
+ - run: bundle exec rake test:unit
36
+
37
+ test-examples:
38
+ env:
39
+ MAKEFLAGS: -j2
40
+ strategy:
41
+ matrix:
42
+ platform: [ubuntu-latest, windows-latest]
43
+ ruby: ["3.0"]
44
+ runs-on: ${{ matrix.platform }}
45
+ steps:
46
+ - name: configure git crlf on windows
47
+ if: matrix.platform == 'windows-latest'
48
+ run: |
49
+ git config --system core.autocrlf false
50
+ git config --system core.eol lf
51
+ - uses: actions/checkout@v2
52
+ - uses: MSP-Greg/setup-ruby-pkgs@v1
53
+ with:
54
+ apt-get: _update_ build-essential cmake
55
+ mingw: _upgrade_ cmake
56
+ ruby-version: ${{ matrix.ruby }}
57
+ bundler-cache: true
58
+ - uses: actions/cache@v2
59
+ with:
60
+ path: examples/ports/archives
61
+ key: ${{ matrix.platform }}-examples-${{ hashFiles('examples/Rakefile') }}
62
+ - run: bundle exec rake test:examples
data/.gitignore CHANGED
@@ -1,5 +1,5 @@
1
- pkg
2
- tmp
3
- Gemfile.lock
4
1
  .bundle
2
+ Gemfile.lock
3
+ pkg
5
4
  ports
5
+ tmp
data/CHANGELOG.md CHANGED
@@ -1,8 +1,49 @@
1
- ### 2.2.0.rc1 / 2016-03-08
1
+ ## mini_portile changelog
2
+
3
+ ### 2.5.1 / 2021-04-28
4
+
5
+ #### Dependencies
6
+
7
+ This release ends support for ruby < 2.3.0. If you're on 2.2.x or earlier, we strongly suggest that you find the time to upgrade, because [official support for Ruby 2.2 ended on 2018-03-31](https://www.ruby-lang.org/en/news/2018/06/20/support-of-ruby-2-2-has-ended/).
8
+
9
+ #### Enhancements
10
+
11
+ * `MiniPortile.execute` now takes an optional `:env` hash, which is merged into the environment variables for the subprocess. Likely this is only useful for specialized use cases. [#99]
12
+ * Experimental support for cmake-based projects extended to Windows. (Thanks, @larskanis!)
13
+
14
+
15
+ ### 2.5.0 / 2020-02-24
16
+
17
+ #### Enhancements
18
+
19
+ * When verifying GPG signatures, remove all imported pubkeys from keyring [#90] (Thanks, @hanazuki!)
20
+
21
+
22
+ ### 2.4.0 / 2018-12-02
23
+
24
+ #### Enhancements
25
+
26
+ * Skip progress report when Content-Length is unavailable. [#85] (Thanks, @eagletmt!)
27
+
28
+
29
+ ### 2.3.0 / 2017-09-13
30
+
31
+ #### Enhancements
32
+
33
+ * Verify checksums of files at extraction time (in addition to at download time). (#56)
34
+ * Clarify error message if a `tar` command can't be found. (#81)
35
+
36
+
37
+ ### 2.2.0 / 2017-06-04
2
38
 
3
39
  #### Enhancements
4
40
 
5
- * Add experimental support for cmake-based projects
41
+ * Remove MD5 hashing of configure options, not avialbale in FIPS mode. (#78)
42
+ * Add experimental support for cmake-based projects.
43
+ * Retry on HTTP failures during downloads. [#63] (Thanks, @jtarchie and @jvshahid!)
44
+ * Support Ruby 2.4 frozen string literals.
45
+ * Support applying patches for users with misconfigured git worktree. [#69]
46
+ * Support gpg signature verification of download resources.
6
47
 
7
48
 
8
49
  ### 2.1.0 / 2016-01-06
data/README.md CHANGED
@@ -5,8 +5,8 @@ renamed to `mini_portile2`. For mini_portile versions 0.6.x and
5
5
  previous, please visit
6
6
  [the v0.6.x branch](https://github.com/flavorjones/mini_portile/tree/v0.6.x).
7
7
 
8
- [![travis status](https://travis-ci.org/flavorjones/mini_portile.svg?branch=master)](https://travis-ci.org/flavorjones/mini_portile?branch=master)
9
- [![appveyor status](https://ci.appveyor.com/api/projects/status/509669xx1qlhqqab/branch/master?svg=true)](https://ci.appveyor.com/project/flavorjones/mini-portile/branch/master)
8
+ [![Continuous Integration](https://github.com/flavorjones/mini_portile/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/flavorjones/mini_portile/actions/workflows/ci.yml)
9
+ [![Tidelift dependencies](https://tidelift.com/badges/package/rubygems/mini_portile2)](https://tidelift.com/subscription/pkg/rubygems-mini.portile2?utm_source=undefined&utm_medium=referral&utm_campaign=readme)
10
10
 
11
11
  * Documentation: http://www.rubydoc.info/github/flavorjones/mini_portile
12
12
  * Source Code: https://github.com/flavorjones/mini_portile
@@ -147,7 +147,7 @@ task :libiconv do
147
147
  recipe = MiniPortile.new("libiconv", "1.13.1")
148
148
  recipe.files << {
149
149
  url: "http://ftp.gnu.org/pub/gnu/libiconv/libiconv-1.13.1.tar.gz"],
150
- md5: "7ab33ebd26687c744a37264a330bbe9a"
150
+ sha256: "55a36168306089009d054ccdd9d013041bfc3ab26be7033d107821f1c4949a49"
151
151
  }
152
152
  checkpoint = ".#{recipe.name}-#{recipe.version}.installed"
153
153
 
@@ -174,6 +174,45 @@ The above example will:
174
174
  As an exercise for the reader, you could specify the libiconv version
175
175
  in an environment variable or a configuration file.
176
176
 
177
+ ### Download verification
178
+ MiniPortile supports HTTPS, HTTP, FTP and FILE sources for download.
179
+ The integrity of the downloaded file can be verified per hash value or PGP signature.
180
+ This is particular important for untrusted sources (non-HTTPS).
181
+
182
+ #### Hash digest verification
183
+ MiniPortile can verify the integrity of the downloaded file per SHA256, SHA1 or MD5 hash digest.
184
+
185
+ ```ruby
186
+ recipe.files << {
187
+ url: "http://your.host/file.tar.bz2",
188
+ sha256: "<32 byte hex value>",
189
+ }
190
+ ```
191
+
192
+ #### PGP signature verification
193
+ MiniPortile can also verify the integrity of the downloaded file per PGP signature.
194
+
195
+ ```ruby
196
+ public_key = <<-EOT
197
+ -----BEGIN PGP PUBLIC KEY BLOCK-----
198
+ Version: GnuPG v1
199
+
200
+ mQENBE7SKu8BCADQo6x4ZQfAcPlJMLmL8zBEBUS6GyKMMMDtrTh3Yaq481HB54oR
201
+ [...]
202
+ -----END PGP PUBLIC KEY BLOCK-----
203
+ EOT
204
+
205
+ recipe.files << {
206
+ url: "http://your.host/file.tar.bz2",
207
+ gpg: {
208
+ key: public_key,
209
+ signature_url: "http://your.host/file.tar.bz2.sig"
210
+ }
211
+ }
212
+ ```
213
+
214
+ Please note, that the `gpg` executable is required to verify the signature.
215
+ It is therefore recommended to use the hash verification method instead of PGP, when used in `extconf.rb` while `gem install`.
177
216
 
178
217
  ### Native and/or Cross Compilation
179
218
 
@@ -201,6 +240,22 @@ toolchain. This has been tested against Ubuntu, OSX and even Windows
201
240
  (RubyInstaller with DevKit)
202
241
 
203
242
 
243
+ ## Support
244
+
245
+ The bug tracker is available here:
246
+
247
+ * https://github.com/flavorjones/mini_portile/issues
248
+
249
+ Consider subscribing to [Tidelift][tidelift] which provides license assurances and timely security notifications for your open source dependencies, including Loofah. [Tidelift][tidelift] subscriptions also help the Loofah maintainers fund our [automated testing](https://ci.nokogiri.org) which in turn allows us to ship releases, bugfixes, and security updates more often.
250
+
251
+ [tidelift]: https://tidelift.com/subscription/pkg/rubygems-mini.portile2?utm_source=rubygems-mini.portile2&utm_medium=referral&utm_campaign=enterprise
252
+
253
+
254
+ ## Security
255
+
256
+ See [`SECURITY.md`](SECURITY.md) for vulnerability reporting details.
257
+
258
+
204
259
  ## License
205
260
 
206
261
  This library is licensed under MIT license. Please see LICENSE.txt for details.
data/Rakefile CHANGED
@@ -1,10 +1,10 @@
1
1
  require "rake/clean"
2
- require 'bundler/gem_tasks'
2
+ require "bundler/gem_tasks"
3
3
 
4
4
  namespace :test do
5
5
  desc "Test MiniPortile by running unit tests"
6
6
  task :unit do
7
- sh "ruby -w -W2 -I. -Ilib -e \"#{Dir["test/test_*.rb"].map{|f| "require '#{f}';"}.join}\" -- -v"
7
+ sh "ruby -w -W2 -I. -Ilib -e \"#{Dir["test/test_*.rb"].map { |f| "require '#{f}';" }.join}\" -- #{ENV["TESTOPTS"]} -v"
8
8
  end
9
9
 
10
10
  desc "Test MiniPortile by compiling examples"
data/SECURITY.md ADDED
@@ -0,0 +1,13 @@
1
+ # Security and Vulnerability Reporting
2
+
3
+ The mini_portile core contributors take security very seriously and investigate all reported vulnerabilities.
4
+
5
+ If you would like to report a vulnerablity or have a security concern regarding mini_portile, please [report it via Tidelift](https://tidelift.com/security).
6
+
7
+ Your report will be acknowledged within 48 hours, and you'll receive a more detailed response within 96 hours indicating next steps in handling your report.
8
+
9
+ If you have not received a reply to your submission within 96 hours, Contact the current security coordinator, Mike Dalessio <mike.dalessio@gmail.com>.
10
+
11
+ The information you share with the mini_portile core contributors as part of this process will be kept confidential within the team, unless or until we need to share information upstream with our dependent libraries' core teams, at which point we will notify you.
12
+
13
+ If a vulnerability is first reported by you, we will credit you with the discovery in the public disclosure.
@@ -4,7 +4,7 @@ require 'net/https'
4
4
  require 'net/ftp'
5
5
  require 'fileutils'
6
6
  require 'tempfile'
7
- require 'digest/md5'
7
+ require 'digest'
8
8
  require 'open-uri'
9
9
  require 'cgi'
10
10
  require 'rbconfig'
@@ -34,7 +34,17 @@ class MiniPortile
34
34
  attr_accessor :host, :files, :patch_files, :target, :logger
35
35
 
36
36
  def self.windows?
37
- RbConfig::CONFIG['target_os'] =~ /mswin|mingw32/
37
+ RbConfig::CONFIG['target_os'] =~ /mswin|mingw/
38
+ end
39
+
40
+ # GNU MinGW compiled Ruby?
41
+ def self.mingw?
42
+ RbConfig::CONFIG['target_os'] =~ /mingw/
43
+ end
44
+
45
+ # MS Visual-C compiled Ruby?
46
+ def self.mswin?
47
+ RbConfig::CONFIG['target_os'] =~ /mswin/
38
48
  end
39
49
 
40
50
  def initialize(name, version)
@@ -58,6 +68,7 @@ class MiniPortile
58
68
 
59
69
  def extract
60
70
  files_hashs.each do |file|
71
+ verify_file(file)
61
72
  extract_file(file[:local_path], tmp_path)
62
73
  end
63
74
  end
@@ -72,7 +83,7 @@ class MiniPortile
72
83
  message "Running git apply with #{file}... "
73
84
  # By --work-tree=. git-apply uses the current directory as
74
85
  # the project root and will not search upwards for .git.
75
- execute('patch', ["git", "--work-tree=.", "apply", "--whitespace=warn", file], :initial_message => false)
86
+ execute('patch', ["git", "--git-dir=.", "--work-tree=.", "apply", "--whitespace=warn", file], :initial_message => false)
76
87
  }
77
88
  when which('patch')
78
89
  lambda { |file|
@@ -99,9 +110,8 @@ class MiniPortile
99
110
  def configure
100
111
  return if configured?
101
112
 
102
- md5_file = File.join(tmp_path, 'configure.md5')
103
- digest = Digest::MD5.hexdigest(computed_options.to_s)
104
- File.open(md5_file, "w") { |f| f.write digest }
113
+ cache_file = File.join(tmp_path, 'configure.options_cache')
114
+ File.open(cache_file, "w") { |f| f.write computed_options.to_s }
105
115
 
106
116
  if RUBY_PLATFORM=~/mingw|mswin/
107
117
  # Windows doesn't recognize the shebang.
@@ -131,12 +141,12 @@ class MiniPortile
131
141
  def configured?
132
142
  configure = File.join(work_path, 'configure')
133
143
  makefile = File.join(work_path, 'Makefile')
134
- md5_file = File.join(tmp_path, 'configure.md5')
144
+ cache_file = File.join(tmp_path, 'configure.options_cache')
135
145
 
136
- stored_md5 = File.exist?(md5_file) ? File.read(md5_file) : ""
137
- current_md5 = Digest::MD5.hexdigest(computed_options.to_s)
146
+ stored_options = File.exist?(cache_file) ? File.read(cache_file) : ""
147
+ current_options = computed_options.to_s
138
148
 
139
- (current_md5 == stored_md5) && newer?(makefile, configure)
149
+ (current_options == stored_options) && newer?(makefile, configure)
140
150
  end
141
151
 
142
152
  def installed?
@@ -251,16 +261,50 @@ private
251
261
  end
252
262
  end
253
263
 
264
+ KEYRING_NAME = "mini_portile_keyring.gpg"
265
+
254
266
  def verify_file(file)
255
- digest = case
256
- when exp=file[:sha256] then Digest::SHA256
257
- when exp=file[:sha1] then Digest::SHA1
258
- when exp=file[:md5] then Digest::MD5
259
- end
260
- if digest
261
- is = digest.file(file[:local_path]).hexdigest
262
- unless is == exp.downcase
263
- raise "Downloaded file '#{file[:local_path]}' has wrong hash: expected: #{exp} is: #{is}"
267
+ if file.has_key?(:gpg)
268
+ gpg = file[:gpg]
269
+
270
+ signature_url = gpg[:signature_url] || "#{file[:url]}.asc"
271
+ signature_file = file[:local_path] + ".asc"
272
+ # download the signature file
273
+ download_file(signature_url, signature_file)
274
+
275
+ gpg_exe = which('gpg2') || which('gpg') || raise("Neither GPG nor GPG2 is installed")
276
+
277
+ # import the key into our own keyring
278
+ gpg_status = IO.popen([gpg_exe, "--status-fd", "1", "--no-default-keyring", "--keyring", KEYRING_NAME, "--import"], "w+") do |io|
279
+ io.write gpg[:key]
280
+ io.close_write
281
+ io.read
282
+ end
283
+ key_ids = gpg_status.scan(/\[GNUPG:\] IMPORT_OK \d+ (?<key_id>[0-9a-f]+)/i).map(&:first)
284
+ raise "invalid gpg key provided" if key_ids.empty?
285
+
286
+ # verify the signature against our keyring
287
+ gpg_status = IO.popen([gpg_exe, "--status-fd", "1", "--no-default-keyring", "--keyring", KEYRING_NAME, "--verify", signature_file, file[:local_path]], &:read)
288
+
289
+ # remove the key from our keyring
290
+ key_ids.each do |key_id|
291
+ IO.popen([gpg_exe, "--batch", "--yes", "--no-default-keyring", "--keyring", KEYRING_NAME, "--delete-keys", key_id], &:read)
292
+ raise "unable to delete the imported key" unless $?.exitstatus==0
293
+ end
294
+
295
+ raise "signature mismatch" unless gpg_status.match(/^\[GNUPG:\] VALIDSIG/)
296
+
297
+ else
298
+ digest = case
299
+ when exp=file[:sha256] then Digest::SHA256
300
+ when exp=file[:sha1] then Digest::SHA1
301
+ when exp=file[:md5] then Digest::MD5
302
+ end
303
+ if digest
304
+ is = digest.file(file[:local_path]).hexdigest
305
+ unless is == exp.downcase
306
+ raise "Downloaded file '#{file[:local_path]}' has wrong hash: expected: #{exp} is: #{is}"
307
+ end
264
308
  end
265
309
  end
266
310
  end
@@ -272,11 +316,12 @@ private
272
316
  }
273
317
  end
274
318
 
319
+ TAR_EXECUTABLES = %w[gtar bsdtar tar basic-bsdtar]
275
320
  def tar_exe
276
321
  @@tar_exe ||= begin
277
- %w[gtar bsdtar tar basic-bsdtar].find { |c|
322
+ TAR_EXECUTABLES.find { |c|
278
323
  which(c)
279
- }
324
+ } or raise("tar not found - please make sure that one of the following commands is in the PATH: #{TAR_EXECUTABLES.join(", ")}")
280
325
  end
281
326
  end
282
327
 
@@ -335,24 +380,36 @@ private
335
380
  execute('extract', [tar_exe, "#{tar_compression_switch(filename)}xf", file, "-C", target], {:cd => Dir.pwd, :initial_message => false})
336
381
  end
337
382
 
338
- def execute(action, command, options={})
339
- log_out = log_file(action)
383
+ # command could be an array of args, or one string containing a command passed to the shell. See
384
+ # Process.spawn for more information.
385
+ def execute(action, command, command_opts={})
386
+ opt_message = command_opts.fetch(:initial_message, true)
387
+ opt_debug = command_opts.fetch(:debug, false)
388
+ opt_cd = command_opts.fetch(:cd) { work_path }
389
+ opt_env = command_opts.fetch(:env) { Hash.new }
340
390
 
341
- Dir.chdir (options.fetch(:cd){ work_path }) do
342
- if options.fetch(:initial_message){ true }
343
- message "Running '#{action}' for #{@name} #{@version}... "
344
- end
391
+ log_out = log_file(action)
392
+
393
+ Dir.chdir(opt_cd) do
394
+ output "DEBUG: env is #{opt_env.inspect}" if opt_debug
395
+ output "DEBUG: command is #{command.inspect}" if opt_debug
396
+ message "Running '#{action}' for #{@name} #{@version}... " if opt_message
345
397
 
346
398
  if Process.respond_to?(:spawn) && ! RbConfig.respond_to?(:java)
347
- args = [command].flatten + [{[:out, :err]=>[log_out, "a"]}]
399
+ options = {[:out, :err]=>[log_out, "a"]}
400
+ output "DEBUG: options are #{options.inspect}" if opt_debug
401
+ args = [opt_env, command, options].flatten
348
402
  pid = spawn(*args)
349
403
  Process.wait(pid)
350
404
  else
351
- redirected = if command.kind_of?(Array)
352
- %Q{#{command.map(&:shellescape).join(" ")} > #{log_out.shellescape} 2>&1}
353
- else
354
- %Q{#{command} > #{log_out.shellescape} 2>&1}
355
- end
405
+ env_args = opt_env.map { |k,v| "#{k}=#{v}".shellescape }.join(" ")
406
+ c = if command.kind_of?(Array)
407
+ command.map(&:shellescape).join(" ")
408
+ else
409
+ command
410
+ end
411
+ redirected = %Q{env #{env_args} #{c} > #{log_out.shellescape} 2>&1}
412
+ output "DEBUG: final command is #{redirected.inspect}" if opt_debug
356
413
  system redirected
357
414
  end
358
415
 
@@ -422,9 +479,14 @@ private
422
479
  "Accept-Encoding" => 'identity',
423
480
  :content_length_proc => lambda{|length| total = length },
424
481
  :progress_proc => lambda{|bytes|
425
- new_progress = (bytes * 100) / total
426
- message "\rDownloading %s (%3d%%) " % [filename, new_progress]
427
- progress = new_progress
482
+ if total
483
+ new_progress = (bytes * 100) / total
484
+ message "\rDownloading %s (%3d%%) " % [filename, new_progress]
485
+ progress = new_progress
486
+ else
487
+ # Content-Length is unavailable because Transfer-Encoding is chunked
488
+ message "\rDownloading %s " % [filename]
489
+ end
428
490
  }
429
491
  }
430
492
  proxy_uri = URI.parse(url).scheme.downcase == 'https' ?
@@ -438,6 +500,7 @@ private
438
500
  [proxy_uri, proxy_user, proxy_pass]
439
501
  end
440
502
  end
503
+
441
504
  begin
442
505
  OpenURI.open_uri(url, 'rb', params) do |io|
443
506
  temp_file << io.read
@@ -446,8 +509,15 @@ private
446
509
  rescue OpenURI::HTTPRedirect => redirect
447
510
  raise "Too many redirections for the original URL, halting." if count <= 0
448
511
  count = count - 1
449
- return download_file(redirect.url, full_path, count - 1)
512
+ return download_file(redirect.url, full_path, count-1)
450
513
  rescue => e
514
+ count = count - 1
515
+ puts "#{count} retrie(s) left for #{filename}"
516
+ if count > 0
517
+ sleep 1
518
+ return download_file_http(url, full_path, count)
519
+ end
520
+
451
521
  output e.message
452
522
  return false
453
523
  end