ruby-nuggets 0.9.1 → 0.9.2

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.
@@ -0,0 +1,348 @@
1
+ #--
2
+ ###############################################################################
3
+ # #
4
+ # A component of ruby-nuggets, some extensions to the Ruby programming #
5
+ # language. #
6
+ # #
7
+ # Copyright (C) 2007-2011 Jens Wille #
8
+ # #
9
+ # Authors: #
10
+ # Jens Wille <jens.wille@gmail.com> #
11
+ # #
12
+ # ruby-nuggets is free software; you can redistribute it and/or modify it #
13
+ # under the terms of the GNU Affero General Public License as published by #
14
+ # the Free Software Foundation; either version 3 of the License, or (at your #
15
+ # option) any later version. #
16
+ # #
17
+ # ruby-nuggets is distributed in the hope that it will be useful, but WITHOUT #
18
+ # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
19
+ # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License #
20
+ # for more details. #
21
+ # #
22
+ # You should have received a copy of the GNU Affero General Public License #
23
+ # along with ruby-nuggets. If not, see <http://www.gnu.org/licenses/>. #
24
+ # #
25
+ ###############################################################################
26
+ #++
27
+
28
+ require 'rbconfig'
29
+
30
+ module Nuggets
31
+
32
+ # Heavily based on Phusion Passenger's PlatformInfo module; see
33
+ # {their code}[https://github.com/FooBarWidget/passenger/blob/release-3.0.2/lib/phusion_passenger/platform_info/ruby.rb].
34
+ #
35
+ #--
36
+ # Phusion Passenger - http://www.modrails.com/
37
+ # Copyright (c) 2010 Phusion
38
+ #
39
+ # "Phusion Passenger" is a trademark of Hongli Lai & Ninh Bui.
40
+ #
41
+ # Permission is hereby granted, free of charge, to any person obtaining a
42
+ # copy of this software and associated documentation files (the "Software"),
43
+ # to deal in the Software without restriction, including without limitation
44
+ # the rights to use, copy, modify, merge, publish, distribute, sublicense,
45
+ # and/or sell copies of the Software, and to permit persons to whom the
46
+ # Software is furnished to do so, subject to the following conditions:
47
+ #
48
+ # The above copyright notice and this permission notice shall be included in
49
+ # all copies or substantial portions of the Software.
50
+ #++
51
+
52
+ module Ruby
53
+
54
+ extend self
55
+
56
+ CONFIG = ::RbConfig::CONFIG
57
+
58
+ # Store original $GEM_HOME value so that even if the app customizes
59
+ # $GEM_HOME we can still work with the original value.
60
+ if gem_home = ::ENV['GEM_HOME']
61
+ gem_home = gem_home.strip.freeze
62
+ gem_home = nil if gem_home.empty?
63
+ end
64
+
65
+ GEM_HOME = gem_home
66
+
67
+ RUBY_ENGINE = defined?(::RUBY_ENGINE) ? ::RUBY_ENGINE : 'ruby'
68
+
69
+ OSX_RUBY_RE = %r{\A/System/Library/Frameworks/Ruby.framework/Versions/.*?/usr/bin/ruby\Z}
70
+
71
+ UPDATE_RVM = %q{Please update RVM by running 'rvm update --head && rvm reload && rvm repair all'.} # :nodoc:
72
+
73
+ # Returns correct command for invoking the current Ruby interpreter.
74
+ # In case of RVM this function will return the path to the RVM wrapper script
75
+ # that executes the current Ruby interpreter in the currently active gem set.
76
+ def ruby_command
77
+ return @ruby_command if defined?(@ruby_command)
78
+
79
+ return @ruby_command = ruby_executable unless rvm?
80
+
81
+ if name = rvm_ruby_string and dir = rvm_path
82
+ if ::File.exist?(filename = ::File.join(dir, 'wrappers', name, 'ruby'))
83
+ # Old wrapper scripts reference $HOME which causes
84
+ # things to blow up when run by a different user.
85
+ return @ruby_command = filename unless ::File.read(filename).include?('$HOME')
86
+ end
87
+
88
+ abort 'Your RVM wrapper scripts are too old. ' << UPDATE_RVM
89
+ end
90
+
91
+ # Something's wrong with the user's RVM installation.
92
+ # Raise an error so that the user knows this instead of
93
+ # having things fail randomly later on.
94
+ # 'name' is guaranteed to be non-nil because rvm_ruby_string
95
+ # already raises an exception on error.
96
+ abort 'Your RVM installation appears to be broken: the RVM path cannot be found. ' <<
97
+ 'Please fix your RVM installation or contact the RVM developers for support.'
98
+ end
99
+
100
+ attr_writer :ruby_command
101
+
102
+ # Returns the full path to the current Ruby interpreter's executable file.
103
+ # This might not be the actual correct command to use for invoking the Ruby
104
+ # interpreter; use ruby_command instead.
105
+ def ruby_executable
106
+ @ruby_executable ||= begin
107
+ dir, name, ext = CONFIG.values_at(*%w[bindir RUBY_INSTALL_NAME EXEEXT])
108
+ ::File.join(dir, name + ext).sub(/.*\s.*/m, '"\&"')
109
+ end
110
+ end
111
+
112
+ attr_writer :ruby_executable
113
+
114
+ # Returns whether the Ruby interpreter supports process forking.
115
+ def ruby_supports_fork?
116
+ # MRI >= 1.9.2's respond_to? returns false
117
+ # for methods that are not implemented.
118
+ ::Process.respond_to?(:fork) &&
119
+ RUBY_ENGINE != 'jruby' &&
120
+ RUBY_ENGINE != 'macruby' &&
121
+ CONFIG['target_os'] !~ /mswin|windows|mingw/
122
+ end
123
+
124
+ # Returns whether the current Ruby interpreter is managed by RVM.
125
+ def rvm?
126
+ CONFIG['bindir'] =~ %r{/\.?rvm/}
127
+ end
128
+
129
+ # If the current Ruby interpreter is managed by RVM, returns the
130
+ # directory in which RVM places its working files. Otherwise returns
131
+ # +nil+.
132
+ def rvm_path
133
+ return @rvm_path if defined?(@rvm_path)
134
+
135
+ return @rvm_path = nil unless rvm?
136
+
137
+ [::ENV['rvm_path'], '~/.rvm', '/usr/local/rvm'].compact.each { |path|
138
+ path = ::File.expand_path(path)
139
+ return @rvm_path = path if ::File.directory?(path)
140
+ }
141
+
142
+ # Failure to locate the RVM path is probably caused by the
143
+ # user customizing $rvm_path. Older RVM versions don't
144
+ # export $rvm_path, making us unable to detect its value.
145
+ abort 'Unable to locate the RVM path. Your RVM ' <<
146
+ 'installation is probably too old. ' << UPDATE_RVM
147
+ end
148
+
149
+ attr_writer :rvm_path
150
+
151
+ # If the current Ruby interpreter is managed by RVM, returns the
152
+ # RVM name which identifies the current Ruby interpreter plus the
153
+ # currently active gemset, e.g. something like this:
154
+ # "ruby-1.9.2-p0@mygemset"
155
+ #
156
+ # Returns +nil+ otherwise.
157
+ def rvm_ruby_string
158
+ return @rvm_ruby_string if defined?(@rvm_ruby_string)
159
+
160
+ return @rvm_ruby_string = nil unless rvm?
161
+
162
+ # RVM used to export the necessary information through
163
+ # environment variables, but doesn't always do that anymore
164
+ # in the latest versions in order to fight env var pollution.
165
+ # Scanning $LOAD_PATH seems to be the only way to obtain
166
+ # the information.
167
+
168
+ # Getting the RVM name of the Ruby interpreter ("ruby-1.9.2")
169
+ # isn't so hard, we can extract it from the #ruby_executable
170
+ # string. Getting the gemset name is a bit harder, so let's
171
+ # try various strategies...
172
+
173
+ # $GEM_HOME usually contains the gem set name.
174
+ return @rvm_ruby_string = ::File.basename(GEM_HOME) if GEM_HOME && GEM_HOME.include?('rvm/gems/')
175
+
176
+ # User somehow managed to nuke $GEM_HOME. Extract info from $LOAD_PATH.
177
+ $LOAD_PATH.each { |path| return @rvm_ruby_string = $1 if path =~ %r{^.*rvm/gems/([^/]+)} }
178
+
179
+ # On Ruby 1.9, $LOAD_PATH does not contain any gem paths until
180
+ # at least one gem has been required so the above can fail.
181
+ # We're out of options now, we can't detect the gem set.
182
+ # Raise an exception so that the user knows what's going on
183
+ # instead of having things fail in obscure ways later.
184
+ abort 'Unable to autodetect the currently active RVM gem set ' <<
185
+ "name. Please contact this program's author for support."
186
+ end
187
+
188
+ attr_writer :rvm_ruby_string
189
+
190
+ # Returns either 'sudo' or 'rvmsudo' depending on whether the current
191
+ # Ruby interpreter is managed by RVM.
192
+ def ruby_sudo_command
193
+ "#{'rvm' if rvm?}sudo"
194
+ end
195
+
196
+ # Locates a Ruby tool command +name+, e.g. 'gem', 'rake', 'bundle', etc. Instead
197
+ # of naively looking in $PATH, this function uses a variety of search heuristics
198
+ # to find the command that's really associated with the current Ruby interpreter.
199
+ # It should never locate a command that's actually associated with a different
200
+ # Ruby interpreter.
201
+ #
202
+ # NOTE: The return value may not be the actual correct invocation for the tool.
203
+ # Use command_for_ruby_tool for that.
204
+ #
205
+ # Returns +nil+ when nothing's found.
206
+ def locate_ruby_tool(name)
207
+ extensions = ['', CONFIG['EXEEXT']].compact.uniq
208
+
209
+ # Deduce Ruby's --program-prefix and --program-suffix from its install name
210
+ # and transform the given input name accordingly.
211
+ #
212
+ # "rake" => "jrake", "rake1.8", etc
213
+ [name, CONFIG['RUBY_INSTALL_NAME'].sub('ruby', name)].uniq.each { |basename|
214
+ extensions.each { |ext|
215
+ result = locate_ruby_tool_by_basename("#{basename}#{ext}")
216
+ return result if result
217
+ }
218
+ }
219
+
220
+ nil
221
+ end
222
+
223
+ # Returns the correct command string for invoking the +name+ executable
224
+ # that belongs to the current Ruby interpreter. Returns +nil+ if the
225
+ # command is not found.
226
+ #
227
+ # If the command executable is a Ruby program, then we need to run it
228
+ # in the correct Ruby interpreter just in case the command doesn't
229
+ # have the correct shebang line; we don't want a totally different
230
+ # Ruby than the current one to be invoked.
231
+ #
232
+ # If it's not a Ruby program then it's probably a wrapper
233
+ # script as is the case with e.g. RVM (~/.rvm/wrappers).
234
+ def command_for_ruby_tool(name)
235
+ filename = respond_to?(name) ? send(name) : locate_ruby_tool(name)
236
+ shebang_command(filename) =~ /ruby/ ? "#{ruby_command} #{filename}" : filename
237
+ end
238
+
239
+ %w[gem rake rspec].each { |name|
240
+ class_eval <<-EOT, __FILE__, __LINE__ + 1
241
+ def #{name}
242
+ @#{name} ||= locate_ruby_tool('#{name}')
243
+ end
244
+
245
+ attr_writer :#{name}
246
+
247
+ def #{name}_command
248
+ @#{name}_command ||= command_for_ruby_tool('#{name}')
249
+ end
250
+
251
+ attr_writer :#{name}_command
252
+ EOT
253
+ }
254
+
255
+ def ruby_options_to_argv(args, ruby_command = ruby_command)
256
+ argv = [ruby_command]
257
+
258
+ args.pop.each { |key, val|
259
+ opt = "-#{key.to_s[0, 1]}"
260
+
261
+ if val.is_a?(::Array)
262
+ val.each { |wal|
263
+ argv << opt << wal.to_s
264
+ }
265
+ else
266
+ if opt == '-e'
267
+ argv << opt << val.to_s
268
+ elsif val != false
269
+ argv << "#{opt}#{val unless val == true}"
270
+ end
271
+ end
272
+ } if args.last.is_a?(::Hash)
273
+
274
+ argv.concat(args.map! { |arg| arg.to_s.strip })
275
+ end
276
+
277
+ private
278
+
279
+ def locate_ruby_tool_by_basename(name)
280
+ dir = if ::RUBY_PLATFORM =~ /darwin/ && ruby_command =~ OSX_RUBY_RE
281
+ # On OS X we must look for Ruby binaries in /usr/bin.
282
+ # RubyGems puts executables (e.g. 'rake') in there, not in
283
+ # /System/Libraries/(...)/bin.
284
+ '/usr/bin'
285
+ else
286
+ ::File.dirname(ruby_command)
287
+ end
288
+
289
+ filename = ::File.join(dir, name)
290
+ return filename if ::File.file?(filename) && ::File.executable?(filename)
291
+
292
+ # RubyGems might put binaries in a directory other
293
+ # than Ruby's bindir. Debian packaged RubyGems and
294
+ # DebGem packaged RubyGems are the prime examples.
295
+ begin
296
+ require 'rubygems' unless defined?(::Gem)
297
+
298
+ filename = ::File.join(::Gem.bindir, name)
299
+ return filename if ::File.file?(filename) && ::File.executable?(filename)
300
+ rescue ::LoadError
301
+ end
302
+
303
+ # Looks like it's not in the RubyGems bindir. Search in $PATH, but
304
+ # be very careful about this because whatever we find might belong
305
+ # to a different Ruby interpreter than the current one.
306
+ ::ENV['PATH'].split(::File::PATH_SEPARATOR).each { |path|
307
+ filename = ::File.join(path, name)
308
+
309
+ if ::File.file?(filename) && ::File.executable?(filename)
310
+ return filename if shebang_command(filename) == ruby_command
311
+ end
312
+ }
313
+
314
+ nil
315
+ end
316
+
317
+ def shebang_command(filename)
318
+ ::File.foreach(filename) { |line|
319
+ return $1 if line =~ /\A#!\s*(\S*)/
320
+
321
+ # Allow one extra line for magic comment.
322
+ break if $. > 1
323
+ }
324
+ end
325
+
326
+ end
327
+
328
+ end
329
+
330
+ def File.ruby; ::Nuggets::Ruby.ruby_command; end
331
+
332
+ begin
333
+ require 'open4'
334
+
335
+ def Process.ruby(*args)
336
+ argv = ::Nuggets::Ruby.ruby_options_to_argv(args)
337
+ ::Open4.popen4(*argv, &block_given? ? ::Proc.new : nil)
338
+ end
339
+
340
+ require 'nuggets/io/interact'
341
+
342
+ def Process.interact_ruby(input, *args)
343
+ ruby(*args) { |_, i, o, e|
344
+ ::IO.interact({ input => i }, { o => $stdout, e => $stderr })
345
+ }
346
+ end
347
+ rescue ::LoadError
348
+ end
@@ -1,127 +1,4 @@
1
- #--
2
- ###############################################################################
3
- # #
4
- # A component of ruby-nuggets, some extensions to the Ruby programming #
5
- # language. #
6
- # #
7
- # Copyright (C) 2007-2011 Jens Wille #
8
- # #
9
- # Authors: #
10
- # Jens Wille <jens.wille@gmail.com> #
11
- # #
12
- # ruby-nuggets is free software; you can redistribute it and/or modify it #
13
- # under the terms of the GNU Affero General Public License as published by #
14
- # the Free Software Foundation; either version 3 of the License, or (at your #
15
- # option) any later version. #
16
- # #
17
- # ruby-nuggets is distributed in the hope that it will be useful, but WITHOUT #
18
- # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
19
- # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License #
20
- # for more details. #
21
- # #
22
- # You should have received a copy of the GNU Affero General Public License #
23
- # along with ruby-nuggets. If not, see <http://www.gnu.org/licenses/>. #
24
- # #
25
- ###############################################################################
26
- #++
1
+ require 'nuggets/ansicolor2css'
2
+ module Util; ANSIColor2CSS = ::Nuggets::ANSIColor2CSS; end
27
3
 
28
- module Util
29
-
30
- module ANSIColor2CSS
31
-
32
- extend self
33
-
34
- ATTRIBUTES = {
35
- '0' => nil, # clear
36
- '1' => 'font-weight: bold', # bold
37
- '2' => '', # dark
38
- '3' => 'font-style: italic', # italic -- not widely implemented
39
- '4' => 'text-decoration: underline', # underline
40
- '5' => 'text-decoration: blink', # blink
41
- '6' => 'text-decoration: blink', # rapid blink -- not widely implemented
42
- '7' => '', # reverse
43
- '8' => 'opacity: 0', # concealed
44
- '9' => 'text-decoration: line-through', # strikethrough -- not widely implemented
45
- '22' => 'font-weight: normal', # bold off
46
- '23' => 'font-style: normal', # italic off
47
- '24' => 'text-decoration: none', # underline off
48
- '25' => 'text-decoration: none', # blink off
49
- '27' => '', # reverse off
50
- '28' => 'opacity: 1', # concealed off
51
- '29' => 'text-decoration: none', # strikethrough off
52
- '30' => 'color: black', # black
53
- '31' => 'color: maroon', # red
54
- '32' => 'color: green', # green
55
- '33' => 'color: olive', # yellow
56
- '34' => 'color: navy', # blue
57
- '35' => 'color: purple', # magenta
58
- '36' => 'color: teal', # cyan
59
- '37' => 'color: silver', # white
60
- '39' => 'color: silver', # default (white)
61
- '40' => 'background-color: black', # on black
62
- '41' => 'background-color: maroon', # on red
63
- '42' => 'background-color: green', # on green
64
- '43' => 'background-color: olive', # on yellow
65
- '44' => 'background-color: navy', # on blue
66
- '45' => 'background-color: purple', # on magenta
67
- '46' => 'background-color: teal', # on cyan
68
- '47' => 'background-color: silver', # on white
69
- '49' => 'background-color: black', # on default (black)
70
- '90' => 'color: gray', # bright black
71
- '91' => 'color: red', # bright red
72
- '92' => 'color: lime', # bright green
73
- '93' => 'color: yellow', # bright yellow
74
- '94' => 'color: blue', # bright blue
75
- '95' => 'color: fuchsia', # bright magenta
76
- '96' => 'color: cyan', # bright cyan
77
- '97' => 'color: white', # bright white
78
- '100' => 'background-color: gray', # on bright black
79
- '101' => 'background-color: red', # on bright red
80
- '102' => 'background-color: lime', # on bright green
81
- '103' => 'background-color: yellow', # on bright yellow
82
- '104' => 'background-color: blue', # on bright blue
83
- '105' => 'background-color: fuchsia', # on bright magenta
84
- '106' => 'background-color: cyan', # on bright cyan
85
- '107' => 'background-color: white' # on bright white
86
- }
87
-
88
- ATTRIBUTES_RE = ::Regexp.union(*ATTRIBUTES.keys)
89
-
90
- DELIMITER = ';'
91
-
92
- COLOR_RE = %r{
93
- \e \[ ( #{ATTRIBUTES_RE} (?: #{DELIMITER} #{ATTRIBUTES_RE} )* ) m
94
- }x
95
-
96
- STYLE = '<span style="%s">'
97
- CLEAR = '</span>'
98
-
99
- def convert(string)
100
- string.gsub(COLOR_RE) { format($1.split(DELIMITER).uniq) }
101
- end
102
-
103
- def format(attributes)
104
- "#{clear(attributes)}#{style(attributes) if attributes.any?}"
105
- end
106
-
107
- def clear(attributes)
108
- CLEAR if attributes.delete('0')
109
- end
110
-
111
- def style(attributes)
112
- STYLE % ATTRIBUTES.values_at(*attributes).join('; ')
113
- end
114
-
115
- end
116
-
117
- end
118
-
119
- class String
120
-
121
- def ansicolor2css
122
- ::Util::ANSIColor2CSS.convert(self)
123
- end
124
-
125
- alias_method :ansicolour2css, :ansicolor2css
126
-
127
- end
4
+ warn "#{__FILE__}: Util::ANSIColor2CSS is deprecated, use Nuggets::ANSIColor2CSS instead."