engineyard-serverside 2.0.0 → 2.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (36) hide show
  1. data/lib/engineyard-serverside/paths.rb +0 -1
  2. data/lib/engineyard-serverside/version.rb +1 -1
  3. data/lib/vendor/thor/{LICENSE → LICENSE.md} +2 -2
  4. data/lib/vendor/thor/README.md +28 -0
  5. data/lib/vendor/thor/lib/thor.rb +183 -48
  6. data/lib/vendor/thor/lib/thor/actions.rb +66 -23
  7. data/lib/vendor/thor/lib/thor/actions/create_file.rb +5 -3
  8. data/lib/vendor/thor/lib/thor/actions/create_link.rb +57 -0
  9. data/lib/vendor/thor/lib/thor/actions/directory.rb +14 -7
  10. data/lib/vendor/thor/lib/thor/actions/empty_directory.rb +24 -5
  11. data/lib/vendor/thor/lib/thor/actions/file_manipulation.rb +106 -21
  12. data/lib/vendor/thor/lib/thor/actions/inject_into_file.rb +15 -10
  13. data/lib/vendor/thor/lib/thor/base.rb +144 -43
  14. data/lib/vendor/thor/lib/thor/core_ext/dir_escape.rb +0 -0
  15. data/lib/vendor/thor/lib/thor/core_ext/hash_with_indifferent_access.rb +1 -1
  16. data/lib/vendor/thor/lib/thor/error.rb +6 -1
  17. data/lib/vendor/thor/lib/thor/group.rb +41 -27
  18. data/lib/vendor/thor/lib/thor/invocation.rb +48 -58
  19. data/lib/vendor/thor/lib/thor/parser/argument.rb +29 -22
  20. data/lib/vendor/thor/lib/thor/parser/arguments.rb +26 -5
  21. data/lib/vendor/thor/lib/thor/parser/option.rb +42 -49
  22. data/lib/vendor/thor/lib/thor/parser/options.rb +39 -30
  23. data/lib/vendor/thor/lib/thor/rake_compat.rb +13 -8
  24. data/lib/vendor/thor/lib/thor/runner.rb +27 -20
  25. data/lib/vendor/thor/lib/thor/shell.rb +10 -5
  26. data/lib/vendor/thor/lib/thor/shell/basic.rb +228 -78
  27. data/lib/vendor/thor/lib/thor/shell/color.rb +40 -4
  28. data/lib/vendor/thor/lib/thor/shell/html.rb +123 -0
  29. data/lib/vendor/thor/lib/thor/task.rb +83 -53
  30. data/lib/vendor/thor/lib/thor/util.rb +57 -21
  31. data/lib/vendor/thor/lib/thor/version.rb +1 -1
  32. data/lib/vendor/thor/thor.gemspec +21 -115
  33. metadata +109 -217
  34. data/lib/vendor/thor/CHANGELOG.rdoc +0 -89
  35. data/lib/vendor/thor/README.rdoc +0 -297
  36. data/lib/vendor/thor/Thorfile +0 -69
@@ -10,10 +10,10 @@ class Thor
10
10
  # available only in class methods invocations (i.e. in Thor::Group).
11
11
  def prepare_for_invocation(key, name) #:nodoc:
12
12
  case name
13
- when Symbol, String
14
- Thor::Util.find_class_and_task_by_namespace(name.to_s)
15
- else
16
- name
13
+ when Symbol, String
14
+ Thor::Util.find_class_and_task_by_namespace(name.to_s, !key)
15
+ else
16
+ name
17
17
  end
18
18
  end
19
19
  end
@@ -85,7 +85,7 @@ class Thor
85
85
  # that it's going to use.
86
86
  #
87
87
  # If you want Rspec::RR to be initialized with its own set of options, you
88
- # have to do that explicitely:
88
+ # have to do that explicitly:
89
89
  #
90
90
  # invoke "rspec:rr", [], :style => :foo
91
91
  #
@@ -94,31 +94,38 @@ class Thor
94
94
  # invoke Rspec::RR, [], :style => :foo
95
95
  #
96
96
  def invoke(name=nil, *args)
97
+ if name.nil?
98
+ warn "[Thor] Calling invoke() without argument is deprecated. Please use invoke_all instead.\n#{caller.join("\n")}"
99
+ return invoke_all
100
+ end
101
+
97
102
  args.unshift(nil) if Array === args.first || NilClass === args.first
98
103
  task, args, opts, config = args
99
104
 
100
- object, task = _prepare_for_invocation(name, task)
101
- klass, instance = _initialize_klass_with_initializer(object, args, opts, config)
102
-
103
- method_args = []
104
- current = @_invocations[klass]
105
+ klass, task = _retrieve_class_and_task(name, task)
106
+ raise "Expected Thor class, got #{klass}" unless klass <= Thor::Base
105
107
 
106
- iterator = proc do |_, task|
107
- unless current.include?(task.name)
108
- current << task.name
109
- task.run(instance, method_args)
110
- end
108
+ args, opts, config = _parse_initialization_options(args, opts, config)
109
+ klass.send(:dispatch, task, args, opts, config) do |instance|
110
+ instance.parent_options = options
111
111
  end
112
+ end
112
113
 
113
- if task
114
- args ||= []
115
- method_args = args[Range.new(klass.arguments.size, -1)] || []
116
- iterator.call(nil, task)
117
- else
118
- klass.all_tasks.map(&iterator)
114
+ # Invoke the given task if the given args.
115
+ def invoke_task(task, *args) #:nodoc:
116
+ current = @_invocations[self.class]
117
+
118
+ unless current.include?(task.name)
119
+ current << task.name
120
+ task.run(self, *args)
119
121
  end
120
122
  end
121
123
 
124
+ # Invoke all tasks for the current instance.
125
+ def invoke_all #:nodoc:
126
+ self.class.all_tasks.map { |_, task| invoke_task(task) }
127
+ end
128
+
122
129
  # Invokes using shell padding.
123
130
  def invoke_with_padding(*args)
124
131
  with_padding { invoke(*args) }
@@ -131,50 +138,33 @@ class Thor
131
138
  { :invocations => @_invocations }
132
139
  end
133
140
 
134
- # This method can receive several different types of arguments and it's then
135
- # responsible to normalize them by returning the object where the task should
136
- # be invoked and a Thor::Task object.
137
- def _prepare_for_invocation(name, sent_task=nil) #:nodoc:
138
- if name.is_a?(Thor::Task)
139
- task = name
140
- elsif task = self.class.all_tasks[name.to_s]
141
- object = self
141
+ # This method simply retrieves the class and task to be invoked.
142
+ # If the name is nil or the given name is a task in the current class,
143
+ # use the given name and return self as class. Otherwise, call
144
+ # prepare_for_invocation in the current class.
145
+ def _retrieve_class_and_task(name, sent_task=nil) #:nodoc:
146
+ case
147
+ when name.nil?
148
+ [self.class, nil]
149
+ when self.class.all_tasks[name.to_s]
150
+ [self.class, name.to_s]
142
151
  else
143
- object, task = self.class.prepare_for_invocation(nil, name)
144
- task ||= sent_task
152
+ klass, task = self.class.prepare_for_invocation(nil, name)
153
+ [klass, task || sent_task]
145
154
  end
146
-
147
- # If the object was not set, use self and use the name as task.
148
- object, task = self, name unless object
149
- return object, _validate_task(object, task)
150
- end
151
-
152
- # Check if the object given is a Thor class object and get a task object
153
- # for it.
154
- def _validate_task(object, task) #:nodoc:
155
- klass = object.is_a?(Class) ? object : object.class
156
- raise "Expected Thor class, got #{klass}" unless klass <= Thor::Base
157
-
158
- task ||= klass.default_task if klass.respond_to?(:default_task)
159
- task = klass.all_tasks[task.to_s] || Thor::Task::Dynamic.new(task) if task && !task.is_a?(Thor::Task)
160
- task
161
155
  end
162
156
 
163
157
  # Initialize klass using values stored in the @_initializer.
164
- def _initialize_klass_with_initializer(object, args, opts, config) #:nodoc:
165
- if object.is_a?(Class)
166
- klass = object
158
+ def _parse_initialization_options(args, opts, config) #:nodoc:
159
+ stored_args, stored_opts, stored_config = @_initializer
167
160
 
168
- stored_args, stored_opts, stored_config = @_initializer
169
- args ||= stored_args.dup
170
- opts ||= stored_opts.dup
161
+ args ||= stored_args.dup
162
+ opts ||= stored_opts.dup
171
163
 
172
- config ||= {}
173
- config = stored_config.merge(_shared_configuration).merge!(config)
174
- [ klass, klass.new(args, opts, config) ]
175
- else
176
- [ object.class, object ]
177
- end
164
+ config ||= {}
165
+ config = stored_config.merge(_shared_configuration).merge!(config)
166
+
167
+ [ args, opts, config ]
178
168
  end
179
169
  end
180
170
  end
@@ -2,21 +2,24 @@ class Thor
2
2
  class Argument #:nodoc:
3
3
  VALID_TYPES = [ :numeric, :hash, :array, :string ]
4
4
 
5
- attr_reader :name, :description, :required, :type, :default, :banner
5
+ attr_reader :name, :description, :enum, :required, :type, :default, :banner
6
6
  alias :human_name :name
7
7
 
8
- def initialize(name, description=nil, required=true, type=:string, default=nil, banner=nil)
8
+ def initialize(name, options={})
9
9
  class_name = self.class.name.split("::").last
10
10
 
11
+ type = options[:type]
12
+
11
13
  raise ArgumentError, "#{class_name} name can't be nil." if name.nil?
12
14
  raise ArgumentError, "Type :#{type} is not valid for #{class_name.downcase}s." if type && !valid_type?(type)
13
15
 
14
16
  @name = name.to_s
15
- @description = description
16
- @required = required || false
17
+ @description = options[:desc]
18
+ @required = options.key?(:required) ? options[:required] : true
17
19
  @type = (type || :string).to_sym
18
- @default = default
19
- @banner = banner || default_banner
20
+ @default = options[:default]
21
+ @banner = options[:banner] || default_banner
22
+ @enum = options[:enum]
20
23
 
21
24
  validate! # Trigger specific validations
22
25
  end
@@ -31,35 +34,39 @@ class Thor
31
34
 
32
35
  def show_default?
33
36
  case default
34
- when Array, String, Hash
35
- !default.empty?
36
- else
37
- default
37
+ when Array, String, Hash
38
+ !default.empty?
39
+ else
40
+ default
38
41
  end
39
42
  end
40
43
 
41
44
  protected
42
45
 
43
46
  def validate!
44
- raise ArgumentError, "An argument cannot be required and have default value." if required? && !default.nil?
47
+ if required? && !default.nil?
48
+ raise ArgumentError, "An argument cannot be required and have default value."
49
+ elsif @enum && !@enum.is_a?(Array)
50
+ raise ArgumentError, "An argument cannot have an enum other than an array."
51
+ end
45
52
  end
46
53
 
47
54
  def valid_type?(type)
48
- VALID_TYPES.include?(type.to_sym)
55
+ self.class::VALID_TYPES.include?(type.to_sym)
49
56
  end
50
57
 
51
58
  def default_banner
52
59
  case type
53
- when :boolean
54
- nil
55
- when :string, :default
56
- human_name.upcase
57
- when :numeric
58
- "N"
59
- when :hash
60
- "key:value"
61
- when :array
62
- "one two three"
60
+ when :boolean
61
+ nil
62
+ when :string, :default
63
+ human_name.upcase
64
+ when :numeric
65
+ "N"
66
+ when :hash
67
+ "key:value"
68
+ when :array
69
+ "one two three"
63
70
  end
64
71
  end
65
72
 
@@ -28,7 +28,7 @@ class Thor
28
28
  @switches = arguments
29
29
 
30
30
  arguments.each do |argument|
31
- if argument.default
31
+ if argument.default != nil
32
32
  @assigns[argument.human_name] = argument.default
33
33
  elsif argument.required?
34
34
  @non_assigned_required << argument
@@ -49,8 +49,17 @@ class Thor
49
49
  @assigns
50
50
  end
51
51
 
52
+ def remaining
53
+ @pile
54
+ end
55
+
52
56
  private
53
57
 
58
+ def no_or_skip?(arg)
59
+ arg =~ /^--(no|skip)-([-\w]+)$/
60
+ $2
61
+ end
62
+
54
63
  def last?
55
64
  @pile.empty?
56
65
  end
@@ -89,7 +98,7 @@ class Thor
89
98
  hash = {}
90
99
 
91
100
  while current_is_value? && peek.include?(?:)
92
- key, value = shift.split(':')
101
+ key, value = shift.split(':',2)
93
102
  hash[key] = value
94
103
  end
95
104
  hash
@@ -114,7 +123,7 @@ class Thor
114
123
  array
115
124
  end
116
125
 
117
- # Check if the peel is numeric ofrmat and return a Float or Integer.
126
+ # Check if the peek is numeric format and return a Float or Integer.
118
127
  # Otherwise raises an error.
119
128
  #
120
129
  def parse_numeric(name)
@@ -127,10 +136,22 @@ class Thor
127
136
  $&.index('.') ? shift.to_f : shift.to_i
128
137
  end
129
138
 
130
- # Parse string, i.e., just return the current value in the pile.
139
+ # Parse string:
140
+ # for --string-arg, just return the current value in the pile
141
+ # for --no-string-arg, nil
131
142
  #
132
143
  def parse_string(name)
133
- shift
144
+ if no_or_skip?(name)
145
+ nil
146
+ else
147
+ value = shift
148
+ if @switches.is_a?(Hash) && switch = @switches[name]
149
+ if switch.enum && !switch.enum.include?(value)
150
+ raise MalformattedArgumentError, "Expected '#{name}' to be one of #{switch.enum.join(', ')}; got #{value}"
151
+ end
152
+ end
153
+ value
154
+ end
134
155
  end
135
156
 
136
157
  # Raises an error if @non_assigned_required array is not empty.
@@ -1,13 +1,16 @@
1
1
  class Thor
2
2
  class Option < Argument #:nodoc:
3
- attr_reader :aliases, :group
3
+ attr_reader :aliases, :group, :lazy_default, :hide
4
4
 
5
5
  VALID_TYPES = [:boolean, :numeric, :hash, :array, :string]
6
6
 
7
- def initialize(name, description=nil, required=nil, type=nil, default=nil, banner=nil, group=nil, aliases=nil)
8
- super(name, description, required, type, default, banner)
9
- @aliases = [*aliases].compact
10
- @group = group.to_s.capitalize if group
7
+ def initialize(name, options={})
8
+ options[:required] = false unless options.key?(:required)
9
+ super
10
+ @lazy_default = options[:lazy_default]
11
+ @group = options[:group].to_s.capitalize if options[:group]
12
+ @aliases = Array(options[:aliases])
13
+ @hide = options[:hide]
11
14
  end
12
15
 
13
16
  # This parse quick options given as method_options. It makes several
@@ -36,7 +39,7 @@ class Thor
36
39
  # string (--foo=value) or booleans (just --foo).
37
40
  #
38
41
  # By default all options are optional, unless :required is given.
39
- #
42
+ #
40
43
  def self.parse(key, value)
41
44
  if key.is_a?(Array)
42
45
  name, *aliases = key
@@ -48,23 +51,21 @@ class Thor
48
51
  default = value
49
52
 
50
53
  type = case value
51
- when Symbol
52
- default = nil
53
-
54
- if VALID_TYPES.include?(value)
55
- value
56
- elsif required = (value == :required)
57
- :string
58
- end
59
- when TrueClass, FalseClass
60
- :boolean
61
- when Numeric
62
- :numeric
63
- when Hash, Array, String
64
- value.class.name.downcase.to_sym
54
+ when Symbol
55
+ default = nil
56
+ if VALID_TYPES.include?(value)
57
+ value
58
+ elsif required = (value == :required)
59
+ :string
60
+ end
61
+ when TrueClass, FalseClass
62
+ :boolean
63
+ when Numeric
64
+ :numeric
65
+ when Hash, Array, String
66
+ value.class.name.downcase.to_sym
65
67
  end
66
-
67
- self.new(name.to_s, nil, required, type, default, nil, nil, aliases)
68
+ self.new(name.to_s, :required => required, :type => type, :default => default, :aliases => aliases)
68
69
  end
69
70
 
70
71
  def switch_name
@@ -91,38 +92,30 @@ class Thor
91
92
  end
92
93
  end
93
94
 
94
- # Allow some type predicates as: boolean?, string? and etc.
95
- #
96
- def method_missing(method, *args, &block)
97
- given = method.to_s.sub(/\?$/, '').to_sym
98
- if valid_type?(given)
99
- self.type == given
100
- else
101
- super
102
- end
95
+ VALID_TYPES.each do |type|
96
+ class_eval <<-RUBY, __FILE__, __LINE__ + 1
97
+ def #{type}?
98
+ self.type == #{type.inspect}
99
+ end
100
+ RUBY
103
101
  end
104
102
 
105
- protected
106
-
107
- def validate!
108
- raise ArgumentError, "An option cannot be boolean and required." if boolean? && required?
109
- end
110
-
111
- def valid_type?(type)
112
- VALID_TYPES.include?(type.to_sym)
113
- end
103
+ protected
114
104
 
115
- def dasherized?
116
- name.index('-') == 0
117
- end
105
+ def validate!
106
+ raise ArgumentError, "An option cannot be boolean and required." if boolean? && required?
107
+ end
118
108
 
119
- def undasherize(str)
120
- str.sub(/^-{1,2}/, '')
121
- end
109
+ def dasherized?
110
+ name.index('-') == 0
111
+ end
122
112
 
123
- def dasherize(str)
124
- (str.length > 1 ? "--" : "-") + str.gsub('_', '-')
125
- end
113
+ def undasherize(str)
114
+ str.sub(/^-{1,2}/, '')
115
+ end
126
116
 
117
+ def dasherize(str)
118
+ (str.length > 1 ? "--" : "-") + str.gsub('_', '-')
119
+ end
127
120
  end
128
121
  end
@@ -1,7 +1,4 @@
1
1
  class Thor
2
- # This is a modified version of Daniel Berger's Getopt::Long class, licensed
3
- # under Ruby's license.
4
- #
5
2
  class Options < Arguments #:nodoc:
6
3
  LONG_RE = /^(--\w+(?:-\w+)*)$/
7
4
  SHORT_RE = /^(-[a-z])$/i
@@ -38,7 +35,7 @@ class Thor
38
35
  @non_assigned_required.delete(hash_options[key])
39
36
  end
40
37
 
41
- @shorts, @switches, @unknown = {}, {}, []
38
+ @shorts, @switches, @extra = {}, {}, []
42
39
 
43
40
  options.each do |option|
44
41
  @switches[option.switch_name] = option
@@ -49,12 +46,19 @@ class Thor
49
46
  end
50
47
  end
51
48
 
49
+ def remaining
50
+ @extra
51
+ end
52
+
52
53
  def parse(args)
53
54
  @pile = args.dup
54
55
 
55
56
  while peek
56
- if current_is_switch?
57
- case shift
57
+ match, is_switch = current_is_switch?
58
+ shifted = shift
59
+
60
+ if is_switch
61
+ case shifted
58
62
  when SHORT_SQ_RE
59
63
  unshift($1.split('').map { |f| "-#{f}" })
60
64
  next
@@ -68,10 +72,11 @@ class Thor
68
72
  switch = normalize_switch(switch)
69
73
  option = switch_option(switch)
70
74
  @assigns[option.human_name] = parse_peek(switch, option)
71
- elsif current_is_switch_formatted?
72
- @unknown << shift
75
+ elsif match
76
+ @extra << shifted
77
+ @extra << shift while peek && peek !~ /^-/
73
78
  else
74
- shift
79
+ @extra << shifted
75
80
  end
76
81
  end
77
82
 
@@ -83,7 +88,9 @@ class Thor
83
88
  end
84
89
 
85
90
  def check_unknown!
86
- raise UnknownArgumentError, "Unknown switches '#{@unknown.join(', ')}'" unless @unknown.empty?
91
+ # an unknown option starts with - or -- and has no more --'s afterward.
92
+ unknown = @extra.select { |str| str =~ /^--?(?:(?!--).)*$/ }
93
+ raise UnknownArgumentError, "Unknown switches '#{unknown.join(', ')}'" unless unknown.empty?
87
94
  end
88
95
 
89
96
  protected
@@ -92,15 +99,17 @@ class Thor
92
99
  #
93
100
  def current_is_switch?
94
101
  case peek
95
- when LONG_RE, SHORT_RE, EQ_RE, SHORT_NUM
96
- switch?($1)
97
- when SHORT_SQ_RE
98
- $1.split('').any? { |f| switch?("-#{f}") }
102
+ when LONG_RE, SHORT_RE, EQ_RE, SHORT_NUM
103
+ [true, switch?($1)]
104
+ when SHORT_SQ_RE
105
+ [true, $1.split('').any? { |f| switch?("-#{f}") }]
106
+ else
107
+ [false, false]
99
108
  end
100
109
  end
101
110
 
102
- def switch_formatted?(arg)
103
- case arg
111
+ def current_is_switch_formatted?
112
+ case peek
104
113
  when LONG_RE, SHORT_RE, EQ_RE, SHORT_NUM, SHORT_SQ_RE
105
114
  true
106
115
  else
@@ -108,12 +117,8 @@ class Thor
108
117
  end
109
118
  end
110
119
 
111
- def current_is_switch_formatted?
112
- switch_formatted? peek
113
- end
114
-
115
120
  def switch?(arg)
116
- switch_option(arg) || @shorts.key?(arg)
121
+ switch_option(normalize_switch(arg))
117
122
  end
118
123
 
119
124
  def switch_option(arg)
@@ -124,22 +129,25 @@ class Thor
124
129
  end
125
130
  end
126
131
 
127
- def no_or_skip?(arg)
128
- arg =~ /^--(no|skip)-([-\w]+)$/
129
- $2
130
- end
131
-
132
132
  # Check if the given argument is actually a shortcut.
133
133
  #
134
134
  def normalize_switch(arg)
135
- @shorts.key?(arg) ? @shorts[arg] : arg
135
+ (@shorts[arg] || arg).tr('_', '-')
136
136
  end
137
137
 
138
138
  # Parse boolean values which can be given as --foo=true, --foo or --no-foo.
139
139
  #
140
140
  def parse_boolean(switch)
141
141
  if current_is_value?
142
- ["true", "TRUE", "t", "T", true].include?(shift)
142
+ if ["true", "TRUE", "t", "T", true].include?(peek)
143
+ shift
144
+ true
145
+ elsif ["false", "FALSE", "f", "F", false].include?(peek)
146
+ shift
147
+ false
148
+ else
149
+ true
150
+ end
143
151
  else
144
152
  @switches.key?(switch) || !no_or_skip?(switch)
145
153
  end
@@ -155,7 +163,9 @@ class Thor
155
163
  return nil # User set value to nil
156
164
  elsif option.string? && !option.required?
157
165
  # Return the default if there is one, else the human name
158
- return option.default || option.human_name
166
+ return option.lazy_default || option.default || option.human_name
167
+ elsif option.lazy_default
168
+ return option.lazy_default
159
169
  else
160
170
  raise MalformattedArgumentError, "No value provided for option '#{switch}'"
161
171
  end
@@ -164,6 +174,5 @@ class Thor
164
174
  @non_assigned_required.delete(option)
165
175
  send(:"parse_#{option.type}", switch)
166
176
  end
167
-
168
177
  end
169
178
  end