gem 0.0.1.alpha
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.
- data/LICENSE +20 -0
- data/README.md +75 -0
- data/bin/gem +7 -0
- data/lib/gem.rb +249 -0
- data/lib/gem/configuration.rb +43 -0
- data/lib/gem/dependency.rb +2 -0
- data/lib/gem/platform.rb +76 -0
- data/lib/gem/progressbar.rb +269 -0
- data/lib/gem/requirement.rb +9 -0
- data/lib/gem/source_index.rb +8 -0
- data/lib/gem/specification.rb +202 -0
- data/lib/gem/tar.rb +7 -0
- data/lib/gem/tar/entry.rb +145 -0
- data/lib/gem/tar/header.rb +266 -0
- data/lib/gem/tar/reader.rb +101 -0
- data/lib/gem/tar/writer.rb +240 -0
- data/lib/gem/thread_poolable.rb +59 -0
- data/lib/gem/version.rb +73 -0
- data/lib/gem/version/requirement.rb +1 -0
- data/lib/net/http/faster.rb +27 -0
- data/lib/net/http/persistent.rb +978 -0
- data/lib/net/http/persistent/ssl_reuse.rb +129 -0
- data/lib/rubygems.rb +1 -0
- data/lib/ubygems.rb +1 -0
- metadata +70 -0
@@ -0,0 +1,269 @@
|
|
1
|
+
#
|
2
|
+
# Ruby/ProgressBar - a text progress bar library
|
3
|
+
#
|
4
|
+
# Copyright (C) 2001-2005 Satoru Takabayashi <satoru@namazu.org>
|
5
|
+
# All rights reserved.
|
6
|
+
# This is free software with ABSOLUTELY NO WARRANTY.
|
7
|
+
#
|
8
|
+
# You can redistribute it and/or modify it under the terms
|
9
|
+
# of Ruby's license.
|
10
|
+
#
|
11
|
+
|
12
|
+
class Gem::ProgressBar
|
13
|
+
VERSION = "0.9"
|
14
|
+
|
15
|
+
attr_reader :title, :current, :total
|
16
|
+
attr_accessor :start_time, :synchronized
|
17
|
+
|
18
|
+
def initialize (title, total, out = STDERR)
|
19
|
+
@title = title
|
20
|
+
@total = total
|
21
|
+
@out = out
|
22
|
+
@terminal_width = 80
|
23
|
+
@bar_mark = "="
|
24
|
+
@current = 0
|
25
|
+
@previous = 0
|
26
|
+
@finished_p = false
|
27
|
+
@synchronized = false
|
28
|
+
@start_time = Time.now
|
29
|
+
@previous_time = @start_time
|
30
|
+
@format = "%s %3d%% %s %s"
|
31
|
+
@format_arguments = [:title, :percentage, :bar, :stat]
|
32
|
+
clear
|
33
|
+
show
|
34
|
+
end
|
35
|
+
|
36
|
+
def synchronized= value
|
37
|
+
@synchronized = value.tap do
|
38
|
+
@mutex = (@mutex || Mutex.new if value)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def synchronized!
|
43
|
+
tap { self.synchronized = true }
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
def synchronize &block
|
49
|
+
if synchronized
|
50
|
+
@mutex.synchronize(&block)
|
51
|
+
else
|
52
|
+
block.call
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def self.synchronize *symbols
|
57
|
+
symbols.each do |symbol|
|
58
|
+
symbol_without_synchronize = :"#{symbol}_without_synchronize"
|
59
|
+
alias_method symbol_without_synchronize, symbol
|
60
|
+
define_method symbol do |*args, &block|
|
61
|
+
synchronize do
|
62
|
+
send symbol_without_synchronize, *args, &block
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def fmt_bar
|
69
|
+
bar_width = do_percentage * @terminal_width / 100
|
70
|
+
sprintf("8%sD%s",
|
71
|
+
@bar_mark * bar_width,
|
72
|
+
" " * (@terminal_width - bar_width))
|
73
|
+
end
|
74
|
+
|
75
|
+
def fmt_percentage
|
76
|
+
do_percentage
|
77
|
+
end
|
78
|
+
|
79
|
+
def fmt_stat
|
80
|
+
if @finished_p then elapsed else eta end
|
81
|
+
end
|
82
|
+
|
83
|
+
def fmt_stat_for_file_transfer
|
84
|
+
if @finished_p then
|
85
|
+
sprintf("%s %s %s", bytes, transfer_rate, elapsed)
|
86
|
+
else
|
87
|
+
sprintf("%s %s %s", bytes, transfer_rate, eta)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def fmt_title
|
92
|
+
@title + "..."
|
93
|
+
end
|
94
|
+
|
95
|
+
def convert_bytes (bytes)
|
96
|
+
if bytes < 1024
|
97
|
+
sprintf("%6dB", bytes)
|
98
|
+
elsif bytes < 1024 * 1000 # 1000kb
|
99
|
+
sprintf("%5.1fKB", bytes.to_f / 1024)
|
100
|
+
elsif bytes < 1024 * 1024 * 1000 # 1000mb
|
101
|
+
sprintf("%5.1fMB", bytes.to_f / 1024 / 1024)
|
102
|
+
else
|
103
|
+
sprintf("%5.1fGB", bytes.to_f / 1024 / 1024 / 1024)
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
def transfer_rate
|
108
|
+
bytes_per_second = @current.to_f / (Time.now - @start_time)
|
109
|
+
sprintf("%s/s", convert_bytes(bytes_per_second))
|
110
|
+
end
|
111
|
+
|
112
|
+
def bytes
|
113
|
+
convert_bytes(@current)
|
114
|
+
end
|
115
|
+
|
116
|
+
def format_time (t)
|
117
|
+
t = t.to_i
|
118
|
+
sec = t % 60
|
119
|
+
min = (t / 60) % 60
|
120
|
+
hour = t / 3600
|
121
|
+
sprintf("%02d:%02d:%02d", hour, min, sec);
|
122
|
+
end
|
123
|
+
|
124
|
+
# ETA stands for Estimated Time of Arrival.
|
125
|
+
def eta
|
126
|
+
if @current == 0
|
127
|
+
"ETA: --:--:--"
|
128
|
+
else
|
129
|
+
elapsed = Time.now - @start_time
|
130
|
+
eta = elapsed * @total / @current - elapsed;
|
131
|
+
sprintf("ETA: %s (%d/%d)", format_time(eta), @current, @total)
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
def elapsed
|
136
|
+
elapsed = Time.now - @start_time
|
137
|
+
sprintf("Time: %s", format_time(elapsed))
|
138
|
+
end
|
139
|
+
|
140
|
+
def eol
|
141
|
+
if @finished_p then "\n" else "\r" end
|
142
|
+
end
|
143
|
+
|
144
|
+
def do_percentage
|
145
|
+
if @total.zero?
|
146
|
+
100
|
147
|
+
else
|
148
|
+
@current * 100 / @total
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
def get_width
|
153
|
+
# FIXME: I don't know how portable it is.
|
154
|
+
default_width = 80
|
155
|
+
begin
|
156
|
+
tiocgwinsz = 0x5413
|
157
|
+
data = [0, 0, 0, 0].pack("SSSS")
|
158
|
+
if @out.ioctl(tiocgwinsz, data) >= 0 then
|
159
|
+
rows, cols, xpixels, ypixels = data.unpack("SSSS")
|
160
|
+
if cols >= 0 then cols else default_width end
|
161
|
+
else
|
162
|
+
default_width
|
163
|
+
end
|
164
|
+
rescue Exception
|
165
|
+
default_width
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
def show
|
170
|
+
arguments = @format_arguments.map {|method|
|
171
|
+
method = sprintf("fmt_%s", method)
|
172
|
+
send(method)
|
173
|
+
}
|
174
|
+
line = sprintf(@format, *arguments)
|
175
|
+
|
176
|
+
width = get_width
|
177
|
+
if line.length == width - 1
|
178
|
+
@out.print(line + eol)
|
179
|
+
@out.flush
|
180
|
+
elsif line.length >= width
|
181
|
+
@terminal_width = [@terminal_width - (line.length - width + 1), 0].max
|
182
|
+
if @terminal_width == 0 then @out.print(line + eol) else show end
|
183
|
+
else # line.length < width - 1
|
184
|
+
@terminal_width += width - line.length + 1
|
185
|
+
show
|
186
|
+
end
|
187
|
+
@previous_time = Time.now
|
188
|
+
end
|
189
|
+
synchronize :show
|
190
|
+
|
191
|
+
def show_if_needed
|
192
|
+
if @total.zero?
|
193
|
+
cur_percentage = 100
|
194
|
+
prev_percentage = 0
|
195
|
+
else
|
196
|
+
cur_percentage = (@current * 100 / @total).to_i
|
197
|
+
prev_percentage = (@previous * 100 / @total).to_i
|
198
|
+
end
|
199
|
+
|
200
|
+
# Use "!=" instead of ">" to support negative changes
|
201
|
+
if cur_percentage != prev_percentage ||
|
202
|
+
Time.now - @previous_time >= 1 || @finished_p
|
203
|
+
show
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
public
|
208
|
+
def clear
|
209
|
+
@out.print "\r"
|
210
|
+
@out.print(" " * (get_width - 1))
|
211
|
+
@out.print "\r"
|
212
|
+
end
|
213
|
+
synchronize :clear
|
214
|
+
|
215
|
+
# puts making sure the progressbar doesn't get in the way
|
216
|
+
def puts *args
|
217
|
+
clear
|
218
|
+
@out.puts *args
|
219
|
+
show
|
220
|
+
end
|
221
|
+
synchronize :puts
|
222
|
+
|
223
|
+
def finish
|
224
|
+
@current = @total
|
225
|
+
@finished_p = true
|
226
|
+
show
|
227
|
+
end
|
228
|
+
|
229
|
+
def finished?
|
230
|
+
@finished_p
|
231
|
+
end
|
232
|
+
|
233
|
+
def file_transfer_mode
|
234
|
+
@format_arguments = [:title, :percentage, :bar, :stat_for_file_transfer]
|
235
|
+
end
|
236
|
+
|
237
|
+
def format= (format)
|
238
|
+
@format = format
|
239
|
+
end
|
240
|
+
|
241
|
+
def format_arguments= (arguments)
|
242
|
+
@format_arguments = arguments
|
243
|
+
end
|
244
|
+
|
245
|
+
def halt
|
246
|
+
@finished_p = true
|
247
|
+
show
|
248
|
+
end
|
249
|
+
|
250
|
+
def inc (step = 1)
|
251
|
+
@current += step
|
252
|
+
@current = @total if @current > @total
|
253
|
+
show_if_needed
|
254
|
+
@previous = @current
|
255
|
+
end
|
256
|
+
|
257
|
+
def set (count)
|
258
|
+
if count < 0 || count > @total
|
259
|
+
raise "invalid count: #{count} (total: #{@total})"
|
260
|
+
end
|
261
|
+
@current = count
|
262
|
+
show_if_needed
|
263
|
+
@previous = @current
|
264
|
+
end
|
265
|
+
|
266
|
+
def inspect
|
267
|
+
"#<ProgressBar:#{@current}/#{@total}>"
|
268
|
+
end
|
269
|
+
end
|
@@ -0,0 +1,202 @@
|
|
1
|
+
class Gem::Specification
|
2
|
+
include Comparable
|
3
|
+
|
4
|
+
# We override some of these later
|
5
|
+
attr_accessor :authors, :autorequire, :bindir, :date, :default_executable, :dependencies,
|
6
|
+
:description, :email, :executables, :extensions, :extra_rdoc_files, :files, :has_rdoc,
|
7
|
+
:homepage, :licenses, :name, :platform, :rdoc_options, :require_paths,
|
8
|
+
:required_ruby_version, :required_rubygems_version, :requirements, :rubyforge_project,
|
9
|
+
:rubygems_version, :specification_version, :summary, :test_files, :version
|
10
|
+
|
11
|
+
def self.from_gem path
|
12
|
+
Gem::Tar::Reader.new(File.open(path, 'r')).each do |entry|
|
13
|
+
if entry.full_name == "metadata.gz" or entry.full_name == "metadata"
|
14
|
+
entry = Zlib::GzipReader.new entry if entry.full_name =~ /\.gz\Z/
|
15
|
+
return YAML.load_stream entry
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.try_from_gem path
|
21
|
+
begin
|
22
|
+
from_gem path
|
23
|
+
# XXX: YAML throws `SyntaxError`s (eek!)
|
24
|
+
rescue Exception
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
@@capture = false
|
29
|
+
|
30
|
+
def self.from_gemspec path
|
31
|
+
@@capture = true
|
32
|
+
load path
|
33
|
+
@@capture
|
34
|
+
end
|
35
|
+
|
36
|
+
def initialize *args
|
37
|
+
options = args.pop if args.last.is_a? Hash
|
38
|
+
options ||= {}
|
39
|
+
|
40
|
+
self.name = args.shift
|
41
|
+
self.version = args.shift
|
42
|
+
self.platform = args.shift
|
43
|
+
|
44
|
+
raise ArgumentError, "Too many arguments" unless args.empty?
|
45
|
+
|
46
|
+
options.each do |key, value|
|
47
|
+
send "#{key}=", value
|
48
|
+
end
|
49
|
+
|
50
|
+
yield self if block_given?
|
51
|
+
|
52
|
+
@@capture = self if @@capture == true
|
53
|
+
end
|
54
|
+
|
55
|
+
def name= value
|
56
|
+
@basename = nil
|
57
|
+
@name = value
|
58
|
+
end
|
59
|
+
|
60
|
+
def version
|
61
|
+
@version
|
62
|
+
end
|
63
|
+
|
64
|
+
def version= value
|
65
|
+
value = Gem::Version.new value unless value.nil? or not value.is_a? Gem::Version
|
66
|
+
@basename = nil
|
67
|
+
@version = value
|
68
|
+
end
|
69
|
+
|
70
|
+
def prerelease?
|
71
|
+
version.is_a? Version and version.prerelease?
|
72
|
+
end
|
73
|
+
|
74
|
+
def platform
|
75
|
+
@platform.to_s == "ruby" ? nil : @platform
|
76
|
+
end
|
77
|
+
|
78
|
+
def platform= value
|
79
|
+
@basename = nil
|
80
|
+
@platform = value
|
81
|
+
end
|
82
|
+
|
83
|
+
def basename
|
84
|
+
@basename ||= [name, version, platform].map(&:to_s).reject(&:empty?).compact.join('-')
|
85
|
+
end
|
86
|
+
|
87
|
+
def authors
|
88
|
+
@authors ||= []
|
89
|
+
end
|
90
|
+
|
91
|
+
def author
|
92
|
+
authors.first
|
93
|
+
end
|
94
|
+
|
95
|
+
def author= value
|
96
|
+
self.authors = [value]
|
97
|
+
end
|
98
|
+
|
99
|
+
def licenses
|
100
|
+
@licenses ||= []
|
101
|
+
end
|
102
|
+
|
103
|
+
def license
|
104
|
+
licenses.first
|
105
|
+
end
|
106
|
+
|
107
|
+
def license= value
|
108
|
+
licenses[0] = value
|
109
|
+
end
|
110
|
+
|
111
|
+
def date
|
112
|
+
@date ||= Time.utc(today.year, today.month, today.day)
|
113
|
+
end
|
114
|
+
|
115
|
+
def rubygems_version
|
116
|
+
@rubygems_version ||= Gem::VERSION
|
117
|
+
end
|
118
|
+
|
119
|
+
def dependencies
|
120
|
+
@dependencies ||= []
|
121
|
+
end
|
122
|
+
|
123
|
+
def add_runtime_dependency *dependency
|
124
|
+
self.dependencies << dependency
|
125
|
+
end
|
126
|
+
|
127
|
+
alias add_dependency add_runtime_dependency
|
128
|
+
|
129
|
+
def add_development_dependency *dependency
|
130
|
+
self.dependencies << dependency
|
131
|
+
end
|
132
|
+
|
133
|
+
def specification_version
|
134
|
+
3
|
135
|
+
end
|
136
|
+
|
137
|
+
def <=> other
|
138
|
+
[name.to_s, version, platform == "ruby" ? -1 : 1] <=> [other.name.to_s, other.version, other.platform == "ruby" ? -1 : 1]
|
139
|
+
end
|
140
|
+
|
141
|
+
def _dump limit=-1
|
142
|
+
Marshal.dump [
|
143
|
+
# This order is important
|
144
|
+
rubygems_version,
|
145
|
+
specification_version,
|
146
|
+
name,
|
147
|
+
version,
|
148
|
+
date,
|
149
|
+
summary,
|
150
|
+
required_ruby_version,
|
151
|
+
required_rubygems_version,
|
152
|
+
platform,
|
153
|
+
dependencies,
|
154
|
+
rubyforge_project,
|
155
|
+
email,
|
156
|
+
authors,
|
157
|
+
description,
|
158
|
+
homepage,
|
159
|
+
has_rdoc,
|
160
|
+
platform,
|
161
|
+
licenses
|
162
|
+
]
|
163
|
+
end
|
164
|
+
|
165
|
+
def self._load data
|
166
|
+
marshalled = Marshal.load data
|
167
|
+
|
168
|
+
new.tap do |spec|
|
169
|
+
# This order is important
|
170
|
+
spec.rubygems_version,
|
171
|
+
spec.specification_version,
|
172
|
+
spec.name,
|
173
|
+
spec.version,
|
174
|
+
spec.date,
|
175
|
+
spec.summary,
|
176
|
+
spec.required_ruby_version,
|
177
|
+
spec.required_rubygems_version,
|
178
|
+
spec.platform,
|
179
|
+
spec.dependencies,
|
180
|
+
spec.rubyforge_project,
|
181
|
+
spec.email,
|
182
|
+
spec.authors,
|
183
|
+
spec.description,
|
184
|
+
spec.homepage,
|
185
|
+
spec.has_rdoc,
|
186
|
+
spec.platform,
|
187
|
+
spec.licenses = marshalled
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
191
|
+
def for_cache
|
192
|
+
dup.for_cache!
|
193
|
+
end
|
194
|
+
|
195
|
+
def for_cache!
|
196
|
+
tap do
|
197
|
+
@files = nil
|
198
|
+
@test_files = nil
|
199
|
+
end
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|