engineyard 1.0.0 → 1.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 (34) hide show
  1. data/lib/engineyard/cli.rb +11 -2
  2. data/lib/engineyard/model/environment.rb +36 -3
  3. data/lib/engineyard/model/instance.rb +1 -1
  4. data/lib/engineyard/thor.rb +50 -68
  5. data/lib/engineyard/version.rb +1 -1
  6. data/spec/ey/deploy_spec.rb +66 -0
  7. metadata +23 -36
  8. data/lib/engineyard/vendor/thor.rb +0 -270
  9. data/lib/engineyard/vendor/thor/actions.rb +0 -297
  10. data/lib/engineyard/vendor/thor/actions/create_file.rb +0 -105
  11. data/lib/engineyard/vendor/thor/actions/directory.rb +0 -93
  12. data/lib/engineyard/vendor/thor/actions/empty_directory.rb +0 -134
  13. data/lib/engineyard/vendor/thor/actions/file_manipulation.rb +0 -229
  14. data/lib/engineyard/vendor/thor/actions/inject_into_file.rb +0 -104
  15. data/lib/engineyard/vendor/thor/base.rb +0 -540
  16. data/lib/engineyard/vendor/thor/core_ext/file_binary_read.rb +0 -9
  17. data/lib/engineyard/vendor/thor/core_ext/hash_with_indifferent_access.rb +0 -75
  18. data/lib/engineyard/vendor/thor/core_ext/ordered_hash.rb +0 -100
  19. data/lib/engineyard/vendor/thor/error.rb +0 -30
  20. data/lib/engineyard/vendor/thor/group.rb +0 -271
  21. data/lib/engineyard/vendor/thor/invocation.rb +0 -180
  22. data/lib/engineyard/vendor/thor/parser.rb +0 -4
  23. data/lib/engineyard/vendor/thor/parser/argument.rb +0 -67
  24. data/lib/engineyard/vendor/thor/parser/arguments.rb +0 -161
  25. data/lib/engineyard/vendor/thor/parser/option.rb +0 -128
  26. data/lib/engineyard/vendor/thor/parser/options.rb +0 -164
  27. data/lib/engineyard/vendor/thor/rake_compat.rb +0 -66
  28. data/lib/engineyard/vendor/thor/runner.rb +0 -314
  29. data/lib/engineyard/vendor/thor/shell.rb +0 -83
  30. data/lib/engineyard/vendor/thor/shell/basic.rb +0 -268
  31. data/lib/engineyard/vendor/thor/shell/color.rb +0 -108
  32. data/lib/engineyard/vendor/thor/task.rb +0 -102
  33. data/lib/engineyard/vendor/thor/util.rb +0 -229
  34. data/lib/engineyard/vendor/thor/version.rb +0 -3
@@ -1,180 +0,0 @@
1
- class Thor
2
- module Invocation
3
- def self.included(base) #:nodoc:
4
- base.extend ClassMethods
5
- end
6
-
7
- module ClassMethods
8
- # This method is responsible for receiving a name and find the proper
9
- # class and task for it. The key is an optional parameter which is
10
- # available only in class methods invocations (i.e. in Thor::Group).
11
- def prepare_for_invocation(key, name) #:nodoc:
12
- case name
13
- when Symbol, String
14
- Thor::Util.find_class_and_task_by_namespace(name.to_s, !key)
15
- else
16
- name
17
- end
18
- end
19
- end
20
-
21
- # Make initializer aware of invocations and the initialization args.
22
- def initialize(args=[], options={}, config={}, &block) #:nodoc:
23
- @_invocations = config[:invocations] || Hash.new { |h,k| h[k] = [] }
24
- @_initializer = [ args, options, config ]
25
- super
26
- end
27
-
28
- # Receives a name and invokes it. The name can be a string (either "task" or
29
- # "namespace:task"), a Thor::Task, a Class or a Thor instance. If the task
30
- # cannot be guessed by name, it can also be supplied as second argument.
31
- #
32
- # You can also supply the arguments, options and configuration values for
33
- # the task to be invoked, if none is given, the same values used to
34
- # initialize the invoker are used to initialize the invoked.
35
- #
36
- # When no name is given, it will invoke the default task of the current class.
37
- #
38
- # ==== Examples
39
- #
40
- # class A < Thor
41
- # def foo
42
- # invoke :bar
43
- # invoke "b:hello", ["José"]
44
- # end
45
- #
46
- # def bar
47
- # invoke "b:hello", ["José"]
48
- # end
49
- # end
50
- #
51
- # class B < Thor
52
- # def hello(name)
53
- # puts "hello #{name}"
54
- # end
55
- # end
56
- #
57
- # You can notice that the method "foo" above invokes two tasks: "bar",
58
- # which belongs to the same class and "hello" which belongs to the class B.
59
- #
60
- # By using an invocation system you ensure that a task is invoked only once.
61
- # In the example above, invoking "foo" will invoke "b:hello" just once, even
62
- # if it's invoked later by "bar" method.
63
- #
64
- # When class A invokes class B, all arguments used on A initialization are
65
- # supplied to B. This allows lazy parse of options. Let's suppose you have
66
- # some rspec tasks:
67
- #
68
- # class Rspec < Thor::Group
69
- # class_option :mock_framework, :type => :string, :default => :rr
70
- #
71
- # def invoke_mock_framework
72
- # invoke "rspec:#{options[:mock_framework]}"
73
- # end
74
- # end
75
- #
76
- # As you noticed, it invokes the given mock framework, which might have its
77
- # own options:
78
- #
79
- # class Rspec::RR < Thor::Group
80
- # class_option :style, :type => :string, :default => :mock
81
- # end
82
- #
83
- # Since it's not rspec concern to parse mock framework options, when RR
84
- # is invoked all options are parsed again, so RR can extract only the options
85
- # that it's going to use.
86
- #
87
- # If you want Rspec::RR to be initialized with its own set of options, you
88
- # have to do that explicitely:
89
- #
90
- # invoke "rspec:rr", [], :style => :foo
91
- #
92
- # Besides giving an instance, you can also give a class to invoke:
93
- #
94
- # invoke Rspec::RR, [], :style => :foo
95
- #
96
- def invoke(name=nil, *args)
97
- args.unshift(nil) if Array === args.first || NilClass === args.first
98
- task, args, opts, config = args
99
-
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
-
106
- iterator = proc do |_, task|
107
- unless current.include?(task.name)
108
- current << task.name
109
- task.run(instance, method_args)
110
- end
111
- end
112
-
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)
119
- end
120
- end
121
-
122
- # Invokes using shell padding.
123
- def invoke_with_padding(*args)
124
- with_padding { invoke(*args) }
125
- end
126
-
127
- protected
128
-
129
- # Configuration values that are shared between invocations.
130
- def _shared_configuration #:nodoc:
131
- { :invocations => @_invocations }
132
- end
133
-
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
142
- else
143
- object, task = self.class.prepare_for_invocation(nil, name)
144
- task ||= sent_task
145
- 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
- end
162
-
163
- # 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
167
-
168
- stored_args, stored_opts, stored_config = @_initializer
169
- args ||= stored_args.dup
170
- opts ||= stored_opts.dup
171
-
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
178
- end
179
- end
180
- end
@@ -1,4 +0,0 @@
1
- require 'thor/parser/argument'
2
- require 'thor/parser/arguments'
3
- require 'thor/parser/option'
4
- require 'thor/parser/options'
@@ -1,67 +0,0 @@
1
- class Thor
2
- class Argument #:nodoc:
3
- VALID_TYPES = [ :numeric, :hash, :array, :string ]
4
-
5
- attr_reader :name, :description, :required, :type, :default, :banner
6
- alias :human_name :name
7
-
8
- def initialize(name, description=nil, required=true, type=:string, default=nil, banner=nil)
9
- class_name = self.class.name.split("::").last
10
-
11
- raise ArgumentError, "#{class_name} name can't be nil." if name.nil?
12
- raise ArgumentError, "Type :#{type} is not valid for #{class_name.downcase}s." if type && !valid_type?(type)
13
-
14
- @name = name.to_s
15
- @description = description
16
- @required = required || false
17
- @type = (type || :string).to_sym
18
- @default = default
19
- @banner = banner || default_banner
20
-
21
- validate! # Trigger specific validations
22
- end
23
-
24
- def usage
25
- required? ? banner : "[#{banner}]"
26
- end
27
-
28
- def required?
29
- required
30
- end
31
-
32
- def show_default?
33
- case default
34
- when Array, String, Hash
35
- !default.empty?
36
- else
37
- default
38
- end
39
- end
40
-
41
- protected
42
-
43
- def validate!
44
- raise ArgumentError, "An argument cannot be required and have default value." if required? && !default.nil?
45
- end
46
-
47
- def valid_type?(type)
48
- VALID_TYPES.include?(type.to_sym)
49
- end
50
-
51
- def default_banner
52
- 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"
63
- end
64
- end
65
-
66
- end
67
- end
@@ -1,161 +0,0 @@
1
- class Thor
2
- class Arguments #:nodoc:
3
- NUMERIC = /(\d*\.\d+|\d+)/
4
-
5
- # Receives an array of args and returns two arrays, one with arguments
6
- # and one with switches.
7
- #
8
- def self.split(args)
9
- arguments = []
10
-
11
- args.each do |item|
12
- break if item =~ /^-/
13
- arguments << item
14
- end
15
-
16
- return arguments, args[Range.new(arguments.size, -1)]
17
- end
18
-
19
- def self.parse(*args)
20
- to_parse = args.pop
21
- new(*args).parse(to_parse)
22
- end
23
-
24
- # Takes an array of Thor::Argument objects.
25
- #
26
- def initialize(arguments=[])
27
- @assigns, @non_assigned_required = {}, []
28
- @switches = arguments
29
-
30
- arguments.each do |argument|
31
- if argument.default
32
- @assigns[argument.human_name] = argument.default
33
- elsif argument.required?
34
- @non_assigned_required << argument
35
- end
36
- end
37
- end
38
-
39
- def parse(args)
40
- @pile = args.dup
41
-
42
- @switches.each do |argument|
43
- break unless peek
44
- @non_assigned_required.delete(argument)
45
- @assigns[argument.human_name] = send(:"parse_#{argument.type}", argument.human_name)
46
- end
47
-
48
- check_requirement!
49
- @assigns
50
- end
51
-
52
- private
53
-
54
- def no_or_skip?(arg)
55
- arg =~ /^--(no|skip)-([-\w]+)$/
56
- $2
57
- end
58
-
59
- def last?
60
- @pile.empty?
61
- end
62
-
63
- def peek
64
- @pile.first
65
- end
66
-
67
- def shift
68
- @pile.shift
69
- end
70
-
71
- def unshift(arg)
72
- unless arg.kind_of?(Array)
73
- @pile.unshift(arg)
74
- else
75
- @pile = arg + @pile
76
- end
77
- end
78
-
79
- def current_is_value?
80
- peek && peek.to_s !~ /^-/
81
- end
82
-
83
- # Runs through the argument array getting strings that contains ":" and
84
- # mark it as a hash:
85
- #
86
- # [ "name:string", "age:integer" ]
87
- #
88
- # Becomes:
89
- #
90
- # { "name" => "string", "age" => "integer" }
91
- #
92
- def parse_hash(name)
93
- return shift if peek.is_a?(Hash)
94
- hash = {}
95
-
96
- while current_is_value? && peek.include?(?:)
97
- key, value = shift.split(':')
98
- hash[key] = value
99
- end
100
- hash
101
- end
102
-
103
- # Runs through the argument array getting all strings until no string is
104
- # found or a switch is found.
105
- #
106
- # ["a", "b", "c"]
107
- #
108
- # And returns it as an array:
109
- #
110
- # ["a", "b", "c"]
111
- #
112
- def parse_array(name)
113
- return shift if peek.is_a?(Array)
114
- array = []
115
-
116
- while current_is_value?
117
- array << shift
118
- end
119
- array
120
- end
121
-
122
- # Check if the peek is numeric format and return a Float or Integer.
123
- # Otherwise raises an error.
124
- #
125
- def parse_numeric(name)
126
- return shift if peek.is_a?(Numeric)
127
-
128
- unless peek =~ NUMERIC && $& == peek
129
- raise MalformattedArgumentError, "Expected numeric value for '#{name}'; got #{peek.inspect}"
130
- end
131
-
132
- $&.index('.') ? shift.to_f : shift.to_i
133
- end
134
-
135
- # Parse string:
136
- # for --string-arg, just return the current value in the pile
137
- # for --no-string-arg, nil
138
- #
139
- def parse_string(name)
140
- if no_or_skip?(name)
141
- nil
142
- else
143
- shift
144
- end
145
- end
146
-
147
- # Raises an error if @non_assigned_required array is not empty.
148
- #
149
- def check_requirement!
150
- unless @non_assigned_required.empty?
151
- names = @non_assigned_required.map do |o|
152
- o.respond_to?(:switch_name) ? o.switch_name : o.human_name
153
- end.join("', '")
154
-
155
- class_name = self.class.name.split('::').last.downcase
156
- raise RequiredArgumentMissingError, "No value provided for required #{class_name} '#{names}'"
157
- end
158
- end
159
-
160
- end
161
- end
@@ -1,128 +0,0 @@
1
- class Thor
2
- class Option < Argument #:nodoc:
3
- attr_reader :aliases, :group
4
-
5
- VALID_TYPES = [:boolean, :numeric, :hash, :array, :string]
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
11
- end
12
-
13
- # This parse quick options given as method_options. It makes several
14
- # assumptions, but you can be more specific using the option method.
15
- #
16
- # parse :foo => "bar"
17
- # #=> Option foo with default value bar
18
- #
19
- # parse [:foo, :baz] => "bar"
20
- # #=> Option foo with default value bar and alias :baz
21
- #
22
- # parse :foo => :required
23
- # #=> Required option foo without default value
24
- #
25
- # parse :foo => 2
26
- # #=> Option foo with default value 2 and type numeric
27
- #
28
- # parse :foo => :numeric
29
- # #=> Option foo without default value and type numeric
30
- #
31
- # parse :foo => true
32
- # #=> Option foo with default value true and type boolean
33
- #
34
- # The valid types are :boolean, :numeric, :hash, :array and :string. If none
35
- # is given a default type is assumed. This default type accepts arguments as
36
- # string (--foo=value) or booleans (just --foo).
37
- #
38
- # By default all options are optional, unless :required is given.
39
- #
40
- def self.parse(key, value)
41
- if key.is_a?(Array)
42
- name, *aliases = key
43
- else
44
- name, aliases = key, []
45
- end
46
-
47
- name = name.to_s
48
- default = value
49
-
50
- 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
65
- end
66
-
67
- self.new(name.to_s, nil, required, type, default, nil, nil, aliases)
68
- end
69
-
70
- def switch_name
71
- @switch_name ||= dasherized? ? name : dasherize(name)
72
- end
73
-
74
- def human_name
75
- @human_name ||= dasherized? ? undasherize(name) : name
76
- end
77
-
78
- def usage(padding=0)
79
- sample = if banner && !banner.to_s.empty?
80
- "#{switch_name}=#{banner}"
81
- else
82
- switch_name
83
- end
84
-
85
- sample = "[#{sample}]" unless required?
86
-
87
- if aliases.empty?
88
- (" " * padding) << sample
89
- else
90
- "#{aliases.join(', ')}, #{sample}"
91
- end
92
- end
93
-
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
103
- end
104
-
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
114
-
115
- def dasherized?
116
- name.index('-') == 0
117
- end
118
-
119
- def undasherize(str)
120
- str.sub(/^-{1,2}/, '')
121
- end
122
-
123
- def dasherize(str)
124
- (str.length > 1 ? "--" : "-") + str.gsub('_', '-')
125
- end
126
-
127
- end
128
- end