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 +5 -5
- data/.github/FUNDING.yml +1 -0
- data/.github/workflows/ci.yml +62 -0
- data/.gitignore +3 -3
- data/CHANGELOG.md +43 -2
- data/README.md +58 -3
- data/Rakefile +2 -2
- data/SECURITY.md +13 -0
- data/lib/mini_portile2/mini_portile.rb +107 -37
- data/lib/mini_portile2/mini_portile_cmake.rb +12 -11
- data/lib/mini_portile2/version.rb +1 -1
- data/mini_portile2.gemspec +25 -20
- data/test/assets/gpg-fixtures/data +1 -0
- data/test/assets/gpg-fixtures/data.asc +9 -0
- data/test/assets/gpg-fixtures/data.invalid.asc +9 -0
- data/test/test_cmake.rb +9 -13
- data/test/test_cook.rb +49 -3
- data/test/test_digest.rb +145 -0
- data/test/test_download.rb +11 -9
- data/test/test_execute.rb +39 -0
- data/test/test_proxy.rb +2 -2
- metadata +44 -23
- data/.concourse.yml +0 -83
- data/.travis.yml +0 -12
- data/appveyor.yml +0 -24
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 1f30e371678c82b2de1219ec842fa298bf1e6acc47b2f210ebfda77939aed190
|
4
|
+
data.tar.gz: 7ac927dc6453bf1532db4e55677cebefa115b17fffc43358ef68b8d80c967210
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: df62e128fdb0a950c7f6eb45ba97bdab7793b6e8b6e4a139dd5fe93913bffee194a5505114dfe421f6d64efb25ad17215eb8f1ecd8fdc1d40969aa2b888bebee
|
7
|
+
data.tar.gz: c05f9262bdbb32fcdcda598c8ae0f16962219f39306ae9d4433b1e13af6e2c2ec181c33864ee99284ebe5f82828940ce3d96a9bb9a4ce00947ab56b7d3699252
|
data/.github/FUNDING.yml
ADDED
@@ -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
data/CHANGELOG.md
CHANGED
@@ -1,8 +1,49 @@
|
|
1
|
-
|
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
|
-
*
|
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
|
-
[![
|
9
|
-
[![
|
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
|
-
|
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
|
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
|
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|
|
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
|
-
|
103
|
-
|
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
|
-
|
144
|
+
cache_file = File.join(tmp_path, 'configure.options_cache')
|
135
145
|
|
136
|
-
|
137
|
-
|
146
|
+
stored_options = File.exist?(cache_file) ? File.read(cache_file) : ""
|
147
|
+
current_options = computed_options.to_s
|
138
148
|
|
139
|
-
(
|
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
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
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
|
-
|
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
|
-
|
339
|
-
|
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
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
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
|
-
|
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
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
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
|
-
|
426
|
-
|
427
|
-
|
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
|
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
|