honkster-bundler 1.1.pre

Sign up to get free protection for your applications and to get access to all the features.
Files changed (137) hide show
  1. data/.gitignore +14 -0
  2. data/CHANGELOG.md +547 -0
  3. data/ISSUES.md +32 -0
  4. data/LICENSE +20 -0
  5. data/README.md +29 -0
  6. data/Rakefile +150 -0
  7. data/UPGRADING.md +103 -0
  8. data/bin/bundle +21 -0
  9. data/bundler.gemspec +30 -0
  10. data/lib/bundler.rb +268 -0
  11. data/lib/bundler/capistrano.rb +11 -0
  12. data/lib/bundler/cli.rb +515 -0
  13. data/lib/bundler/definition.rb +427 -0
  14. data/lib/bundler/dependency.rb +114 -0
  15. data/lib/bundler/deployment.rb +37 -0
  16. data/lib/bundler/dsl.rb +245 -0
  17. data/lib/bundler/environment.rb +47 -0
  18. data/lib/bundler/gem_helper.rb +145 -0
  19. data/lib/bundler/graph.rb +130 -0
  20. data/lib/bundler/index.rb +114 -0
  21. data/lib/bundler/installer.rb +84 -0
  22. data/lib/bundler/lazy_specification.rb +71 -0
  23. data/lib/bundler/lockfile_parser.rb +108 -0
  24. data/lib/bundler/remote_specification.rb +59 -0
  25. data/lib/bundler/resolver.rb +454 -0
  26. data/lib/bundler/rubygems_ext.rb +203 -0
  27. data/lib/bundler/runtime.rb +148 -0
  28. data/lib/bundler/settings.rb +117 -0
  29. data/lib/bundler/setup.rb +15 -0
  30. data/lib/bundler/shared_helpers.rb +151 -0
  31. data/lib/bundler/source.rb +662 -0
  32. data/lib/bundler/spec_set.rb +134 -0
  33. data/lib/bundler/templates/Executable +16 -0
  34. data/lib/bundler/templates/Gemfile +4 -0
  35. data/lib/bundler/templates/newgem/Gemfile.tt +4 -0
  36. data/lib/bundler/templates/newgem/Rakefile.tt +2 -0
  37. data/lib/bundler/templates/newgem/bin/newgem.tt +3 -0
  38. data/lib/bundler/templates/newgem/gitignore.tt +3 -0
  39. data/lib/bundler/templates/newgem/lib/newgem.rb.tt +7 -0
  40. data/lib/bundler/templates/newgem/lib/newgem/version.rb.tt +7 -0
  41. data/lib/bundler/templates/newgem/newgem.gemspec.tt +21 -0
  42. data/lib/bundler/ui.rb +60 -0
  43. data/lib/bundler/vendor/thor.rb +319 -0
  44. data/lib/bundler/vendor/thor/actions.rb +297 -0
  45. data/lib/bundler/vendor/thor/actions/create_file.rb +105 -0
  46. data/lib/bundler/vendor/thor/actions/directory.rb +93 -0
  47. data/lib/bundler/vendor/thor/actions/empty_directory.rb +134 -0
  48. data/lib/bundler/vendor/thor/actions/file_manipulation.rb +229 -0
  49. data/lib/bundler/vendor/thor/actions/inject_into_file.rb +104 -0
  50. data/lib/bundler/vendor/thor/base.rb +556 -0
  51. data/lib/bundler/vendor/thor/core_ext/file_binary_read.rb +9 -0
  52. data/lib/bundler/vendor/thor/core_ext/hash_with_indifferent_access.rb +75 -0
  53. data/lib/bundler/vendor/thor/core_ext/ordered_hash.rb +100 -0
  54. data/lib/bundler/vendor/thor/error.rb +30 -0
  55. data/lib/bundler/vendor/thor/invocation.rb +168 -0
  56. data/lib/bundler/vendor/thor/parser.rb +4 -0
  57. data/lib/bundler/vendor/thor/parser/argument.rb +67 -0
  58. data/lib/bundler/vendor/thor/parser/arguments.rb +161 -0
  59. data/lib/bundler/vendor/thor/parser/option.rb +120 -0
  60. data/lib/bundler/vendor/thor/parser/options.rb +174 -0
  61. data/lib/bundler/vendor/thor/shell.rb +88 -0
  62. data/lib/bundler/vendor/thor/shell/basic.rb +275 -0
  63. data/lib/bundler/vendor/thor/shell/color.rb +108 -0
  64. data/lib/bundler/vendor/thor/shell/html.rb +121 -0
  65. data/lib/bundler/vendor/thor/task.rb +114 -0
  66. data/lib/bundler/vendor/thor/util.rb +229 -0
  67. data/lib/bundler/vendor/thor/version.rb +3 -0
  68. data/lib/bundler/version.rb +6 -0
  69. data/lib/bundler/vlad.rb +9 -0
  70. data/man/bundle-config.ronn +90 -0
  71. data/man/bundle-exec.ronn +98 -0
  72. data/man/bundle-install.ronn +310 -0
  73. data/man/bundle-package.ronn +59 -0
  74. data/man/bundle-update.ronn +176 -0
  75. data/man/bundle.ronn +77 -0
  76. data/man/gemfile.5.ronn +273 -0
  77. data/man/index.txt +6 -0
  78. data/spec/cache/gems_spec.rb +205 -0
  79. data/spec/cache/git_spec.rb +9 -0
  80. data/spec/cache/path_spec.rb +27 -0
  81. data/spec/cache/platform_spec.rb +57 -0
  82. data/spec/install/deploy_spec.rb +197 -0
  83. data/spec/install/deprecated_spec.rb +43 -0
  84. data/spec/install/gems/c_ext_spec.rb +48 -0
  85. data/spec/install/gems/env_spec.rb +107 -0
  86. data/spec/install/gems/flex_spec.rb +272 -0
  87. data/spec/install/gems/groups_spec.rb +228 -0
  88. data/spec/install/gems/packed_spec.rb +72 -0
  89. data/spec/install/gems/platform_spec.rb +195 -0
  90. data/spec/install/gems/resolving_spec.rb +72 -0
  91. data/spec/install/gems/simple_case_spec.rb +749 -0
  92. data/spec/install/gems/sudo_spec.rb +77 -0
  93. data/spec/install/gems/win32_spec.rb +26 -0
  94. data/spec/install/gemspec_spec.rb +96 -0
  95. data/spec/install/git_spec.rb +553 -0
  96. data/spec/install/invalid_spec.rb +17 -0
  97. data/spec/install/path_spec.rb +329 -0
  98. data/spec/install/upgrade_spec.rb +26 -0
  99. data/spec/lock/flex_spec.rb +650 -0
  100. data/spec/lock/git_spec.rb +35 -0
  101. data/spec/other/check_spec.rb +221 -0
  102. data/spec/other/config_spec.rb +40 -0
  103. data/spec/other/console_spec.rb +54 -0
  104. data/spec/other/exec_spec.rb +241 -0
  105. data/spec/other/ext_spec.rb +16 -0
  106. data/spec/other/gem_helper_spec.rb +126 -0
  107. data/spec/other/help_spec.rb +36 -0
  108. data/spec/other/init_spec.rb +40 -0
  109. data/spec/other/newgem_spec.rb +24 -0
  110. data/spec/other/open_spec.rb +35 -0
  111. data/spec/other/show_spec.rb +82 -0
  112. data/spec/pack/gems_spec.rb +22 -0
  113. data/spec/quality_spec.rb +55 -0
  114. data/spec/resolver/basic_spec.rb +20 -0
  115. data/spec/resolver/platform_spec.rb +57 -0
  116. data/spec/runtime/environment_rb_spec.rb +162 -0
  117. data/spec/runtime/executable_spec.rb +110 -0
  118. data/spec/runtime/load_spec.rb +102 -0
  119. data/spec/runtime/platform_spec.rb +90 -0
  120. data/spec/runtime/require_spec.rb +231 -0
  121. data/spec/runtime/setup_spec.rb +412 -0
  122. data/spec/runtime/with_clean_env_spec.rb +15 -0
  123. data/spec/spec_helper.rb +82 -0
  124. data/spec/support/builders.rb +566 -0
  125. data/spec/support/helpers.rb +243 -0
  126. data/spec/support/indexes.rb +113 -0
  127. data/spec/support/matchers.rb +89 -0
  128. data/spec/support/path.rb +71 -0
  129. data/spec/support/platforms.rb +49 -0
  130. data/spec/support/ruby_ext.rb +19 -0
  131. data/spec/support/rubygems_ext.rb +30 -0
  132. data/spec/support/rubygems_hax/rubygems_plugin.rb +9 -0
  133. data/spec/support/sudo.rb +21 -0
  134. data/spec/update/gems_spec.rb +112 -0
  135. data/spec/update/git_spec.rb +159 -0
  136. data/spec/update/source_spec.rb +50 -0
  137. metadata +251 -0
@@ -0,0 +1,134 @@
1
+ require 'tsort'
2
+
3
+ module Bundler
4
+ class SpecSet
5
+ include TSort, Enumerable
6
+
7
+ def initialize(specs)
8
+ @specs = specs.sort_by { |s| s.name }
9
+ end
10
+
11
+ def each
12
+ sorted.each { |s| yield s }
13
+ end
14
+
15
+ def length
16
+ @specs.length
17
+ end
18
+
19
+ def for(dependencies, skip = [], check = false, match_current_platform = false)
20
+ handled, deps, specs = {}, dependencies.dup, []
21
+ skip << 'bundler'
22
+
23
+ until deps.empty?
24
+ dep = deps.shift
25
+ next if handled[dep] || skip.include?(dep.name)
26
+
27
+ spec = lookup[dep.name].find do |s|
28
+ match_current_platform ?
29
+ Gem::Platform.match(s.platform) :
30
+ s.match_platform(dep.__platform)
31
+ end
32
+
33
+ handled[dep] = true
34
+
35
+ if spec
36
+ specs << spec
37
+
38
+ spec.dependencies.each do |d|
39
+ next if d.type == :development
40
+ d = DepProxy.new(d, dep.__platform) unless match_current_platform
41
+ deps << d
42
+ end
43
+ elsif check
44
+ return false
45
+ end
46
+ end
47
+
48
+ if spec = lookup['bundler'].first
49
+ specs << spec
50
+ end
51
+
52
+ check ? true : SpecSet.new(specs)
53
+ end
54
+
55
+ def valid_for?(deps)
56
+ self.for(deps, [], true)
57
+ end
58
+
59
+ def [](key)
60
+ key = key.name if key.respond_to?(:name)
61
+ lookup[key].reverse
62
+ end
63
+
64
+ def []=(key, value)
65
+ @specs << value
66
+ @lookup = nil
67
+ @sorted = nil
68
+ value
69
+ end
70
+
71
+ def to_a
72
+ sorted.dup
73
+ end
74
+
75
+ def to_hash
76
+ lookup.dup
77
+ end
78
+
79
+ def materialize(deps, missing_specs = nil)
80
+ materialized = self.for(deps, [], false, true).to_a
81
+ materialized.map! do |s|
82
+ next s unless s.is_a?(LazySpecification)
83
+ spec = s.__materialize__
84
+ if missing_specs
85
+ missing_specs << s unless spec
86
+ else
87
+ raise GemNotFound, "Could not find #{s.full_name} in any of the sources" unless spec
88
+ end
89
+ spec if spec
90
+ end
91
+ SpecSet.new(materialized.compact)
92
+ end
93
+
94
+ def merge(set)
95
+ arr = sorted.dup
96
+ set.each do |s|
97
+ next if arr.any? { |s2| s2.name == s.name && s2.version == s.version && s2.platform == s.platform }
98
+ arr << s
99
+ end
100
+ SpecSet.new(arr)
101
+ end
102
+
103
+ private
104
+
105
+ def sorted
106
+ rake = @specs.find { |s| s.name == 'rake' }
107
+ @sorted ||= ([rake] + tsort).compact.uniq
108
+ end
109
+
110
+ def lookup
111
+ @lookup ||= begin
112
+ lookup = Hash.new { |h,k| h[k] = [] }
113
+ specs = @specs.sort_by do |s|
114
+ s.platform.to_s == 'ruby' ? "\0" : s.platform.to_s
115
+ end
116
+ specs.reverse_each do |s|
117
+ lookup[s.name] << s
118
+ end
119
+ lookup
120
+ end
121
+ end
122
+
123
+ def tsort_each_node
124
+ @specs.each { |s| yield s }
125
+ end
126
+
127
+ def tsort_each_child(s)
128
+ s.dependencies.sort_by { |d| d.name }.each do |d|
129
+ next if d.type == :development
130
+ lookup[d.name].each { |s2| yield s2 }
131
+ end
132
+ end
133
+ end
134
+ end
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env <%= RbConfig::CONFIG['ruby_install_name'] %>
2
+ #
3
+ # This file was generated by Bundler.
4
+ #
5
+ # The application '<%= executable %>' is installed as part of a gem, and
6
+ # this file is here to facilitate running it.
7
+ #
8
+
9
+ require 'pathname'
10
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../<%= relative_gemfile_path %>",
11
+ Pathname.new(__FILE__).realpath)
12
+
13
+ require 'rubygems'
14
+ require 'bundler/setup'
15
+
16
+ load Gem.bin_path('<%= spec.name %>', '<%= executable %>')
@@ -0,0 +1,4 @@
1
+ # A sample Gemfile
2
+ source "http://rubygems.org"
3
+
4
+ # gem "rails"
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in <%=config[:name]%>.gemspec
4
+ gemspec
@@ -0,0 +1,2 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "<%= config[:name] %>"
@@ -0,0 +1,3 @@
1
+ pkg/*
2
+ *.gem
3
+ .bundle
@@ -0,0 +1,7 @@
1
+ <%- config[:constant_array].each_with_index do |c,i| -%>
2
+ <%= ' '*i %>module <%= c %>
3
+ <%- end -%>
4
+ <%= ' '*config[:constant_array].size %># Your code goes here...
5
+ <%- (config[:constant_array].size-1).downto(0) do |i| -%>
6
+ <%= ' '*i %>end
7
+ <%- end -%>
@@ -0,0 +1,7 @@
1
+ <%- config[:constant_array].each_with_index do |c,i| -%>
2
+ <%= ' '*i %>module <%= c %>
3
+ <%- end -%>
4
+ <%= ' '*config[:constant_array].size %>VERSION = "0.0.1"
5
+ <%- (config[:constant_array].size-1).downto(0) do |i| -%>
6
+ <%= ' '*i %>end
7
+ <%- end -%>
@@ -0,0 +1,21 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "<%=config[:name]%>/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = <%=config[:name].inspect%>
7
+ s.version = <%=config[:constant_name]%>::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["TODO: Write your name"]
10
+ s.email = ["TODO: Write your email address"]
11
+ s.homepage = "http://rubygems.org/gems/<%=config[:name]%>"
12
+ s.summary = %q{TODO: Write a gem summary}
13
+ s.description = %q{TODO: Write a gem description}
14
+
15
+ s.rubyforge_project = <%=config[:name].inspect%>
16
+
17
+ s.files = `git ls-files`.split("\n")
18
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
19
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
20
+ s.require_paths = ["lib"]
21
+ end
data/lib/bundler/ui.rb ADDED
@@ -0,0 +1,60 @@
1
+ module Bundler
2
+ class UI
3
+ def warn(message)
4
+ end
5
+
6
+ def error(message)
7
+ end
8
+
9
+ def info(message)
10
+ end
11
+
12
+ def confirm(message)
13
+ end
14
+
15
+ class Shell < UI
16
+ def initialize(shell)
17
+ @shell = shell
18
+ @quiet = false
19
+ end
20
+
21
+ def debug(msg)
22
+ @shell.say(msg) if ENV['DEBUG'] && !@quiet
23
+ end
24
+
25
+ def info(msg)
26
+ @shell.say(msg) if !@quiet
27
+ end
28
+
29
+ def confirm(msg)
30
+ @shell.say(msg, :green) if !@quiet
31
+ end
32
+
33
+ def warn(msg)
34
+ @shell.say(msg, :yellow)
35
+ end
36
+
37
+ def error(msg)
38
+ @shell.say(msg, :red)
39
+ end
40
+
41
+ def be_quiet!
42
+ @quiet = true
43
+ end
44
+ end
45
+
46
+ class RGProxy < Gem::SilentUI
47
+ def initialize(ui)
48
+ @ui = ui
49
+ end
50
+
51
+ def say(message)
52
+ if message =~ /native extensions/
53
+ @ui.info "with native extensions "
54
+ else
55
+ @ui.debug(message)
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,319 @@
1
+ require 'thor/base'
2
+
3
+ class Thor
4
+ class << self
5
+ # Sets the default task when thor is executed without an explicit task to be called.
6
+ #
7
+ # ==== Parameters
8
+ # meth<Symbol>:: name of the defaut task
9
+ #
10
+ def default_task(meth=nil)
11
+ case meth
12
+ when :none
13
+ @default_task = 'help'
14
+ when nil
15
+ @default_task ||= from_superclass(:default_task, 'help')
16
+ else
17
+ @default_task = meth.to_s
18
+ end
19
+ end
20
+
21
+ # Defines the usage and the description of the next task.
22
+ #
23
+ # ==== Parameters
24
+ # usage<String>
25
+ # description<String>
26
+ # options<String>
27
+ #
28
+ def desc(usage, description, options={})
29
+ if options[:for]
30
+ task = find_and_refresh_task(options[:for])
31
+ task.usage = usage if usage
32
+ task.description = description if description
33
+ else
34
+ @usage, @desc, @hide = usage, description, options[:hide] || false
35
+ end
36
+ end
37
+
38
+ # Defines the long description of the next task.
39
+ #
40
+ # ==== Parameters
41
+ # long description<String>
42
+ #
43
+ def long_desc(long_description, options={})
44
+ if options[:for]
45
+ task = find_and_refresh_task(options[:for])
46
+ task.long_description = long_description if long_description
47
+ else
48
+ @long_desc = long_description
49
+ end
50
+ end
51
+
52
+ # Maps an input to a task. If you define:
53
+ #
54
+ # map "-T" => "list"
55
+ #
56
+ # Running:
57
+ #
58
+ # thor -T
59
+ #
60
+ # Will invoke the list task.
61
+ #
62
+ # ==== Parameters
63
+ # Hash[String|Array => Symbol]:: Maps the string or the strings in the array to the given task.
64
+ #
65
+ def map(mappings=nil)
66
+ @map ||= from_superclass(:map, {})
67
+
68
+ if mappings
69
+ mappings.each do |key, value|
70
+ if key.respond_to?(:each)
71
+ key.each {|subkey| @map[subkey] = value}
72
+ else
73
+ @map[key] = value
74
+ end
75
+ end
76
+ end
77
+
78
+ @map
79
+ end
80
+
81
+ # Declares the options for the next task to be declared.
82
+ #
83
+ # ==== Parameters
84
+ # Hash[Symbol => Object]:: The hash key is the name of the option and the value
85
+ # is the type of the option. Can be :string, :array, :hash, :boolean, :numeric
86
+ # or :required (string). If you give a value, the type of the value is used.
87
+ #
88
+ def method_options(options=nil)
89
+ @method_options ||= {}
90
+ build_options(options, @method_options) if options
91
+ @method_options
92
+ end
93
+
94
+ # Adds an option to the set of method options. If :for is given as option,
95
+ # it allows you to change the options from a previous defined task.
96
+ #
97
+ # def previous_task
98
+ # # magic
99
+ # end
100
+ #
101
+ # method_option :foo => :bar, :for => :previous_task
102
+ #
103
+ # def next_task
104
+ # # magic
105
+ # end
106
+ #
107
+ # ==== Parameters
108
+ # name<Symbol>:: The name of the argument.
109
+ # options<Hash>:: Described below.
110
+ #
111
+ # ==== Options
112
+ # :desc - Description for the argument.
113
+ # :required - If the argument is required or not.
114
+ # :default - Default value for this argument. It cannot be required and have default values.
115
+ # :aliases - Aliases for this option.
116
+ # :type - The type of the argument, can be :string, :hash, :array, :numeric or :boolean.
117
+ # :banner - String to show on usage notes.
118
+ #
119
+ def method_option(name, options={})
120
+ scope = if options[:for]
121
+ find_and_refresh_task(options[:for]).options
122
+ else
123
+ method_options
124
+ end
125
+
126
+ build_option(name, options, scope)
127
+ end
128
+
129
+ # Prints help information for the given task.
130
+ #
131
+ # ==== Parameters
132
+ # shell<Thor::Shell>
133
+ # task_name<String>
134
+ #
135
+ def task_help(shell, task_name)
136
+ meth = normalize_task_name(task_name)
137
+ task = all_tasks[meth]
138
+ handle_no_task_error(meth) unless task
139
+
140
+ shell.say "Usage:"
141
+ shell.say " #{banner(task)}"
142
+ shell.say
143
+ class_options_help(shell, nil => task.options.map { |_, o| o })
144
+ if task.long_description
145
+ shell.say "Description:"
146
+ shell.print_wrapped(task.long_description, :ident => 2)
147
+ else
148
+ shell.say task.description
149
+ end
150
+ end
151
+
152
+ # Prints help information for this class.
153
+ #
154
+ # ==== Parameters
155
+ # shell<Thor::Shell>
156
+ #
157
+ def help(shell, subcommand = false)
158
+ list = printable_tasks(true, subcommand)
159
+ Thor::Util.thor_classes_in(self).each do |klass|
160
+ list += klass.printable_tasks(false)
161
+ end
162
+ list.sort!{ |a,b| a[0] <=> b[0] }
163
+
164
+ shell.say "Tasks:"
165
+ shell.print_table(list, :ident => 2, :truncate => true)
166
+ shell.say
167
+ class_options_help(shell)
168
+ end
169
+
170
+ # Returns tasks ready to be printed.
171
+ def printable_tasks(all = true, subcommand = false)
172
+ (all ? all_tasks : tasks).map do |_, task|
173
+ next if task.hidden?
174
+ item = []
175
+ item << banner(task, false, subcommand)
176
+ item << (task.description ? "# #{task.description.gsub(/\s+/m,' ')}" : "")
177
+ item
178
+ end.compact
179
+ end
180
+
181
+ def subcommands
182
+ @subcommands ||= from_superclass(:subcommands, [])
183
+ end
184
+
185
+ def subcommand(subcommand, subcommand_class)
186
+ self.subcommands << subcommand.to_s
187
+ subcommand_class.subcommand_help subcommand
188
+ define_method(subcommand) { |*args| invoke subcommand_class, args }
189
+ end
190
+
191
+ # Extend check unknown options to accept a hash of conditions.
192
+ #
193
+ # === Parameters
194
+ # options<Hash>: A hash containing :only and/or :except keys
195
+ def check_unknown_options!(options={})
196
+ @check_unknown_options ||= Hash.new
197
+ options.each do |key, value|
198
+ if value
199
+ @check_unknown_options[key] = Array(value)
200
+ else
201
+ @check_unknown_options.delete(key)
202
+ end
203
+ end
204
+ @check_unknown_options
205
+ end
206
+
207
+ # Overwrite check_unknown_options? to take subcommands and options into account.
208
+ def check_unknown_options?(config) #:nodoc:
209
+ options = check_unknown_options
210
+ return false unless options
211
+
212
+ task = config[:current_task]
213
+ return true unless task
214
+
215
+ name = task.name
216
+
217
+ if subcommands.include?(name)
218
+ false
219
+ elsif options[:except]
220
+ !options[:except].include?(name.to_sym)
221
+ elsif options[:only]
222
+ options[:only].include?(name.to_sym)
223
+ else
224
+ true
225
+ end
226
+ end
227
+
228
+ protected
229
+
230
+ # The method responsible for dispatching given the args.
231
+ def dispatch(meth, given_args, given_opts, config) #:nodoc:
232
+ meth ||= retrieve_task_name(given_args)
233
+ task = all_tasks[normalize_task_name(meth)]
234
+
235
+ if task
236
+ args, opts = Thor::Options.split(given_args)
237
+ else
238
+ args, opts = given_args, nil
239
+ task = Thor::DynamicTask.new(meth)
240
+ end
241
+
242
+ opts = given_opts || opts || []
243
+ config.merge!(:current_task => task, :task_options => task.options)
244
+
245
+ trailing = args[Range.new(arguments.size, -1)]
246
+ new(args, opts, config).invoke_task(task, trailing || [])
247
+ end
248
+
249
+ # The banner for this class. You can customize it if you are invoking the
250
+ # thor class by another ways which is not the Thor::Runner. It receives
251
+ # the task that is going to be invoked and a boolean which indicates if
252
+ # the namespace should be displayed as arguments.
253
+ #
254
+ def banner(task, namespace = nil, subcommand = false)
255
+ base = File.basename($0).split(" ").first
256
+ "#{base} #{task.formatted_usage(self, $thor_runner, subcommand)}"
257
+ end
258
+
259
+ def baseclass #:nodoc:
260
+ Thor
261
+ end
262
+
263
+ def create_task(meth) #:nodoc:
264
+ if @usage && @desc
265
+ base_class = @hide ? Thor::HiddenTask : Thor::Task
266
+ tasks[meth] = base_class.new(meth, @desc, @long_desc, @usage, method_options)
267
+ @usage, @desc, @long_desc, @method_options, @hide = nil
268
+ true
269
+ elsif self.all_tasks[meth] || meth == "method_missing"
270
+ true
271
+ else
272
+ puts "[WARNING] Attempted to create task #{meth.inspect} without usage or description. " <<
273
+ "Call desc if you want this method to be available as task or declare it inside a " <<
274
+ "no_tasks{} block. Invoked from #{caller[1].inspect}."
275
+ false
276
+ end
277
+ end
278
+
279
+ def initialize_added #:nodoc:
280
+ class_options.merge!(method_options)
281
+ @method_options = nil
282
+ end
283
+
284
+ # Retrieve the task name from given args.
285
+ def retrieve_task_name(args) #:nodoc:
286
+ meth = args.first.to_s unless args.empty?
287
+
288
+ if meth && (map[meth] || meth !~ /^\-/)
289
+ args.shift
290
+ else
291
+ nil
292
+ end
293
+ end
294
+
295
+ # Receives a task name (can be nil), and try to get a map from it.
296
+ # If a map can't be found use the sent name or the default task.
297
+ def normalize_task_name(meth) #:nodoc:
298
+ meth = map[meth.to_s] || meth || default_task
299
+ meth.to_s.gsub('-','_') # treat foo-bar > foo_bar
300
+ end
301
+
302
+ def subcommand_help(cmd)
303
+ desc "help [COMMAND]", "Describe subcommands or one specific subcommand"
304
+ class_eval <<-RUBY
305
+ def help(task = nil, subcommand = true); super; end
306
+ RUBY
307
+ end
308
+
309
+ end
310
+
311
+ include Thor::Base
312
+
313
+ map HELP_MAPPINGS => :help
314
+
315
+ desc "help [TASK]", "Describe available tasks or one specific task"
316
+ def help(task = nil, subcommand = false)
317
+ task ? self.class.task_help(shell, task) : self.class.help(shell, subcommand)
318
+ end
319
+ end