engineyard-serverside 2.0.0 → 2.0.1

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.
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