metaforce 1.0.0a → 1.0.0
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.
- data/.gitignore +1 -0
- data/README.md +34 -0
- data/bin/metaforce +14 -0
- data/examples/example.rb +10 -9
- data/lib/metaforce/cli.rb +124 -0
- data/lib/metaforce/job.rb +49 -25
- data/lib/metaforce/job/deploy.rb +4 -4
- data/lib/metaforce/job/retrieve.rb +2 -2
- data/lib/metaforce/metadata/client/crud.rb +2 -2
- data/lib/metaforce/metadata/client/file.rb +1 -1
- data/lib/metaforce/reporters.rb +2 -0
- data/lib/metaforce/reporters/base_reporter.rb +56 -0
- data/lib/metaforce/reporters/deploy_reporter.rb +69 -0
- data/lib/metaforce/reporters/retrieve_reporter.rb +11 -0
- data/lib/metaforce/version.rb +1 -1
- data/metaforce.gemspec +4 -1
- data/spec/lib/cli_spec.rb +40 -0
- data/spec/lib/job/deploy_spec.rb +16 -15
- data/spec/lib/job_spec.rb +18 -2
- data/spec/lib/reporters/base_reporter_spec.rb +79 -0
- data/spec/lib/reporters/deploy_reporter_spec.rb +124 -0
- data/spec/lib/reporters/retrieve_reporter_spec.rb +14 -0
- data/spec/spec_helper.rb +4 -1
- metadata +75 -13
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -125,6 +125,40 @@ client.send_email(
|
|
125
125
|
)
|
126
126
|
```
|
127
127
|
|
128
|
+
## Command-line
|
129
|
+
|
130
|
+
Metaforce also comes with a handy command line utility that can deploy and retrieve
|
131
|
+
code from Salesforce. It also allows you to watch a directory and deploy when
|
132
|
+
anything changes.
|
133
|
+
|
134
|
+
When you deploy, it will also run all tests and provide you with a report,
|
135
|
+
similar to rspec.
|
136
|
+
|
137
|
+
```bash
|
138
|
+
$ metaforce deploy ./src
|
139
|
+
Deploying: ./src
|
140
|
+
```
|
141
|
+
|
142
|
+
```bash
|
143
|
+
$ metaforce watch ./src
|
144
|
+
Watching: ./src
|
145
|
+
```
|
146
|
+
|
147
|
+
```bash
|
148
|
+
$ metaforce retrieve ./src
|
149
|
+
Retrieving: ./src/package.xml
|
150
|
+
|
151
|
+
$ metaforce retrieve ./src/package.xml ./other-location
|
152
|
+
Retrieving: ./src/package.xml
|
153
|
+
```
|
154
|
+
|
155
|
+
### .metaforce.yml
|
156
|
+
|
157
|
+
The metaforce command will pull it's configuration from a `.metaforce.yml`
|
158
|
+
file, if present. You can provide options for multiple environments, then use
|
159
|
+
the `-e` swtich on the command line to use an environment. See the
|
160
|
+
[examples](examples) directory for an example.
|
161
|
+
|
128
162
|
## Contributing
|
129
163
|
|
130
164
|
1. Fork it
|
data/bin/metaforce
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'rubygems'
|
3
|
+
require 'bundler/setup'
|
4
|
+
require 'metaforce'
|
5
|
+
|
6
|
+
begin
|
7
|
+
require 'metaforce/cli'
|
8
|
+
Metaforce::CLI.start
|
9
|
+
rescue Interrupt => e
|
10
|
+
puts "\nQuitting..."
|
11
|
+
exit 1
|
12
|
+
rescue SystemExit => e
|
13
|
+
exit e.status
|
14
|
+
end
|
data/examples/example.rb
CHANGED
@@ -11,18 +11,12 @@ client = Metaforce.new :username => ENV['USER'],
|
|
11
11
|
Metaforce::Job.disable_threading!
|
12
12
|
|
13
13
|
# Test sending an email.
|
14
|
-
print 'send email to: '
|
14
|
+
print 'send email to: '; email = STDIN.gets.chomp
|
15
15
|
client.send_email(
|
16
|
-
to_addresses: [
|
16
|
+
to_addresses: [email],
|
17
17
|
subject: 'Test',
|
18
18
|
plain_text_body: 'Test'
|
19
|
-
)
|
20
|
-
|
21
|
-
# Test deployment.
|
22
|
-
client.deploy('../spec/fixtures/payload.zip')
|
23
|
-
.on_complete { |job| puts "Deploy Completed: #{job.id}."}
|
24
|
-
.on_error { |job| puts "Deploy Failed: #{job.id}."}
|
25
|
-
.perform
|
19
|
+
) if email
|
26
20
|
|
27
21
|
# Test retrieve.
|
28
22
|
manifest = Metaforce::Manifest.new(:custom_object => ['Account'])
|
@@ -32,6 +26,13 @@ client.retrieve_unpackaged(manifest)
|
|
32
26
|
.extract_to('./tmp')
|
33
27
|
.perform
|
34
28
|
|
29
|
+
# Test deployment.
|
30
|
+
client.deploy('./tmp')
|
31
|
+
.on_complete { |job| puts "Deploy Completed: #{job.id}. #{job.result}"}
|
32
|
+
.on_error { |job| puts "Deploy Failed: #{job.id}."}
|
33
|
+
.on_poll { |job| puts "Deploy: Polled status for #{job.id}."}
|
34
|
+
.perform
|
35
|
+
|
35
36
|
# Test delete.
|
36
37
|
client.delete(:apex_page, 'TestPage')
|
37
38
|
.on_complete { |job| puts "Delete Completed: #{job.id}."}
|
@@ -0,0 +1,124 @@
|
|
1
|
+
require 'listen'
|
2
|
+
require 'thor'
|
3
|
+
require 'metaforce/reporters'
|
4
|
+
require 'metaforce/reporters'
|
5
|
+
|
6
|
+
Metaforce.configuration.log = false
|
7
|
+
Metaforce::Job.disable_threading!
|
8
|
+
|
9
|
+
module Metaforce
|
10
|
+
class CLI < Thor
|
11
|
+
CONFIG_FILE = '.metaforce.yml'
|
12
|
+
|
13
|
+
include Thor::Actions
|
14
|
+
|
15
|
+
class << self
|
16
|
+
def credential_options
|
17
|
+
method_option :username, :aliases => '-u', :desc => 'Username.'
|
18
|
+
method_option :password, :aliases => '-p', :desc => 'Password.'
|
19
|
+
method_option :security_token, :aliases => '-t', :desc => 'Security Token.'
|
20
|
+
method_option :environment, :aliases => '-e', :default => 'production', :desc => 'Environment to use from config file (if present).'
|
21
|
+
method_option :host, :aliases => '-h', :desc => 'Salesforce host to connect to.'
|
22
|
+
end
|
23
|
+
|
24
|
+
def deploy_options
|
25
|
+
method_option :deploy_options, :aliases => '-o', :type => :hash, :default => { :run_all_tests => true }, :desc => 'Deploy Options'
|
26
|
+
end
|
27
|
+
|
28
|
+
def retrieve_options
|
29
|
+
method_option :retrieve_options, :aliases => '-o', :type => :hash, :default => {}, :desc => 'Retrieve Options'
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
desc 'deploy <path>', 'Deploy <path> to the target organization.'
|
34
|
+
|
35
|
+
credential_options
|
36
|
+
deploy_options
|
37
|
+
|
38
|
+
def deploy(path)
|
39
|
+
say "Deploying: #{path} ", :cyan
|
40
|
+
say "#{options[:deploy_options].inspect}"
|
41
|
+
client(options).deploy(path, options[:deploy_options].symbolize_keys!)
|
42
|
+
.on_complete { |job| report job.result, :deploy }
|
43
|
+
.on_error(&error)
|
44
|
+
.on_poll(&polling)
|
45
|
+
.perform
|
46
|
+
end
|
47
|
+
|
48
|
+
desc 'retrieve <manifest> <path>', 'Retrieve the components specified in <manifest> (package.xml) to <path>.'
|
49
|
+
|
50
|
+
credential_options
|
51
|
+
retrieve_options
|
52
|
+
|
53
|
+
def retrieve(manifest, path=nil)
|
54
|
+
unless path
|
55
|
+
path = manifest
|
56
|
+
manifest = File.join(path, 'package.xml')
|
57
|
+
end
|
58
|
+
say "Retrieving: #{manifest} ", :cyan
|
59
|
+
say "#{options[:retrieve_options].inspect}"
|
60
|
+
client(options).retrieve_unpackaged(manifest, options[:retrieve_options].symbolize_keys!)
|
61
|
+
.extract_to(path)
|
62
|
+
.on_complete { |job| report(job.result, :retrieve) }
|
63
|
+
.on_complete { |job| say "Extracted: #{path}", :green }
|
64
|
+
.on_error(&error)
|
65
|
+
.on_poll(&polling)
|
66
|
+
.perform
|
67
|
+
end
|
68
|
+
|
69
|
+
desc 'watch <path>', 'Deploy <path> to the target organization whenever files are changed.'
|
70
|
+
|
71
|
+
credential_options
|
72
|
+
deploy_options
|
73
|
+
|
74
|
+
def watch(path)
|
75
|
+
say "Watching: #{path}"
|
76
|
+
@watching = true
|
77
|
+
Listen.to(path) { deploy path }
|
78
|
+
end
|
79
|
+
|
80
|
+
private
|
81
|
+
|
82
|
+
def report(results, type)
|
83
|
+
reporter = "Metaforce::Reporters::#{type.to_s.camelize}Reporter".constantize.new(results)
|
84
|
+
reporter.report
|
85
|
+
exit 1 if reporter.issues?
|
86
|
+
end
|
87
|
+
|
88
|
+
def exit(status)
|
89
|
+
super(status) if not watching?
|
90
|
+
end
|
91
|
+
|
92
|
+
def watching?
|
93
|
+
!!@watching
|
94
|
+
end
|
95
|
+
|
96
|
+
def error
|
97
|
+
proc { |job| say "Error: #{job.result.inspect}" }
|
98
|
+
end
|
99
|
+
|
100
|
+
def polling
|
101
|
+
proc { |job| say 'Polling ...', :cyan }
|
102
|
+
end
|
103
|
+
|
104
|
+
def client(options)
|
105
|
+
credentials = Thor::CoreExt::HashWithIndifferentAccess.new(config ? config[options[:environment]] : {})
|
106
|
+
credentials.merge!(options.slice(:username, :password, :security_token, :host))
|
107
|
+
credentials.tap do |credentials|
|
108
|
+
credentials[:username] ||= ask('username:')
|
109
|
+
credentials[:password] ||= ask('password:')
|
110
|
+
credentials[:security_token] ||= ask('security token:')
|
111
|
+
end
|
112
|
+
Metaforce.new credentials
|
113
|
+
end
|
114
|
+
|
115
|
+
def config
|
116
|
+
YAML.load(File.open(config_file)) if File.exists?(config_file)
|
117
|
+
end
|
118
|
+
|
119
|
+
def config_file
|
120
|
+
File.expand_path(CONFIG_FILE)
|
121
|
+
end
|
122
|
+
|
123
|
+
end
|
124
|
+
end
|
data/lib/metaforce/job.rb
CHANGED
@@ -3,6 +3,9 @@ require 'base64'
|
|
3
3
|
|
4
4
|
module Metaforce
|
5
5
|
class Job
|
6
|
+
DELAY_START = 1
|
7
|
+
DELAY_MULTIPLIER = 2
|
8
|
+
|
6
9
|
autoload :Deploy, 'metaforce/job/deploy'
|
7
10
|
autoload :Retrieve, 'metaforce/job/retrieve'
|
8
11
|
autoload :CRUD, 'metaforce/job/crud'
|
@@ -39,11 +42,18 @@ module Metaforce
|
|
39
42
|
self
|
40
43
|
end
|
41
44
|
|
42
|
-
# Public:
|
45
|
+
# Public: Utility method to determine if .perform has been called yet.
|
46
|
+
#
|
47
|
+
# Returns true if @id is set, false otherwise.
|
48
|
+
def started?
|
49
|
+
!!@id
|
50
|
+
end
|
51
|
+
|
52
|
+
# Public: Register a block to be called when an event occurs.
|
43
53
|
#
|
44
54
|
# Yields the job.
|
45
55
|
#
|
46
|
-
# &block - Proc or Lambda to be run when the
|
56
|
+
# &block - Proc or Lambda to be run when the event is triggered.
|
47
57
|
#
|
48
58
|
# Examples
|
49
59
|
#
|
@@ -51,28 +61,26 @@ module Metaforce
|
|
51
61
|
# puts "Job ##{job.id} completed!"
|
52
62
|
# end
|
53
63
|
#
|
54
|
-
# Returns self.
|
55
|
-
def on_complete(&block)
|
56
|
-
@_callbacks[:on_complete] << block
|
57
|
-
self
|
58
|
-
end
|
59
|
-
|
60
|
-
# Public: Register a block to be called when if the job fails.
|
61
|
-
#
|
62
|
-
# Yields the job.
|
63
|
-
#
|
64
|
-
# &block - Proc or Lambda to be run when the job fails.
|
65
|
-
#
|
66
|
-
# Examples
|
67
|
-
#
|
68
64
|
# job.on_error do |job|
|
69
|
-
# puts "Job
|
65
|
+
# puts "Job failed!"
|
66
|
+
# end
|
67
|
+
#
|
68
|
+
# job.on_poll do |job|
|
69
|
+
# puts "Polled status for #{job.id}"
|
70
70
|
# end
|
71
71
|
#
|
72
72
|
# Returns self.
|
73
|
-
|
74
|
-
|
75
|
-
|
73
|
+
#
|
74
|
+
# Signature
|
75
|
+
#
|
76
|
+
# on_complete(&block)
|
77
|
+
# on_error(&block)
|
78
|
+
# on_poll(&block)
|
79
|
+
%w[complete error poll].each do |type|
|
80
|
+
define_method :"on_#{type}" do |&block|
|
81
|
+
@_callbacks[:"on_#{type}"] << block
|
82
|
+
self
|
83
|
+
end
|
76
84
|
end
|
77
85
|
|
78
86
|
# Public: Queries the job status from the API.
|
@@ -84,7 +92,7 @@ module Metaforce
|
|
84
92
|
#
|
85
93
|
# Returns the AsyncResult (http://www.salesforce.com/us/developer/docs/api_meta/Content/meta_asyncresult.htm).
|
86
94
|
def status
|
87
|
-
client.status(id)
|
95
|
+
@status ||= client.status(id)
|
88
96
|
end
|
89
97
|
|
90
98
|
# Public: Returns true if the job has completed.
|
@@ -106,9 +114,9 @@ module Metaforce
|
|
106
114
|
# job.state
|
107
115
|
# # => 'Completed'
|
108
116
|
#
|
109
|
-
# Returns the state
|
117
|
+
# Returns the state of the job.
|
110
118
|
def state
|
111
|
-
|
119
|
+
status.state
|
112
120
|
end
|
113
121
|
|
114
122
|
# Public: Check if the job is in a given state.
|
@@ -140,7 +148,11 @@ module Metaforce
|
|
140
148
|
def disable_threading!
|
141
149
|
self.class_eval do
|
142
150
|
def start_heart_beat
|
151
|
+
delay = DELAY_START
|
143
152
|
loop do
|
153
|
+
@status = nil
|
154
|
+
wait (delay = delay * DELAY_MULTIPLIER)
|
155
|
+
trigger_poll_callbacks
|
144
156
|
trigger_callbacks && break if completed? || error?
|
145
157
|
end
|
146
158
|
end
|
@@ -157,14 +169,26 @@ module Metaforce
|
|
157
169
|
def start_heart_beat
|
158
170
|
Thread.abort_on_exception = true
|
159
171
|
@heart_beat ||= Thread.new do
|
160
|
-
delay =
|
172
|
+
delay = DELAY_START
|
161
173
|
loop do
|
162
|
-
|
174
|
+
@status = nil
|
175
|
+
wait (delay = delay * DELAY_MULTIPLIER)
|
176
|
+
trigger_poll_callbacks
|
163
177
|
trigger_callbacks && Thread.stop if completed? || error?
|
164
178
|
end
|
165
179
|
end
|
166
180
|
end
|
167
181
|
|
182
|
+
def trigger_poll_callbacks
|
183
|
+
@_callbacks[:on_poll].each do |block|
|
184
|
+
block.call(self)
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
def wait(duration)
|
189
|
+
sleep duration
|
190
|
+
end
|
191
|
+
|
168
192
|
def trigger_callbacks
|
169
193
|
@_callbacks[callback_type].each do |block|
|
170
194
|
block.call(self)
|
data/lib/metaforce/job/deploy.rb
CHANGED
@@ -37,7 +37,7 @@ module Metaforce
|
|
37
37
|
#
|
38
38
|
# Returns the DeployResult (http://www.salesforce.com/us/developer/docs/api_meta/Content/meta_deployresult.htm).
|
39
39
|
def result
|
40
|
-
client.status(id, :deploy)
|
40
|
+
@result ||= client.status(id, :deploy)
|
41
41
|
end
|
42
42
|
|
43
43
|
# Public: Returns true if the deploy was successful.
|
@@ -52,7 +52,9 @@ module Metaforce
|
|
52
52
|
result.success
|
53
53
|
end
|
54
54
|
|
55
|
-
|
55
|
+
private
|
56
|
+
|
57
|
+
# Internal: Base64 encodes the contents of the zip file.
|
56
58
|
#
|
57
59
|
# Examples
|
58
60
|
#
|
@@ -64,8 +66,6 @@ module Metaforce
|
|
64
66
|
Base64.encode64(File.open(file, 'rb').read)
|
65
67
|
end
|
66
68
|
|
67
|
-
private
|
68
|
-
|
69
69
|
# Internal: Returns the path to the zip file.
|
70
70
|
def file
|
71
71
|
File.file?(@path) ? @path : zip_file
|
@@ -37,7 +37,7 @@ module Metaforce
|
|
37
37
|
#
|
38
38
|
# Returns the RetrieveResult (http://www.salesforce.com/us/developer/docs/api_meta/Content/meta_retrieveresult.htm).
|
39
39
|
def result
|
40
|
-
client.status(id, :retrieve)
|
40
|
+
@result ||= client.status(id, :retrieve)
|
41
41
|
end
|
42
42
|
|
43
43
|
# Public: Decodes the content of the returned zip file.
|
@@ -63,7 +63,7 @@ module Metaforce
|
|
63
63
|
#
|
64
64
|
# Returns self.
|
65
65
|
def extract_to(destination)
|
66
|
-
return on_complete { |job| job.extract_to(destination) } unless
|
66
|
+
return on_complete { |job| job.extract_to(destination) } unless started?
|
67
67
|
Zip::ZipFile.open(tmp_zip_file) do |zip|
|
68
68
|
zip.each do |f|
|
69
69
|
path = File.join(destination, f.name)
|
@@ -36,7 +36,7 @@ module Metaforce
|
|
36
36
|
#
|
37
37
|
# Examples
|
38
38
|
#
|
39
|
-
# client._update(:apex_page, 'OldPage', :full_name => '
|
39
|
+
# client._update(:apex_page, 'OldPage', :full_name => 'TestPage', :label => 'Test page', :content => '<apex:page>hello world</apex:page>')
|
40
40
|
def _update(type, current_name, metadata={})
|
41
41
|
type = type.to_s.camelize
|
42
42
|
request :update do |soap|
|
@@ -70,7 +70,7 @@ module Metaforce
|
|
70
70
|
|
71
71
|
# Internal: Prepare metadata by base64 encoding any content keys.
|
72
72
|
def prepare(metadata)
|
73
|
-
metadata = [metadata]
|
73
|
+
metadata = Array[metadata].compact.flatten
|
74
74
|
metadata.each { |m| encode_content(m) }
|
75
75
|
metadata
|
76
76
|
end
|
@@ -97,7 +97,7 @@ module Metaforce
|
|
97
97
|
package = if manifest.is_a?(Metaforce::Manifest)
|
98
98
|
manifest
|
99
99
|
elsif manifest.is_a?(String)
|
100
|
-
Metaforce::Manifest.new(File.open(manifest).read)
|
100
|
+
Metaforce::Manifest.new(::File.open(manifest).read)
|
101
101
|
end
|
102
102
|
options = {
|
103
103
|
:api_version => Metaforce.configuration.api_version,
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'thor/shell/color'
|
2
|
+
|
3
|
+
module Metaforce
|
4
|
+
module Reporters
|
5
|
+
class BaseReporter < Thor::Shell::Color
|
6
|
+
def initialize(results)
|
7
|
+
super()
|
8
|
+
@results = results
|
9
|
+
end
|
10
|
+
|
11
|
+
def report
|
12
|
+
end
|
13
|
+
|
14
|
+
def report_problems
|
15
|
+
return unless problems?
|
16
|
+
say
|
17
|
+
say "Problems:", :red
|
18
|
+
say
|
19
|
+
problems.each { |message| problem(message) }
|
20
|
+
end
|
21
|
+
|
22
|
+
def problem(message)
|
23
|
+
say "#{short_padding}#{message.file_name}:#{message.line_number}", :red
|
24
|
+
say "#{long_padding}#{message.problem}"
|
25
|
+
say
|
26
|
+
end
|
27
|
+
|
28
|
+
def short_padding
|
29
|
+
' '
|
30
|
+
end
|
31
|
+
|
32
|
+
def long_padding
|
33
|
+
' '
|
34
|
+
end
|
35
|
+
|
36
|
+
def problems?
|
37
|
+
problems.any?
|
38
|
+
end
|
39
|
+
|
40
|
+
def issues?
|
41
|
+
problems?
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
def messages
|
47
|
+
@messages ||= Array[@results.messages].compact.flatten
|
48
|
+
end
|
49
|
+
|
50
|
+
def problems
|
51
|
+
messages.select { |message| message.problem }
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
require 'metaforce/reporters/base_reporter'
|
2
|
+
|
3
|
+
module Metaforce
|
4
|
+
module Reporters
|
5
|
+
class DeployReporter < BaseReporter
|
6
|
+
|
7
|
+
def report
|
8
|
+
report_problems
|
9
|
+
report_failed_tests
|
10
|
+
report_test_results if report_test_results?
|
11
|
+
end
|
12
|
+
|
13
|
+
def report_failed_tests
|
14
|
+
return unless failures?
|
15
|
+
say
|
16
|
+
say "Failures:", :red
|
17
|
+
say
|
18
|
+
failures.each { |failure| failed(failure) }
|
19
|
+
end
|
20
|
+
|
21
|
+
def report_test_results
|
22
|
+
say
|
23
|
+
say "Finished in #{total_time} seconds"
|
24
|
+
say "#{num_tests} tests, #{num_failures} failures", failures? ? :red : :green
|
25
|
+
end
|
26
|
+
|
27
|
+
def failed(failure)
|
28
|
+
say "#{short_padding}#{failure.stack_trace}:", :red
|
29
|
+
say "#{long_padding}#{failure.message}"
|
30
|
+
say
|
31
|
+
end
|
32
|
+
|
33
|
+
def failures?
|
34
|
+
num_failures > 0
|
35
|
+
end
|
36
|
+
|
37
|
+
def issues?
|
38
|
+
problems? || failures?
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def report_test_results?
|
44
|
+
@results.success && problems.empty?
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_results
|
48
|
+
@results.run_test_result
|
49
|
+
end
|
50
|
+
|
51
|
+
def failures
|
52
|
+
@failures ||= Array[test_results.failures].compact.flatten
|
53
|
+
end
|
54
|
+
|
55
|
+
def total_time
|
56
|
+
test_results.total_time
|
57
|
+
end
|
58
|
+
|
59
|
+
def num_tests
|
60
|
+
test_results.num_tests_run.to_i
|
61
|
+
end
|
62
|
+
|
63
|
+
def num_failures
|
64
|
+
test_results.num_failures.to_i
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
data/lib/metaforce/version.rb
CHANGED
data/metaforce.gemspec
CHANGED
@@ -24,7 +24,10 @@ EOL
|
|
24
24
|
s.add_dependency 'savon', '~> 1.2.0'
|
25
25
|
s.add_dependency 'rubyzip', '~> 0.9.9'
|
26
26
|
s.add_dependency 'activesupport'
|
27
|
-
s.add_dependency 'hashie'
|
27
|
+
s.add_dependency 'hashie', '~> 1.2.0'
|
28
|
+
s.add_dependency 'thor', '~> 0.16.0'
|
29
|
+
s.add_dependency 'listen', '~> 0.6.0'
|
30
|
+
s.add_dependency 'rb-fsevent', '~> 0.9.1'
|
28
31
|
|
29
32
|
s.add_development_dependency 'rake'
|
30
33
|
s.add_development_dependency 'rspec'
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'metaforce/cli'
|
3
|
+
|
4
|
+
describe Metaforce::CLI do
|
5
|
+
before do
|
6
|
+
Metaforce::Client.any_instance.stub(:deploy).and_return(double('deploy job').as_null_object)
|
7
|
+
Metaforce::Client.any_instance.stub(:retrieve).and_return(double('retrieve job').as_null_object)
|
8
|
+
subject.stub(:config).and_return(nil)
|
9
|
+
end
|
10
|
+
|
11
|
+
describe 'credentials' do
|
12
|
+
let(:output) { capture(:stdout) { subject.deploy('./path') } }
|
13
|
+
|
14
|
+
context 'when supplied credentials from the command line' do
|
15
|
+
let(:options) { indifferent_hash(:username => 'foo', :password => 'bar', :security_token => 'token', :deploy_options => {}) }
|
16
|
+
|
17
|
+
it 'uses supplied credentials from command line' do
|
18
|
+
subject.options = options
|
19
|
+
Metaforce.should_receive(:new).with(indifferent_hash(options).slice(:username, :password, :security_token)).and_call_original
|
20
|
+
output.should include('Deploying: ./path')
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
context 'when supplied credentials from config file' do
|
25
|
+
let(:options) { indifferent_hash(:environment => 'production', :deploy_options => {}) }
|
26
|
+
let(:config) { { 'username' => 'foo', 'password' => 'bar', 'security_token' => 'token' } }
|
27
|
+
|
28
|
+
it 'uses credentials from the config file' do
|
29
|
+
subject.options = options
|
30
|
+
subject.stub(:config).and_return('production' => config)
|
31
|
+
Metaforce.should_receive(:new).with(indifferent_hash(config)).and_call_original
|
32
|
+
output.should include('Deploying: ./path')
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def indifferent_hash(hash)
|
38
|
+
Thor::CoreExt::HashWithIndifferentAccess.new(hash)
|
39
|
+
end
|
40
|
+
end
|
data/spec/lib/job/deploy_spec.rb
CHANGED
@@ -5,28 +5,29 @@ describe Metaforce::Job::Deploy do
|
|
5
5
|
let(:path) { File.expand_path('../../../fixtures/payload.zip', __FILE__) }
|
6
6
|
let(:job) { described_class.new client, path }
|
7
7
|
|
8
|
-
describe '.
|
9
|
-
subject { job.
|
8
|
+
describe '.perform' do
|
9
|
+
subject { job.perform }
|
10
10
|
|
11
11
|
context 'when the path is a file' do
|
12
|
-
|
12
|
+
before do
|
13
|
+
client.should_receive(:_deploy).with(/^UEsDBA.*/, {}).and_return(Hashie::Mash.new(id: '1234'))
|
14
|
+
client.should_receive(:status).any_number_of_times.and_return(Hashie::Mash.new(done: true, state: 'Completed'))
|
15
|
+
end
|
16
|
+
|
17
|
+
it { should eq job }
|
18
|
+
its(:id) { should eq '1234' }
|
13
19
|
end
|
14
20
|
|
15
21
|
context 'when the path is a directory' do
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
22
|
+
before do
|
23
|
+
client.should_receive(:_deploy).with(/.*1stwAAAJI.*/, {}).and_return(Hashie::Mash.new(id: '1234'))
|
24
|
+
client.should_receive(:status).any_number_of_times.and_return(Hashie::Mash.new(done: true, state: 'Completed'))
|
25
|
+
end
|
20
26
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
client.should_receive(:status).any_number_of_times.and_return(Hashie::Mash.new(done: true, state: 'Completed'))
|
27
|
+
let(:path) { File.expand_path('../../../fixtures', __FILE__) }
|
28
|
+
it { should eq job }
|
29
|
+
its(:id) { should eq '1234' }
|
25
30
|
end
|
26
|
-
|
27
|
-
subject { job.perform }
|
28
|
-
it { should eq job }
|
29
|
-
its(:id) { should eq '1234' }
|
30
31
|
end
|
31
32
|
|
32
33
|
describe '.result' do
|
data/spec/lib/job_spec.rb
CHANGED
@@ -11,6 +11,22 @@ describe Metaforce::Job do
|
|
11
11
|
end
|
12
12
|
end
|
13
13
|
|
14
|
+
describe '.started?' do
|
15
|
+
subject { job.started? }
|
16
|
+
|
17
|
+
context 'when .perform has been called and an @id has been set' do
|
18
|
+
before do
|
19
|
+
job.instance_variable_set(:@id, '1234')
|
20
|
+
end
|
21
|
+
|
22
|
+
it { should be_true }
|
23
|
+
end
|
24
|
+
|
25
|
+
context 'when .perform has not been called and no @id has been set' do
|
26
|
+
it { should be_false }
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
14
30
|
describe '.on_complete' do
|
15
31
|
it 'allows the user to register an on_complete callback' do
|
16
32
|
client.should_receive(:status).any_number_of_times.and_return(Hashie::Mash.new(done: true, state: 'Completed'))
|
@@ -67,7 +83,7 @@ describe Metaforce::Job do
|
|
67
83
|
|
68
84
|
context 'when done' do
|
69
85
|
before do
|
70
|
-
client.should_receive(:status).
|
86
|
+
client.should_receive(:status).and_return(Hashie::Mash.new(done: true, state: 'Completed'))
|
71
87
|
end
|
72
88
|
|
73
89
|
it { should eq 'Completed' }
|
@@ -85,7 +101,7 @@ describe Metaforce::Job do
|
|
85
101
|
%w[Queued InProgress Completed Error].each do |state|
|
86
102
|
describe ".#{state.underscore}?" do
|
87
103
|
before do
|
88
|
-
client.should_receive(:status).
|
104
|
+
client.should_receive(:status).and_return(Hashie::Mash.new(done: true, state: state))
|
89
105
|
end
|
90
106
|
|
91
107
|
subject { job.send(:"#{state.underscore}?") }
|
@@ -0,0 +1,79 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'metaforce/reporters/base_reporter'
|
3
|
+
|
4
|
+
describe Metaforce::Reporters::BaseReporter do
|
5
|
+
let(:results) { Hashie::Mash.new(success: true) }
|
6
|
+
let(:reporter) { described_class.new results }
|
7
|
+
|
8
|
+
describe '.problem' do
|
9
|
+
context 'when a line_number is present' do
|
10
|
+
let(:problem) { Hashie::Mash.new(file_name: 'path/file', line_number: '10', problem: 'Foobar') }
|
11
|
+
|
12
|
+
it 'prints the problem' do
|
13
|
+
reporter.should_receive(:say).with(' path/file:10', :red)
|
14
|
+
reporter.should_receive(:say).with(' Foobar')
|
15
|
+
reporter.should_receive(:say).with
|
16
|
+
reporter.problem(problem)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
context 'when there is no line number present' do
|
21
|
+
let(:problem) { Hashie::Mash.new(file_name: 'path/file', problem: 'Foobar') }
|
22
|
+
|
23
|
+
it 'prints the problem' do
|
24
|
+
reporter.should_receive(:say).with(' path/file:', :red)
|
25
|
+
reporter.should_receive(:say).with(' Foobar')
|
26
|
+
reporter.should_receive(:say).with
|
27
|
+
reporter.problem(problem)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
describe '.report_problems' do
|
33
|
+
context 'when there are no problems' do
|
34
|
+
it 'does not report any problems' do
|
35
|
+
reporter.should_receive(:say).never
|
36
|
+
reporter.should_receive(:problem).never
|
37
|
+
reporter.report_problems
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
context 'when there are problems' do
|
42
|
+
let(:results) { Hashie::Mash.new(success: true, messages: { problem: 'Problem', file_name: 'path/file', line_number: '10' }) }
|
43
|
+
|
44
|
+
it 'prints each problem' do
|
45
|
+
reporter.should_receive(:say)
|
46
|
+
reporter.should_receive(:say).with('Problems:', :red)
|
47
|
+
reporter.should_receive(:say)
|
48
|
+
reporter.should_receive(:problem)
|
49
|
+
reporter.report_problems
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
describe '.problems?' do
|
55
|
+
subject { reporter.problems? }
|
56
|
+
|
57
|
+
context 'when there are no problems' do
|
58
|
+
it { should be_false }
|
59
|
+
end
|
60
|
+
|
61
|
+
context 'when there are problems' do
|
62
|
+
let(:results) { Hashie::Mash.new(success: true, messages: { problem: 'Problem', file_name: 'path/file', line_number: '10' }) }
|
63
|
+
it { should be_true }
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
describe '.issues?' do
|
68
|
+
subject { reporter.issues? }
|
69
|
+
|
70
|
+
context 'when there are no problems' do
|
71
|
+
it { should be_false }
|
72
|
+
end
|
73
|
+
|
74
|
+
context 'when there are problems' do
|
75
|
+
let(:results) { Hashie::Mash.new(success: true, messages: { problem: 'Problem', file_name: 'path/file', line_number: '10' }) }
|
76
|
+
it { should be_true }
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,124 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'metaforce/reporters/deploy_reporter'
|
3
|
+
|
4
|
+
describe Metaforce::Reporters::DeployReporter do
|
5
|
+
let(:results) { Hashie::Mash.new(success: true) }
|
6
|
+
let(:reporter) { described_class.new results }
|
7
|
+
|
8
|
+
describe '.failed' do
|
9
|
+
let(:failure) { Hashie::Mash.new(stack_trace: 'stack trace', message: 'message') }
|
10
|
+
|
11
|
+
it 'prints the failure' do
|
12
|
+
reporter.should_receive(:say).with(' stack trace:', :red)
|
13
|
+
reporter.should_receive(:say).with(' message')
|
14
|
+
reporter.should_receive(:say).with
|
15
|
+
reporter.failed(failure)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe '.report' do
|
20
|
+
context 'when the deploy was successfull' do
|
21
|
+
it 'should report everything' do
|
22
|
+
reporter.should_receive(:report_problems)
|
23
|
+
reporter.should_receive(:report_failed_tests)
|
24
|
+
reporter.should_receive(:report_test_results)
|
25
|
+
reporter.report
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
context 'when the deploy was not successful' do
|
30
|
+
let(:results) { Hashie::Mash.new(success: false) }
|
31
|
+
|
32
|
+
it 'should report everything except test results' do
|
33
|
+
reporter.should_receive(:report_problems)
|
34
|
+
reporter.should_receive(:report_failed_tests)
|
35
|
+
reporter.should_receive(:report_test_results).never
|
36
|
+
reporter.report
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
describe '.report_failed_tests' do
|
42
|
+
let(:results) { Hashie::Mash.new(success: true, run_test_result: { num_failures: num_failures, failures: failures }) }
|
43
|
+
|
44
|
+
context 'when there are no failed tests' do
|
45
|
+
let(:failures) { nil }
|
46
|
+
let(:num_failures) { '0' }
|
47
|
+
|
48
|
+
it 'does not report any failed tests' do
|
49
|
+
reporter.should_receive(:say).never
|
50
|
+
reporter.should_receive(:failed).never
|
51
|
+
reporter.report_failed_tests
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
context 'when there are failed tests' do
|
56
|
+
context 'passed as an object' do
|
57
|
+
let(:failures) { { stack_trace: 'stack trace', message: 'message' } }
|
58
|
+
let(:num_failures) { '1' }
|
59
|
+
|
60
|
+
it 'prints each failed tests' do
|
61
|
+
reporter.should_receive(:say)
|
62
|
+
reporter.should_receive(:say).with('Failures:', :red)
|
63
|
+
reporter.should_receive(:say)
|
64
|
+
reporter.should_receive(:failed)
|
65
|
+
reporter.report_failed_tests
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
context 'passed as an array' do
|
70
|
+
let(:failures) { [{ stack_trace: 'stack trace', message: 'message' }, { stack_trace: 'stack trace 2', message: 'message 2' }] }
|
71
|
+
let(:num_failures) { '2' }
|
72
|
+
|
73
|
+
it 'prints each failed tests' do
|
74
|
+
reporter.should_receive(:say)
|
75
|
+
reporter.should_receive(:say).with('Failures:', :red)
|
76
|
+
reporter.should_receive(:say)
|
77
|
+
reporter.should_receive(:failed).twice
|
78
|
+
reporter.report_failed_tests
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
describe '.report_test_results' do
|
85
|
+
let(:results) { Hashie::Mash.new(success: true, run_test_result: { total_time: '20', num_tests_run: '10', num_failures: num_failures }) }
|
86
|
+
|
87
|
+
context 'when there are failures' do
|
88
|
+
let(:num_failures) { '5' }
|
89
|
+
|
90
|
+
it 'prints the test results in red' do
|
91
|
+
reporter.should_receive(:say)
|
92
|
+
reporter.should_receive(:say).with("Finished in 20 seconds")
|
93
|
+
reporter.should_receive(:say).with("10 tests, 5 failures", :red)
|
94
|
+
reporter.report_test_results
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
context 'when there are no failures' do
|
99
|
+
let(:num_failures) { '0' }
|
100
|
+
|
101
|
+
it 'prints the test results in red' do
|
102
|
+
reporter.should_receive(:say)
|
103
|
+
reporter.should_receive(:say).with("Finished in 20 seconds")
|
104
|
+
reporter.should_receive(:say).with("10 tests, 0 failures", :green)
|
105
|
+
reporter.report_test_results
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
describe '.failures?' do
|
111
|
+
let(:results) { Hashie::Mash.new(success: true, run_test_result: { total_time: '20', num_tests_run: '10', num_failures: num_failures }) }
|
112
|
+
subject { reporter.failures? }
|
113
|
+
|
114
|
+
context 'when there are failures' do
|
115
|
+
let(:num_failures) { '5' }
|
116
|
+
it { should be_true }
|
117
|
+
end
|
118
|
+
|
119
|
+
context 'when there are no failures' do
|
120
|
+
let(:num_failures) { '0' }
|
121
|
+
it { should be_false }
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'metaforce/reporters/retrieve_reporter'
|
3
|
+
|
4
|
+
describe Metaforce::Reporters::RetrieveReporter do
|
5
|
+
let(:results) { Hashie::Mash.new(success: true) }
|
6
|
+
let(:reporter) { described_class.new results }
|
7
|
+
|
8
|
+
describe '.report' do
|
9
|
+
it 'reports the problems' do
|
10
|
+
reporter.should_receive(:report_problems)
|
11
|
+
reporter.report
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,14 +1,17 @@
|
|
1
1
|
require 'bundler'
|
2
2
|
Bundler.require :default, :development
|
3
3
|
require 'pp'
|
4
|
+
require 'rspec/mocks'
|
4
5
|
|
5
6
|
Dir['./spec/support/**/*.rb'].sort.each {|f| require f}
|
6
7
|
|
7
8
|
RSpec.configure do |config|
|
9
|
+
config.mock_with :rspec
|
8
10
|
config.include Savon::Spec::Macros
|
9
11
|
|
10
|
-
config.before(:
|
12
|
+
config.before(:each) do
|
11
13
|
Metaforce::Job.disable_threading!
|
14
|
+
Metaforce::Job.any_instance.stub(:wait)
|
12
15
|
end
|
13
16
|
end
|
14
17
|
|
metadata
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: metaforce
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
5
|
-
prerelease:
|
4
|
+
version: 1.0.0
|
5
|
+
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Eric J. Holmes
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2012-12-
|
13
|
+
date: 2012-12-23 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: savon
|
@@ -65,17 +65,65 @@ dependencies:
|
|
65
65
|
requirement: !ruby/object:Gem::Requirement
|
66
66
|
none: false
|
67
67
|
requirements:
|
68
|
-
- -
|
68
|
+
- - ~>
|
69
69
|
- !ruby/object:Gem::Version
|
70
|
-
version:
|
70
|
+
version: 1.2.0
|
71
71
|
type: :runtime
|
72
72
|
prerelease: false
|
73
73
|
version_requirements: !ruby/object:Gem::Requirement
|
74
74
|
none: false
|
75
75
|
requirements:
|
76
|
-
- -
|
76
|
+
- - ~>
|
77
77
|
- !ruby/object:Gem::Version
|
78
|
-
version:
|
78
|
+
version: 1.2.0
|
79
|
+
- !ruby/object:Gem::Dependency
|
80
|
+
name: thor
|
81
|
+
requirement: !ruby/object:Gem::Requirement
|
82
|
+
none: false
|
83
|
+
requirements:
|
84
|
+
- - ~>
|
85
|
+
- !ruby/object:Gem::Version
|
86
|
+
version: 0.16.0
|
87
|
+
type: :runtime
|
88
|
+
prerelease: false
|
89
|
+
version_requirements: !ruby/object:Gem::Requirement
|
90
|
+
none: false
|
91
|
+
requirements:
|
92
|
+
- - ~>
|
93
|
+
- !ruby/object:Gem::Version
|
94
|
+
version: 0.16.0
|
95
|
+
- !ruby/object:Gem::Dependency
|
96
|
+
name: listen
|
97
|
+
requirement: !ruby/object:Gem::Requirement
|
98
|
+
none: false
|
99
|
+
requirements:
|
100
|
+
- - ~>
|
101
|
+
- !ruby/object:Gem::Version
|
102
|
+
version: 0.6.0
|
103
|
+
type: :runtime
|
104
|
+
prerelease: false
|
105
|
+
version_requirements: !ruby/object:Gem::Requirement
|
106
|
+
none: false
|
107
|
+
requirements:
|
108
|
+
- - ~>
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: 0.6.0
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: rb-fsevent
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
none: false
|
115
|
+
requirements:
|
116
|
+
- - ~>
|
117
|
+
- !ruby/object:Gem::Version
|
118
|
+
version: 0.9.1
|
119
|
+
type: :runtime
|
120
|
+
prerelease: false
|
121
|
+
version_requirements: !ruby/object:Gem::Requirement
|
122
|
+
none: false
|
123
|
+
requirements:
|
124
|
+
- - ~>
|
125
|
+
- !ruby/object:Gem::Version
|
126
|
+
version: 0.9.1
|
79
127
|
- !ruby/object:Gem::Dependency
|
80
128
|
name: rake
|
81
129
|
requirement: !ruby/object:Gem::Requirement
|
@@ -144,7 +192,8 @@ description: A Ruby gem for interacting with the Salesforce Metadata API
|
|
144
192
|
email:
|
145
193
|
- eric@ejholmes.net
|
146
194
|
- Kevinp@madronasg.com
|
147
|
-
executables:
|
195
|
+
executables:
|
196
|
+
- metaforce
|
148
197
|
extensions: []
|
149
198
|
extra_rdoc_files: []
|
150
199
|
files:
|
@@ -155,9 +204,12 @@ files:
|
|
155
204
|
- LICENSE
|
156
205
|
- README.md
|
157
206
|
- Rakefile
|
207
|
+
- bin/metaforce
|
208
|
+
- examples/.metaforce.yml
|
158
209
|
- examples/example.rb
|
159
210
|
- lib/metaforce.rb
|
160
211
|
- lib/metaforce/abstract_client.rb
|
212
|
+
- lib/metaforce/cli.rb
|
161
213
|
- lib/metaforce/client.rb
|
162
214
|
- lib/metaforce/config.rb
|
163
215
|
- lib/metaforce/job.rb
|
@@ -169,6 +221,10 @@ files:
|
|
169
221
|
- lib/metaforce/metadata/client.rb
|
170
222
|
- lib/metaforce/metadata/client/crud.rb
|
171
223
|
- lib/metaforce/metadata/client/file.rb
|
224
|
+
- lib/metaforce/reporters.rb
|
225
|
+
- lib/metaforce/reporters/base_reporter.rb
|
226
|
+
- lib/metaforce/reporters/deploy_reporter.rb
|
227
|
+
- lib/metaforce/reporters/retrieve_reporter.rb
|
172
228
|
- lib/metaforce/services/client.rb
|
173
229
|
- lib/metaforce/version.rb
|
174
230
|
- metaforce.gemspec
|
@@ -192,6 +248,7 @@ files:
|
|
192
248
|
- spec/fixtures/requests/retrieve/in_progress.xml
|
193
249
|
- spec/fixtures/requests/send_email/success.xml
|
194
250
|
- spec/fixtures/requests/update/in_progress.xml
|
251
|
+
- spec/lib/cli_spec.rb
|
195
252
|
- spec/lib/client_spec.rb
|
196
253
|
- spec/lib/config_spec.rb
|
197
254
|
- spec/lib/job/deploy_spec.rb
|
@@ -201,6 +258,9 @@ files:
|
|
201
258
|
- spec/lib/manifest_spec.rb
|
202
259
|
- spec/lib/metadata/client_spec.rb
|
203
260
|
- spec/lib/metaforce_spec.rb
|
261
|
+
- spec/lib/reporters/base_reporter_spec.rb
|
262
|
+
- spec/lib/reporters/deploy_reporter_spec.rb
|
263
|
+
- spec/lib/reporters/retrieve_reporter_spec.rb
|
204
264
|
- spec/lib/services/client_spec.rb
|
205
265
|
- spec/spec_helper.rb
|
206
266
|
- spec/support/client.rb
|
@@ -223,15 +283,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
223
283
|
- - ! '>='
|
224
284
|
- !ruby/object:Gem::Version
|
225
285
|
version: '0'
|
226
|
-
segments:
|
227
|
-
- 0
|
228
|
-
hash: -4477921491118908816
|
229
286
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
230
287
|
none: false
|
231
288
|
requirements:
|
232
|
-
- - ! '
|
289
|
+
- - ! '>='
|
233
290
|
- !ruby/object:Gem::Version
|
234
|
-
version:
|
291
|
+
version: '0'
|
235
292
|
requirements: []
|
236
293
|
rubyforge_project: metaforce
|
237
294
|
rubygems_version: 1.8.23
|
@@ -259,6 +316,7 @@ test_files:
|
|
259
316
|
- spec/fixtures/requests/retrieve/in_progress.xml
|
260
317
|
- spec/fixtures/requests/send_email/success.xml
|
261
318
|
- spec/fixtures/requests/update/in_progress.xml
|
319
|
+
- spec/lib/cli_spec.rb
|
262
320
|
- spec/lib/client_spec.rb
|
263
321
|
- spec/lib/config_spec.rb
|
264
322
|
- spec/lib/job/deploy_spec.rb
|
@@ -268,6 +326,10 @@ test_files:
|
|
268
326
|
- spec/lib/manifest_spec.rb
|
269
327
|
- spec/lib/metadata/client_spec.rb
|
270
328
|
- spec/lib/metaforce_spec.rb
|
329
|
+
- spec/lib/reporters/base_reporter_spec.rb
|
330
|
+
- spec/lib/reporters/deploy_reporter_spec.rb
|
331
|
+
- spec/lib/reporters/retrieve_reporter_spec.rb
|
271
332
|
- spec/lib/services/client_spec.rb
|
272
333
|
- spec/spec_helper.rb
|
273
334
|
- spec/support/client.rb
|
335
|
+
has_rdoc:
|