metaforce 1.0.0a → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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:
|