bundler 0.8.1 → 0.9.0.pre1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of bundler might be problematic. Click here for more details.

Files changed (58) hide show
  1. data/README +7 -0
  2. data/bin/bundle +3 -0
  3. data/lib/bundler.rb +72 -37
  4. data/lib/bundler/cli.rb +64 -68
  5. data/lib/bundler/definition.rb +78 -0
  6. data/lib/bundler/dependency.rb +7 -57
  7. data/lib/bundler/dsl.rb +42 -142
  8. data/lib/bundler/environment.rb +94 -54
  9. data/lib/bundler/index.rb +98 -0
  10. data/lib/bundler/installer.rb +137 -0
  11. data/lib/bundler/remote_specification.rb +1 -1
  12. data/lib/bundler/resolver.rb +20 -50
  13. data/lib/bundler/rubygems.rb +22 -0
  14. data/lib/bundler/source.rb +185 -295
  15. data/lib/bundler/specification.rb +22 -0
  16. data/lib/bundler/templates/Gemfile +4 -0
  17. data/lib/bundler/templates/environment.erb +3 -153
  18. data/lib/bundler/ui.rb +51 -0
  19. data/lib/bundler/vendor/thor.rb +241 -0
  20. data/lib/bundler/vendor/thor/actions.rb +274 -0
  21. data/lib/bundler/vendor/thor/actions/create_file.rb +103 -0
  22. data/lib/bundler/vendor/thor/actions/directory.rb +91 -0
  23. data/lib/bundler/vendor/thor/actions/empty_directory.rb +134 -0
  24. data/lib/bundler/vendor/thor/actions/file_manipulation.rb +223 -0
  25. data/lib/bundler/vendor/thor/actions/inject_into_file.rb +101 -0
  26. data/lib/bundler/vendor/thor/base.rb +515 -0
  27. data/lib/bundler/vendor/thor/core_ext/file_binary_read.rb +9 -0
  28. data/lib/bundler/vendor/thor/core_ext/hash_with_indifferent_access.rb +75 -0
  29. data/lib/bundler/vendor/thor/core_ext/ordered_hash.rb +100 -0
  30. data/lib/bundler/vendor/thor/error.rb +27 -0
  31. data/lib/bundler/vendor/thor/group.rb +267 -0
  32. data/lib/bundler/vendor/thor/invocation.rb +178 -0
  33. data/lib/bundler/vendor/thor/parser.rb +4 -0
  34. data/lib/bundler/vendor/thor/parser/argument.rb +67 -0
  35. data/lib/bundler/vendor/thor/parser/arguments.rb +145 -0
  36. data/lib/bundler/vendor/thor/parser/option.rb +132 -0
  37. data/lib/bundler/vendor/thor/parser/options.rb +142 -0
  38. data/lib/bundler/vendor/thor/rake_compat.rb +66 -0
  39. data/lib/bundler/vendor/thor/runner.rb +303 -0
  40. data/lib/bundler/vendor/thor/shell.rb +78 -0
  41. data/lib/bundler/vendor/thor/shell/basic.rb +239 -0
  42. data/lib/bundler/vendor/thor/shell/color.rb +108 -0
  43. data/lib/bundler/vendor/thor/task.rb +111 -0
  44. data/lib/bundler/vendor/thor/util.rb +233 -0
  45. data/lib/bundler/vendor/thor/version.rb +3 -0
  46. metadata +48 -26
  47. data/README.markdown +0 -284
  48. data/Rakefile +0 -81
  49. data/lib/bundler/bundle.rb +0 -314
  50. data/lib/bundler/commands/bundle_command.rb +0 -72
  51. data/lib/bundler/commands/exec_command.rb +0 -36
  52. data/lib/bundler/finder.rb +0 -51
  53. data/lib/bundler/gem_bundle.rb +0 -11
  54. data/lib/bundler/gem_ext.rb +0 -34
  55. data/lib/bundler/runtime.rb +0 -2
  56. data/lib/bundler/templates/app_script.erb +0 -3
  57. data/lib/bundler/templates/environment_picker.erb +0 -4
  58. data/lib/rubygems_plugin.rb +0 -6
@@ -0,0 +1,9 @@
1
+ class File #:nodoc:
2
+
3
+ unless File.respond_to?(:binread)
4
+ def self.binread(file)
5
+ File.open(file, 'rb') { |f| f.read }
6
+ end
7
+ end
8
+
9
+ end
@@ -0,0 +1,75 @@
1
+ class Thor
2
+ module CoreExt #:nodoc:
3
+
4
+ # A hash with indifferent access and magic predicates.
5
+ #
6
+ # hash = Thor::CoreExt::HashWithIndifferentAccess.new 'foo' => 'bar', 'baz' => 'bee', 'force' => true
7
+ #
8
+ # hash[:foo] #=> 'bar'
9
+ # hash['foo'] #=> 'bar'
10
+ # hash.foo? #=> true
11
+ #
12
+ class HashWithIndifferentAccess < ::Hash #:nodoc:
13
+
14
+ def initialize(hash={})
15
+ super()
16
+ hash.each do |key, value|
17
+ self[convert_key(key)] = value
18
+ end
19
+ end
20
+
21
+ def [](key)
22
+ super(convert_key(key))
23
+ end
24
+
25
+ def []=(key, value)
26
+ super(convert_key(key), value)
27
+ end
28
+
29
+ def delete(key)
30
+ super(convert_key(key))
31
+ end
32
+
33
+ def values_at(*indices)
34
+ indices.collect { |key| self[convert_key(key)] }
35
+ end
36
+
37
+ def merge(other)
38
+ dup.merge!(other)
39
+ end
40
+
41
+ def merge!(other)
42
+ other.each do |key, value|
43
+ self[convert_key(key)] = value
44
+ end
45
+ self
46
+ end
47
+
48
+ protected
49
+
50
+ def convert_key(key)
51
+ key.is_a?(Symbol) ? key.to_s : key
52
+ end
53
+
54
+ # Magic predicates. For instance:
55
+ #
56
+ # options.force? # => !!options['force']
57
+ # options.shebang # => "/usr/lib/local/ruby"
58
+ # options.test_framework?(:rspec) # => options[:test_framework] == :rspec
59
+ #
60
+ def method_missing(method, *args, &block)
61
+ method = method.to_s
62
+ if method =~ /^(\w+)\?$/
63
+ if args.empty?
64
+ !!self[$1]
65
+ else
66
+ self[$1] == args.first
67
+ end
68
+ else
69
+ self[method]
70
+ end
71
+ end
72
+
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,100 @@
1
+ class Thor
2
+ module CoreExt #:nodoc:
3
+
4
+ if RUBY_VERSION >= '1.9'
5
+ class OrderedHash < ::Hash
6
+ end
7
+ else
8
+ # This class is based on the Ruby 1.9 ordered hashes.
9
+ #
10
+ # It keeps the semantics and most of the efficiency of normal hashes
11
+ # while also keeping track of the order in which elements were set.
12
+ #
13
+ class OrderedHash #:nodoc:
14
+ include Enumerable
15
+
16
+ Node = Struct.new(:key, :value, :next, :prev)
17
+
18
+ def initialize
19
+ @hash = {}
20
+ end
21
+
22
+ def [](key)
23
+ @hash[key] && @hash[key].value
24
+ end
25
+
26
+ def []=(key, value)
27
+ if node = @hash[key]
28
+ node.value = value
29
+ else
30
+ node = Node.new(key, value)
31
+
32
+ if @first.nil?
33
+ @first = @last = node
34
+ else
35
+ node.prev = @last
36
+ @last.next = node
37
+ @last = node
38
+ end
39
+ end
40
+
41
+ @hash[key] = node
42
+ value
43
+ end
44
+
45
+ def delete(key)
46
+ if node = @hash[key]
47
+ prev_node = node.prev
48
+ next_node = node.next
49
+
50
+ next_node.prev = prev_node if next_node
51
+ prev_node.next = next_node if prev_node
52
+
53
+ @first = next_node if @first == node
54
+ @last = prev_node if @last == node
55
+
56
+ value = node.value
57
+ end
58
+
59
+ @hash.delete(key)
60
+ value
61
+ end
62
+
63
+ def keys
64
+ self.map { |k, v| k }
65
+ end
66
+
67
+ def values
68
+ self.map { |k, v| v }
69
+ end
70
+
71
+ def each
72
+ return unless @first
73
+ yield [@first.key, @first.value]
74
+ node = @first
75
+ yield [node.key, node.value] while node = node.next
76
+ self
77
+ end
78
+
79
+ def merge(other)
80
+ hash = self.class.new
81
+
82
+ self.each do |key, value|
83
+ hash[key] = value
84
+ end
85
+
86
+ other.each do |key, value|
87
+ hash[key] = value
88
+ end
89
+
90
+ hash
91
+ end
92
+
93
+ def empty?
94
+ @hash.empty?
95
+ end
96
+ end
97
+ end
98
+
99
+ end
100
+ end
@@ -0,0 +1,27 @@
1
+ class Thor
2
+ # Thor::Error is raised when it's caused by wrong usage of thor classes. Those
3
+ # errors have their backtrace supressed and are nicely shown to the user.
4
+ #
5
+ # Errors that are caused by the developer, like declaring a method which
6
+ # overwrites a thor keyword, it SHOULD NOT raise a Thor::Error. This way, we
7
+ # ensure that developer errors are shown with full backtrace.
8
+ #
9
+ class Error < StandardError
10
+ end
11
+
12
+ # Raised when a task was not found.
13
+ #
14
+ class UndefinedTaskError < Error
15
+ end
16
+
17
+ # Raised when a task was found, but not invoked properly.
18
+ #
19
+ class InvocationError < Error
20
+ end
21
+
22
+ class RequiredArgumentMissingError < InvocationError
23
+ end
24
+
25
+ class MalformattedArgumentError < InvocationError
26
+ end
27
+ end
@@ -0,0 +1,267 @@
1
+ # Thor has a special class called Thor::Group. The main difference to Thor class
2
+ # is that it invokes all tasks at once. It also include some methods that allows
3
+ # invocations to be done at the class method, which are not available to Thor
4
+ # tasks.
5
+ #
6
+ class Thor::Group
7
+ class << self
8
+ # The descrition for this Thor::Group. If none is provided, but a source root
9
+ # exists, tries to find the USAGE one folder above it, otherwise searches
10
+ # in the superclass.
11
+ #
12
+ # ==== Parameters
13
+ # description<String>:: The description for this Thor::Group.
14
+ #
15
+ def desc(description=nil)
16
+ case description
17
+ when nil
18
+ @desc ||= from_superclass(:desc, nil)
19
+ else
20
+ @desc = description
21
+ end
22
+ end
23
+
24
+ # Start works differently in Thor::Group, it simply invokes all tasks
25
+ # inside the class.
26
+ #
27
+ def start(given_args=ARGV, config={})
28
+ super do
29
+ if Thor::HELP_MAPPINGS.include?(given_args.first)
30
+ help(config[:shell])
31
+ return
32
+ end
33
+
34
+ args, opts = Thor::Options.split(given_args)
35
+ new(args, opts, config).invoke
36
+ end
37
+ end
38
+
39
+ # Prints help information.
40
+ #
41
+ # ==== Options
42
+ # short:: When true, shows only usage.
43
+ #
44
+ def help(shell)
45
+ shell.say "Usage:"
46
+ shell.say " #{banner}\n"
47
+ shell.say
48
+ class_options_help(shell)
49
+ shell.say self.desc if self.desc
50
+ end
51
+
52
+ # Stores invocations for this class merging with superclass values.
53
+ #
54
+ def invocations #:nodoc:
55
+ @invocations ||= from_superclass(:invocations, {})
56
+ end
57
+
58
+ # Stores invocation blocks used on invoke_from_option.
59
+ #
60
+ def invocation_blocks #:nodoc:
61
+ @invocation_blocks ||= from_superclass(:invocation_blocks, {})
62
+ end
63
+
64
+ # Invoke the given namespace or class given. It adds an instance
65
+ # method that will invoke the klass and task. You can give a block to
66
+ # configure how it will be invoked.
67
+ #
68
+ # The namespace/class given will have its options showed on the help
69
+ # usage. Check invoke_from_option for more information.
70
+ #
71
+ def invoke(*names, &block)
72
+ options = names.last.is_a?(Hash) ? names.pop : {}
73
+ verbose = options.fetch(:verbose, true)
74
+
75
+ names.each do |name|
76
+ invocations[name] = false
77
+ invocation_blocks[name] = block if block_given?
78
+
79
+ class_eval <<-METHOD, __FILE__, __LINE__
80
+ def _invoke_#{name.to_s.gsub(/\W/, '_')}
81
+ klass, task = self.class.prepare_for_invocation(nil, #{name.inspect})
82
+
83
+ if klass
84
+ say_status :invoke, #{name.inspect}, #{verbose.inspect}
85
+ block = self.class.invocation_blocks[#{name.inspect}]
86
+ _invoke_for_class_method klass, task, &block
87
+ else
88
+ say_status :error, %(#{name.inspect} [not found]), :red
89
+ end
90
+ end
91
+ METHOD
92
+ end
93
+ end
94
+
95
+ # Invoke a thor class based on the value supplied by the user to the
96
+ # given option named "name". A class option must be created before this
97
+ # method is invoked for each name given.
98
+ #
99
+ # ==== Examples
100
+ #
101
+ # class GemGenerator < Thor::Group
102
+ # class_option :test_framework, :type => :string
103
+ # invoke_from_option :test_framework
104
+ # end
105
+ #
106
+ # ==== Boolean options
107
+ #
108
+ # In some cases, you want to invoke a thor class if some option is true or
109
+ # false. This is automatically handled by invoke_from_option. Then the
110
+ # option name is used to invoke the generator.
111
+ #
112
+ # ==== Preparing for invocation
113
+ #
114
+ # In some cases you want to customize how a specified hook is going to be
115
+ # invoked. You can do that by overwriting the class method
116
+ # prepare_for_invocation. The class method must necessarily return a klass
117
+ # and an optional task.
118
+ #
119
+ # ==== Custom invocations
120
+ #
121
+ # You can also supply a block to customize how the option is giong to be
122
+ # invoked. The block receives two parameters, an instance of the current
123
+ # class and the klass to be invoked.
124
+ #
125
+ def invoke_from_option(*names, &block)
126
+ options = names.last.is_a?(Hash) ? names.pop : {}
127
+ verbose = options.fetch(:verbose, :white)
128
+
129
+ names.each do |name|
130
+ unless class_options.key?(name)
131
+ raise ArgumentError, "You have to define the option #{name.inspect} " <<
132
+ "before setting invoke_from_option."
133
+ end
134
+
135
+ invocations[name] = true
136
+ invocation_blocks[name] = block if block_given?
137
+
138
+ class_eval <<-METHOD, __FILE__, __LINE__
139
+ def _invoke_from_option_#{name.to_s.gsub(/\W/, '_')}
140
+ return unless options[#{name.inspect}]
141
+
142
+ value = options[#{name.inspect}]
143
+ value = #{name.inspect} if TrueClass === value
144
+ klass, task = self.class.prepare_for_invocation(#{name.inspect}, value)
145
+
146
+ if klass
147
+ say_status :invoke, value, #{verbose.inspect}
148
+ block = self.class.invocation_blocks[#{name.inspect}]
149
+ _invoke_for_class_method klass, task, &block
150
+ else
151
+ say_status :error, %(\#{value} [not found]), :red
152
+ end
153
+ end
154
+ METHOD
155
+ end
156
+ end
157
+
158
+ # Remove a previously added invocation.
159
+ #
160
+ # ==== Examples
161
+ #
162
+ # remove_invocation :test_framework
163
+ #
164
+ def remove_invocation(*names)
165
+ names.each do |name|
166
+ remove_task(name)
167
+ remove_class_option(name)
168
+ invocations.delete(name)
169
+ invocation_blocks.delete(name)
170
+ end
171
+ end
172
+
173
+ # Overwrite class options help to allow invoked generators options to be
174
+ # shown recursively when invoking a generator.
175
+ #
176
+ def class_options_help(shell, groups={}) #:nodoc:
177
+ get_options_from_invocations(groups, class_options) do |klass|
178
+ klass.send(:get_options_from_invocations, groups, class_options)
179
+ end
180
+ super(shell, groups)
181
+ end
182
+
183
+ # Get invocations array and merge options from invocations. Those
184
+ # options are added to group_options hash. Options that already exists
185
+ # in base_options are not added twice.
186
+ #
187
+ def get_options_from_invocations(group_options, base_options) #:nodoc:
188
+ invocations.each do |name, from_option|
189
+ value = if from_option
190
+ option = class_options[name]
191
+ option.type == :boolean ? name : option.default
192
+ else
193
+ name
194
+ end
195
+ next unless value
196
+
197
+ klass, task = prepare_for_invocation(name, value)
198
+ next unless klass && klass.respond_to?(:class_options)
199
+
200
+ value = value.to_s
201
+ human_name = value.respond_to?(:classify) ? value.classify : value
202
+
203
+ group_options[human_name] ||= []
204
+ group_options[human_name] += klass.class_options.values.select do |option|
205
+ base_options[option.name.to_sym].nil? && option.group.nil? &&
206
+ !group_options.values.flatten.any? { |i| i.name == option.name }
207
+ end
208
+
209
+ yield klass if block_given?
210
+ end
211
+ end
212
+
213
+ # Returns tasks ready to be printed.
214
+ def printable_tasks(*)
215
+ item = []
216
+ item << banner
217
+ item << (desc ? "# #{desc.gsub(/\s+/m,' ')}" : "")
218
+ [item]
219
+ end
220
+
221
+ protected
222
+
223
+ # The banner for this class. You can customize it if you are invoking the
224
+ # thor class by another ways which is not the Thor::Runner.
225
+ #
226
+ def banner
227
+ "thor #{self_task.formatted_usage(self, false)}"
228
+ end
229
+
230
+ # Represents the whole class as a task.
231
+ def self_task #:nodoc:
232
+ Thor::Task::Dynamic.new(self.namespace, class_options)
233
+ end
234
+
235
+ def baseclass #:nodoc:
236
+ Thor::Group
237
+ end
238
+
239
+ def create_task(meth) #:nodoc:
240
+ tasks[meth.to_s] = Thor::Task.new(meth, nil, nil, nil)
241
+ true
242
+ end
243
+ end
244
+
245
+ include Thor::Base
246
+
247
+ protected
248
+
249
+ # Shortcut to invoke with padding and block handling. Use internally by
250
+ # invoke and invoke_from_option class methods.
251
+ def _invoke_for_class_method(klass, task=nil, *args, &block) #:nodoc:
252
+ shell.padding += 1
253
+
254
+ result = if block_given?
255
+ if block.arity == 2
256
+ block.call(self, klass)
257
+ else
258
+ block.call(self, klass, task)
259
+ end
260
+ else
261
+ invoke klass, task, *args
262
+ end
263
+
264
+ shell.padding -= 1
265
+ result
266
+ end
267
+ end