metaforce 0.3.5 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -16,46 +16,24 @@ client = Metaforce::Metadata::Client.new :username => 'username',
16
16
  :password => 'password',
17
17
  :security_token => 'security token')
18
18
 
19
+ # Describe the metadata on the organization
19
20
  client.describe
20
21
  # => { :metadata_objects => [{ :child_xml_names => "CustomLabel", :directory_name => "labels" ... }
21
22
 
23
+ # List all custom objects
22
24
  client.list(:type => "CustomObject")
23
25
  # => [{ :created_by_id => "005U0000000EGpcIAG", :created_by_name => "Eric Holmes", ... }]
24
26
 
25
- deployment = client.deploy(File.dirname(__FILE__))
27
+ # Deploy metadata to the organization
28
+ deployment = client.deploy(File.expand_path('path/to/src'))
26
29
  # => #<Metaforce::Transaction:0x00000102779bf8 @id="04sU0000000WNWoIAO" @type=:deploy>
27
30
 
28
- deployment.done?
29
- # => false
30
-
31
- deployment.result(:wait_until_done => true)
31
+ # Get the result
32
+ deployment.result
32
33
  # => { :id => "04sU0000000WNWoIAO", :messages => [{ :changed => true ... :success => true }
33
- ```
34
-
35
- ## DSL
36
- Metaforce includes a lightweight DSL to make deployments and retrieve's easier.
37
-
38
- ```ruby
39
- require "metaforce/dsl"
40
- include Metaforce::DSL::Metadata
41
-
42
- login :username => 'username', :password => 'password', :security_token => 'security token' do
43
34
 
44
- deploy File.dirname(__FILE__) do |result|
45
- puts "Successful deployment!"
46
- puts result
47
- end
48
-
49
- retrieve File.expand_path("../src/package.xml", __FILE__) |result, zip|
50
- puts "Successful retrieve!"
51
- puts result
52
- File.open("retrieve.zip", "wb") do |file|
53
- file.write(zip)
54
- end
55
- end
56
-
57
- retrieve File.expand_path("../src/package.xml", __FILE__), :to => "directory"
58
- end
35
+ # Retrieve the metadata components specified in package.xml and unzip to the "retrieved" directory
36
+ client.retrieve(File.expand_path('path/to/package.xml')).to('retrieved')
59
37
  ```
60
38
 
61
39
  ## Roadmap
@@ -67,8 +45,6 @@ need to be done.
67
45
  * Implement CRUD based calls <http://www.salesforce.com/us/developer/docs/api_meta/Content/meta_crud_based_calls_intro.htm>.
68
46
  * Implement some helper methods for diffing metadata.
69
47
  * Ability to deploy directly from a git repository.
70
- * <del>Implement .retrieve for retrieving metadata.</del>
71
- * <del>Implement a DSL.</del>
72
48
  * And some other stuff that I haven't quite thought of yet...
73
49
 
74
50
  ## Contributing
@@ -77,6 +53,11 @@ feature on a new branch, then send me a pull request with a detailed
77
53
  description. Please provide applicable rspec specs.
78
54
 
79
55
  ## Version History
56
+ **0.4.0** (March 2, 2012)
57
+
58
+ * Various bug fixes and improvements.
59
+ * Removed DSL to focus on core functionality.
60
+
80
61
  **0.3.5** (February 11, 2012)
81
62
 
82
63
  * Allow rake tasks to get credentials from a metaforce.yml file.
data/Rakefile CHANGED
@@ -1,6 +1,18 @@
1
1
  require "bundler/gem_tasks"
2
2
 
3
+ task :default => :spec
4
+
5
+ desc "Run rspec specs"
6
+ task :spec do
7
+ sh "bundle exec rspec spec"
8
+ end
9
+
3
10
  desc "Start an irb session"
4
11
  task :console do
5
12
  sh "irb -I lib -r metaforce"
6
13
  end
14
+
15
+ desc "Build and publish gem on rubygems.org"
16
+ task :publish do
17
+ sh "gem build metaforce.gemspec && gem push metaforce-*.gem"
18
+ end
@@ -43,7 +43,17 @@ module Metaforce
43
43
  # Defaults to false.
44
44
  attr_accessor :test
45
45
  # Causes Metaforce::Transaction.result to loop until the transaction is
46
- # complete. Defaults to false.
46
+ # complete. Defaults to true.
47
+ #
48
+ # If you want to do custom polling, set this to false.
49
+ #
50
+ # == Example
51
+ #
52
+ # Metaforce.configuration.wait_until_done = false;
53
+ #
54
+ # deploy = client.deploy File.expand_path("myeclipseproj")
55
+ # begin; while !deploy.done?
56
+ # deploy.result
47
57
  attr_accessor :wait_until_done
48
58
 
49
59
  def initialize
@@ -51,7 +61,7 @@ module Metaforce
51
61
  HTTPI.log = false
52
62
  @api_version = "23.0"
53
63
  @test = false
54
- @wait_until_done = false
64
+ @wait_until_done = true
55
65
  end
56
66
 
57
67
  def logger
@@ -0,0 +1,3 @@
1
+ module Metaforce
2
+ class SalesforceError < StandardError; end
3
+ end
@@ -2,13 +2,11 @@ require 'metaforce/manifest'
2
2
  require 'savon'
3
3
  require 'zip/zip'
4
4
  require 'base64'
5
- require 'ostruct'
5
+ require 'tmpdir'
6
6
 
7
7
  module Metaforce
8
8
  module Metadata
9
9
  class Client
10
- DEPLOY_ZIP = 'deploy.zip' # :nodoc:
11
- RETRIEVE_ZIP = 'retrieve.zip' # :nodoc:
12
10
 
13
11
  # Performs a login and sets the session_id and metadata_server_url.
14
12
  #
@@ -45,9 +43,7 @@ module Metaforce
45
43
  # client.list([{ :type => "CustomObject" }, { :type => "ApexComponent" }])
46
44
  # #=> ["ContractContactRole", "Solution", "Invoice_Statements__c", ... ]
47
45
  def list(queries=[])
48
- unless queries.is_a?(Array)
49
- queries = [ queries ]
50
- end
46
+ queries = [ queries ] unless queries.is_a?(Array)
51
47
  response = @client.request(:list_metadata) do |soap|
52
48
  soap.header = @header
53
49
  soap.body = {
@@ -127,8 +123,12 @@ module Metaforce
127
123
  self.status(id)[:done] || false
128
124
  end
129
125
 
130
- # Deploys +dir+ to the organisation.
126
+ # Deploys +path+ to the organisation. +path+ can either be a path to
127
+ # a directory or a path to a zip file.
128
+ #
129
+ # +options+ can contain any of the following keys:
131
130
  #
131
+ # +options+:
132
132
  # See http://www.salesforce.com/us/developer/docs/api_meta/Content/meta_deploy.htm#deploy_options
133
133
  # for a list of _deploy_options_. Options should be convereted from
134
134
  # camelCase to an :underscored_symbol.
@@ -143,12 +143,11 @@ module Metaforce
143
143
  #
144
144
  # deploy.status[:state]
145
145
  # #=> "Completed"
146
- def deploy(dir, deploy_options={})
147
- if dir.is_a?(String)
148
- filename = File.join(File.dirname(dir), DEPLOY_ZIP)
149
- zip_contents = create_deploy_file(filename, dir)
150
- elsif dir.is_a?(File)
151
- zip_contents = Base64.encode64(dir.read)
146
+ def deploy(path, options={})
147
+ if path.is_a?(String)
148
+ zip_contents = create_deploy_file(path)
149
+ elsif path.is_a?(File)
150
+ zip_contents = Base64.encode64(path.read)
152
151
  end
153
152
 
154
153
  Metaforce.log('Executing deploy')
@@ -157,7 +156,7 @@ module Metaforce
157
156
  soap.header = @header
158
157
  soap.body = {
159
158
  :zip_file => zip_contents,
160
- :deploy_options => deploy_options
159
+ :deploy_options => options[:options] || {}
161
160
  }
162
161
  end
163
162
  Transaction.deployment self, response[:deploy_response][:result][:id]
@@ -167,56 +166,56 @@ module Metaforce
167
166
  #
168
167
  # See http://www.salesforce.com/us/developer/docs/api_meta/Content/meta_retrieve_request.htm
169
168
  # for a list of _retrieve_request_ options. Options should be convereted from
170
- # camelCase to an :underscored_symbol.
171
- def retrieve(retrieve_request={})
169
+ # camelCase to an :underscored_symbol. _retrieve_request_ options should
170
+ # be specified under the +:options+ key in options.
171
+ def retrieve(options={})
172
172
  Metaforce.log('Executing retrieve')
173
173
 
174
174
  response = @client.request(:retrieve) do |soap|
175
175
  soap.header = @header
176
176
  soap.body = {
177
- :retrieve_request => retrieve_request
177
+ :retrieve_request => options[:options] || {}
178
178
  }
179
179
  end
180
180
  Transaction.retrieval self, response[:retrieve_response][:result][:id]
181
181
  end
182
182
 
183
- # Retrieves files specified in the manifest file (package.xml). Specificy any extra +retrieve_request+ options in +extra+.
183
+ # Retrieves files specified in the manifest file (package.xml). Specificy any extra options in +options[:options]+.
184
184
  #
185
185
  # == Examples
186
186
  #
187
187
  # retrieve = client.retrieve_unpackaged File.expand_path("spec/fixtures/sample/src/package.xml")
188
188
  # #=> #<Metaforce::Transaction:0x1159bd0 @id='04sU0000000Wx6KIAS' @type=:retrieve>
189
- def retrieve_unpackaged(manifest, extra=nil)
189
+ def retrieve_unpackaged(manifest, options={})
190
190
  if manifest.is_a?(Metaforce::Manifest)
191
191
  package = manifest.to_package
192
192
  elsif manifest.is_a?(String)
193
193
  package = Metaforce::Manifest.new(File.open(manifest).read).to_package
194
194
  end
195
- retrieve_request = {
195
+ options[:options] = {
196
196
  :api_version => Metaforce.configuration.api_version,
197
197
  :single_package => true,
198
198
  :unpackaged => {
199
199
  :types => package
200
200
  }
201
- }
202
- retrieve_request.merge!(extra) if extra.is_a?(Hash)
203
- retrieve(retrieve_request)
201
+ }.merge(options[:options] || {})
202
+ retrieve(options)
204
203
  end
205
204
 
206
205
  private
207
206
 
208
207
  # Creates the deploy file, reads in the contents and returns the base64
209
208
  # encoded data
210
- def create_deploy_file(filename, dir)
211
- File.delete(filename) if File.exists?(filename)
212
- Zip::ZipFile.open(filename, Zip::ZipFile::CREATE) do |zip|
213
- Dir["#{dir}/**/**"].each do |file|
214
- zip.add(file.sub(dir + '/', ''), file)
209
+ def create_deploy_file(dir)
210
+ Dir.mktmpdir do |path|
211
+ path = File.join path, 'deploy.zip'
212
+ Zip::ZipFile.open(path, Zip::ZipFile::CREATE) do |zip|
213
+ Dir["#{dir}/**/**"].each do |file|
214
+ zip.add(file.sub("#{File.dirname(dir)}/", ''), file)
215
+ end
215
216
  end
217
+ Base64.encode64(File.open(path, "rb").read)
216
218
  end
217
- contents = Base64.encode64(File.open(filename, "rb").read)
218
- File.delete(filename)
219
- contents
220
219
  end
221
220
 
222
221
  end
@@ -13,6 +13,7 @@ module Metaforce
13
13
  @client = client
14
14
  @id = id
15
15
  @type = type
16
+ wait_until_done if Metaforce.configuration.wait_until_done
16
17
  end
17
18
 
18
19
  # Creates a new transaction and sets type to +:deploy+.
@@ -41,11 +42,11 @@ module Metaforce
41
42
  # Returns the decoded content of the returned zip file.
42
43
  def zip_file
43
44
  raise 'Request was not a retrieve.' unless @type == :retrieve
44
- Base64.decode64(@result[:zip_file])
45
+ Base64.decode64(result[:zip_file])
45
46
  end
46
47
 
47
48
  # Unzips the returned zip file to +destination+.
48
- def unzip(destination)
49
+ def to(destination)
49
50
  zip = zip_file
50
51
  file = Tempfile.new('retrieve')
51
52
  file.write(zip)
@@ -59,13 +60,13 @@ module Metaforce
59
60
  zip.extract(f, path) { true }
60
61
  end
61
62
  end
63
+ self
62
64
  end
63
65
 
64
66
  # Returns the deploy or retrieve result
65
67
  def result(options={})
66
- self.wait_until_done if (options[:wait_until_done] || Metaforce.configuration.wait_until_done)
67
- raise 'Request has not completed.' unless @done
68
68
  @result = @client.status(@id, @type) if @result.nil?
69
+ raise SalesforceError, @result[:message] if @result[:state] == "Error"
69
70
  @result
70
71
  end
71
72
 
@@ -0,0 +1,35 @@
1
+ require 'metaforce'
2
+ require 'term/ansicolor'
3
+ require 'rake'
4
+ require 'rake/tasklib'
5
+ include Term::ANSIColor
6
+
7
+ module Metaforce
8
+ module Rake
9
+
10
+ class DeployTask < ::Rake::TaskLib
11
+ attr_accessor :name
12
+
13
+ # The directory to deploy
14
+ attr_accessor :directory
15
+
16
+ def initialize(name = 'metaforce:deploy')
17
+ @name = name
18
+ @directory = File.expand_path('src')
19
+ yield self if block_given?
20
+ define
21
+ end
22
+
23
+ def define
24
+ desc "Deploy metadata"
25
+ task @name do
26
+ client = Metaforce::Rake.client
27
+ d = client.deploy(@directory)
28
+ puts green "Deployed #{@directory} successfully" if d.result[:success]
29
+ end
30
+ end
31
+
32
+ end
33
+
34
+ end
35
+ end
@@ -0,0 +1,39 @@
1
+ require 'metaforce'
2
+ require 'term/ansicolor'
3
+ require 'rake'
4
+ require 'rake/tasklib'
5
+ include Term::ANSIColor
6
+
7
+ module Metaforce
8
+ module Rake
9
+
10
+ class RetrieveTask < ::Rake::TaskLib
11
+ attr_accessor :name
12
+
13
+ # Path to the manifest file
14
+ attr_accessor :manifest
15
+
16
+ # The directory to unzip the retrieved files to
17
+ attr_accessor :directory
18
+
19
+ def initialize(name = 'metaforce:retrieve')
20
+ @name = name
21
+ @manifest = File.expand_path('src/package.xml')
22
+ @directory = File.expand_path('retrieved')
23
+ yield self if block_given?
24
+ define
25
+ end
26
+
27
+ def define
28
+ desc "Retrieve metadata"
29
+ task @name do
30
+ client = Metaforce::Rake.client
31
+ r = client.retrieve_unpackaged(@manifest).to(@directory)
32
+ puts green "Files retrieved sucessfully to #{@directory}"
33
+ end
34
+ end
35
+
36
+ end
37
+
38
+ end
39
+ end
@@ -0,0 +1,62 @@
1
+ require 'metaforce'
2
+ require 'term/ansicolor'
3
+ require 'rake'
4
+ require 'rake/tasklib'
5
+ include Term::ANSIColor
6
+
7
+ module Metaforce
8
+ module Rake
9
+
10
+ class TestsTask < ::Rake::TaskLib
11
+ attr_accessor :name
12
+
13
+ # The directory to deploy
14
+ attr_accessor :directory
15
+
16
+ def initialize(name = 'metaforce:tests:ci')
17
+ @name = name
18
+ @directory = File.expand_path('src')
19
+ yield self if block_given?
20
+ define
21
+ end
22
+
23
+ def define
24
+ desc "Deploy metadata, run all tests, then undeploy"
25
+ task @name do
26
+ ENV['env'] = ENV['env'] || 'ci'
27
+ client = Metaforce::Rake.client
28
+ Metaforce.log = false
29
+ result = client.deploy(@directory, :options => { :run_all_tests => true }).result
30
+ failures = result[:run_test_result][:failures]
31
+
32
+ if failures
33
+ failures = [failures] unless failures.is_a?(Array)
34
+ puts "Failures:"
35
+ failures.each_with_index do |failure, index|
36
+ index = index + 1
37
+ puts
38
+ puts "\t#{index}) #{failure[:method_name]}"
39
+ puts red "\t #{failure[:message]}"
40
+ puts
41
+ puts magenta "\t ##{failure[:stack_trace]}"
42
+ puts
43
+ end
44
+ end
45
+
46
+ color = failures ? :red : :green
47
+ puts "Finished in #{Float(result[:run_test_result][:total_time]) / 100} seconds"
48
+ puts send(color, "#{result[:run_test_result][:num_tests_run]} tests, #{result[:run_test_result][:num_failures]} failures")
49
+
50
+ if failures
51
+ puts "\nFailed tests:\n"
52
+ failures.each do |failure|
53
+ puts "#{red failure[:stack_trace]} #{magenta "# #{failure[:method_name]}"}"
54
+ end
55
+ end
56
+
57
+ abort if failures
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,42 @@
1
+ require 'yaml'
2
+ require 'metaforce/rake/deploy'
3
+ require 'metaforce/rake/retrieve'
4
+ require 'metaforce/rake/tests'
5
+
6
+ module Metaforce
7
+ module Rake
8
+
9
+ class << self
10
+ CONFIG_FILE = 'metaforce.yml'
11
+
12
+ # Loads the config and creates a client
13
+ def client
14
+ load_config
15
+ Metaforce::Metadata::Client.new :username => @username,
16
+ :password => @password,
17
+ :security_token => @security_token
18
+ end
19
+
20
+ # Loads configuration settings from metaforce.yml
21
+ def load_config
22
+ if File.exists?(CONFIG_FILE)
23
+ config = YAML.load_file(CONFIG_FILE)
24
+ env = ENV['env'] || 'default'
25
+ config = config.has_key?(env) ? config[env] : config
26
+ @username = config["username"]
27
+ @password = config["password"]
28
+ @security_token = config["security_token"] || ''
29
+ @test = config["test"] || false
30
+ @log = config["log"] || true
31
+ Metaforce.log = @log
32
+ Metaforce.configuration.test = @test
33
+ else
34
+ print "username: "; @username = STDIN.gets.chomp
35
+ print "password: "; @password = STDIN.gets.chomp
36
+ print "security token: "; @security_token = STDIN.gets.chomp
37
+ end
38
+ end
39
+
40
+ end
41
+ end
42
+ end
@@ -4,6 +4,7 @@ metadata using Rake and Metaforce. The following rake tasks are provided:
4
4
 
5
5
  * metaforce:deploy
6
6
  * metaforce:retrieve
7
+ * metaforce:tests:ci
7
8
 
8
9
  You can include the rake tasks by adding the following to your Rakefile:
9
10
 
@@ -51,7 +52,11 @@ This would deploy using the `sandbox` environment:
51
52
 
52
53
  `rake metaforce:deploy env="sandbox"`
53
54
 
54
- This would retrieve code using the `production` environment and would unzip the
55
- contents to "production\_code" rather than the default of "src".
55
+ ## Continuous Integration
56
+ The `metaforce:tests:ci` task is provided to make continuous integration with
57
+ something like [Jenkins](http://jenkins-ci.org) easier.
56
58
 
57
- `rake metaforce:retrieve env="production" dir="production_code"`
59
+ By default, the `metaforce:tests:ci` task will use the `ci` environment in
60
+ metaforce.yml, so you should set that up before you use this task.
61
+
62
+ The task will deploy the metadata and run all tests.
@@ -1,45 +1,5 @@
1
- namespace :metaforce do
2
- Metaforce.log = true
1
+ require 'metaforce/rake'
3
2
 
4
- task :login do
5
- if File.exists?('metaforce.yml')
6
- require 'yaml'
7
- config = YAML.load_file('metaforce.yml')
8
- env = ENV['env'] || 'default'
9
- root = config.has_key?(env) ? config[env] : config
10
- username = root["username"]
11
- password = root["password"]
12
- security_token = root["security_token"] || ''
13
- test = root["test"] || false
14
- Metaforce.configuration.test = test
15
- else
16
- print "username: "; username = STDIN.gets.chomp
17
- print "password: "; password = STDIN.gets.chomp
18
- print "security token: "; security_token = STDIN.gets.chomp
19
- end
20
- @client = Metaforce::Metadata::Client.new :username => username,
21
- :password => password,
22
- :security_token => security_token
23
- end
24
-
25
- desc "Deploy current directory to the organization"
26
- task :deploy => :login do
27
- deployment = @client.deploy File.dirname(__FILE__)
28
- result = deployment.result(:wait_until_done => true)
29
- if result[:success]
30
- puts "Successfully deployed metadata."
31
- else
32
- puts "An error occurred."
33
- end
34
- end
35
-
36
- desc "Retrieve metadata from the organization to src directory"
37
- task :retrieve => :login do
38
- dir = ENV['dir'] || 'src'
39
- retrieval = @client.retrieve_unpackaged(File.expand_path('src/package.xml'))
40
- result = retrieval.result(:wait_until_done => true)
41
- retrieval.unzip(File.expand_path(dir))
42
- puts "Successfully retrieved metadata to '#{dir}'."
43
- end
44
-
45
- end
3
+ Metaforce::Rake::DeployTask.new
4
+ Metaforce::Rake::RetrieveTask.new
5
+ Metaforce::Rake::TestsTask.new
@@ -1,3 +1,3 @@
1
1
  module Metaforce
2
- VERSION = "0.3.5"
2
+ VERSION = "0.4.0"
3
3
  end
data/lib/metaforce.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  require 'metaforce/version'
2
2
  require 'metaforce/config'
3
+ require 'metaforce/error'
3
4
  require 'metaforce/manifest'
4
5
  require 'metaforce/services'
5
6
  require 'metaforce/metadata'
data/metaforce.gemspec CHANGED
@@ -21,6 +21,7 @@ Gem::Specification.new do |s|
21
21
  s.add_dependency "nokogiri", "~> 1.5.0"
22
22
  s.add_dependency "savon", "~> 0.9.7"
23
23
  s.add_dependency "rubyzip", "~> 0.9.5"
24
+ s.add_dependency "term-ansicolor"
24
25
 
25
26
  s.add_development_dependency "rake"
26
27
  s.add_development_dependency "rspec"
@@ -1,8 +1,2 @@
1
- begin
2
- require 'metaforce'
3
- load 'metaforce/tasks/metaforce.rake'
4
- rescue LoadError
5
- task :metaforce do
6
- puts "Couldn't load metaforce tasks"
7
- end
8
- end
1
+ require 'metaforce/rake'
2
+ load 'metaforce/tasks/metaforce.rake'
@@ -129,6 +129,7 @@ describe Metaforce::Metadata::Client do
129
129
 
130
130
  it "deploys the directory and returns a transaction" do
131
131
  savon.expects(:deploy).with(:zip_file => '', :deploy_options => {}).returns(:in_progress)
132
+ savon.expects(:check_status).with(:ids => ['04sU0000000WNWoIAO']).returns(:done);
132
133
  deployment = client.deploy(File.expand_path('../../../fixtures/sample', __FILE__))
133
134
  deployment.should be_a(Metaforce::Transaction)
134
135
  deployment.id.should eq("04sU0000000WNWoIAO")
@@ -138,8 +139,9 @@ describe Metaforce::Metadata::Client do
138
139
 
139
140
  it "allows deploy options to be configured via a hash" do
140
141
  savon.expects(:deploy).with(:zip_file => '', :deploy_options => { :run_all_tests => true }).returns(:in_progress)
142
+ savon.expects(:check_status).with(:ids => ['04sU0000000WNWoIAO']).returns(:done);
141
143
  expect {
142
- client.deploy('', { :run_all_tests => true })
144
+ client.deploy('', :options => { :run_all_tests => true })
143
145
  }.to_not raise_error
144
146
  end
145
147
 
@@ -188,11 +190,12 @@ describe Metaforce::Metadata::Client do
188
190
  context "when given extra retrieve options" do
189
191
  before(:each) do
190
192
  savon.expects(:retrieve).with(:retrieve_request => { :api_version => Metaforce.configuration.api_version, :single_package => true, :unpackaged => { :types => manifest.to_package }, :extra => true }).returns(:in_progress)
193
+ savon.expects(:check_status).with(:ids => ['04sU0000000WkdIIAS']).returns(:done);
191
194
  end
192
195
 
193
196
  it "merges the options" do
194
197
  expect {
195
- retrieval = client.retrieve_unpackaged(File.expand_path('../../../fixtures/sample/src/package.xml', __FILE__), { :extra => true })
198
+ retrieval = client.retrieve_unpackaged(File.expand_path('../../../fixtures/sample/src/package.xml', __FILE__), :options => { :extra => true })
196
199
  }.to_not raise_error
197
200
  end
198
201
 
@@ -15,15 +15,15 @@ describe Metaforce::Transaction do
15
15
 
16
16
  it "allows you to check if the transaction has completed" do
17
17
  savon.expects(:deploy).with(:zip_file => '', :deploy_options => {}).returns(:in_progress)
18
- deployment = client.deploy(File.expand_path('../../../fixtures/sample', __FILE__))
19
18
  savon.expects(:check_status).with(:ids => [ "04sU0000000WNWoIAO" ]).returns(:done)
19
+ deployment = client.deploy(File.expand_path('../../../fixtures/sample', __FILE__))
20
20
  deployment.done?.should eq(true)
21
21
  end
22
22
 
23
23
  it "doesn't send a request if it has already completed" do
24
24
  savon.expects(:deploy).with(:zip_file => '', :deploy_options => {}).returns(:in_progress)
25
- deployment = client.deploy(File.expand_path('../../../fixtures/sample', __FILE__))
26
25
  savon.expects(:check_status).with(:ids => [ "04sU0000000WNWoIAO" ]).returns(:done)
26
+ deployment = client.deploy(File.expand_path('../../../fixtures/sample', __FILE__))
27
27
  deployment.done?.should eq(true)
28
28
  expect { deployment.done?.should eq(true) }.to_not raise_error
29
29
  end
@@ -34,6 +34,7 @@ describe Metaforce::Transaction do
34
34
 
35
35
  it "returns the status" do
36
36
  savon.expects(:deploy).with(:zip_file => '', :deploy_options => {}).returns(:in_progress)
37
+ savon.expects(:check_status).with(:ids => [ "04sU0000000WNWoIAO" ]).returns(:done)
37
38
  deployment = client.deploy(File.expand_path('../../../fixtures/sample', __FILE__))
38
39
  savon.expects(:check_status).with(:ids => [ "04sU0000000WNWoIAO" ]).returns(:done)
39
40
  deployment.status.should be_a(Hash)
@@ -43,16 +44,10 @@ describe Metaforce::Transaction do
43
44
 
44
45
  describe ".result" do
45
46
 
46
- it "raises an error if .done? hasn't been called" do
47
- savon.expects(:deploy).with(:zip_file => '', :deploy_options => {}).returns(:in_progress)
48
- deployment = client.deploy(File.expand_path('../../../fixtures/sample', __FILE__))
49
- expect { deployment.result }.to raise_error
50
- end
51
-
52
47
  it "allows you to check the transaction result" do
53
48
  savon.expects(:deploy).with(:zip_file => '', :deploy_options => {}).returns(:in_progress)
54
- deployment = client.deploy(File.expand_path('../../../fixtures/sample', __FILE__))
55
49
  savon.expects(:check_status).with(:ids => [ "04sU0000000WNWoIAO" ]).returns(:done)
50
+ deployment = client.deploy(File.expand_path('../../../fixtures/sample', __FILE__))
56
51
  deployment.done?.should eq(true)
57
52
  savon.expects(:check_deploy_status).with(:ids => [ "04sU0000000WNWoIAO" ]).returns(:done)
58
53
  deployment.result.should be_a(Hash)
@@ -60,8 +55,8 @@ describe Metaforce::Transaction do
60
55
 
61
56
  it "doesn't send a request if it has already retrieved the result" do
62
57
  savon.expects(:deploy).with(:zip_file => '', :deploy_options => {}).returns(:in_progress)
63
- deployment = client.deploy(File.expand_path('../../../fixtures/sample', __FILE__))
64
58
  savon.expects(:check_status).with(:ids => [ "04sU0000000WNWoIAO" ]).returns(:done)
59
+ deployment = client.deploy(File.expand_path('../../../fixtures/sample', __FILE__))
65
60
  deployment.done?.should eq(true)
66
61
  savon.expects(:check_deploy_status).with(:ids => [ "04sU0000000WNWoIAO" ]).returns(:done)
67
62
  deployment.result.should be_a(Hash)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: metaforce
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.5
4
+ version: 0.4.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-02-12 00:00:00.000000000 Z
12
+ date: 2012-03-02 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: nokogiri
16
- requirement: &9127740 !ruby/object:Gem::Requirement
16
+ requirement: &2152167300 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ~>
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: 1.5.0
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *9127740
24
+ version_requirements: *2152167300
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: savon
27
- requirement: &9127260 !ruby/object:Gem::Requirement
27
+ requirement: &2152166720 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ~>
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: 0.9.7
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *9127260
35
+ version_requirements: *2152166720
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: rubyzip
38
- requirement: &9126870 !ruby/object:Gem::Requirement
38
+ requirement: &2152164880 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ~>
@@ -43,10 +43,21 @@ dependencies:
43
43
  version: 0.9.5
44
44
  type: :runtime
45
45
  prerelease: false
46
- version_requirements: *9126870
46
+ version_requirements: *2152164880
47
+ - !ruby/object:Gem::Dependency
48
+ name: term-ansicolor
49
+ requirement: &2152180240 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ type: :runtime
56
+ prerelease: false
57
+ version_requirements: *2152180240
47
58
  - !ruby/object:Gem::Dependency
48
59
  name: rake
49
- requirement: &9126570 !ruby/object:Gem::Requirement
60
+ requirement: &2152176860 !ruby/object:Gem::Requirement
50
61
  none: false
51
62
  requirements:
52
63
  - - ! '>='
@@ -54,10 +65,10 @@ dependencies:
54
65
  version: '0'
55
66
  type: :development
56
67
  prerelease: false
57
- version_requirements: *9126570
68
+ version_requirements: *2152176860
58
69
  - !ruby/object:Gem::Dependency
59
70
  name: rspec
60
- requirement: &9126200 !ruby/object:Gem::Requirement
71
+ requirement: &2152175140 !ruby/object:Gem::Requirement
61
72
  none: false
62
73
  requirements:
63
74
  - - ! '>='
@@ -65,10 +76,10 @@ dependencies:
65
76
  version: '0'
66
77
  type: :development
67
78
  prerelease: false
68
- version_requirements: *9126200
79
+ version_requirements: *2152175140
69
80
  - !ruby/object:Gem::Dependency
70
81
  name: mocha
71
- requirement: &9125950 !ruby/object:Gem::Requirement
82
+ requirement: &2152188880 !ruby/object:Gem::Requirement
72
83
  none: false
73
84
  requirements:
74
85
  - - ! '>='
@@ -76,10 +87,10 @@ dependencies:
76
87
  version: '0'
77
88
  type: :development
78
89
  prerelease: false
79
- version_requirements: *9125950
90
+ version_requirements: *2152188880
80
91
  - !ruby/object:Gem::Dependency
81
92
  name: savon_spec
82
- requirement: &9125560 !ruby/object:Gem::Requirement
93
+ requirement: &2152186660 !ruby/object:Gem::Requirement
83
94
  none: false
84
95
  requirements:
85
96
  - - ~>
@@ -87,7 +98,7 @@ dependencies:
87
98
  version: 0.1.6
88
99
  type: :development
89
100
  prerelease: false
90
- version_requirements: *9125560
101
+ version_requirements: *2152186660
91
102
  description: A Ruby gem for interacting with the Salesforce Metadata API
92
103
  email:
93
104
  - eric@ejholmes.net
@@ -103,11 +114,15 @@ files:
103
114
  - Rakefile
104
115
  - lib/metaforce.rb
105
116
  - lib/metaforce/config.rb
106
- - lib/metaforce/dsl.rb
117
+ - lib/metaforce/error.rb
107
118
  - lib/metaforce/manifest.rb
108
119
  - lib/metaforce/metadata.rb
109
120
  - lib/metaforce/metadata/client.rb
110
121
  - lib/metaforce/metadata/transaction.rb
122
+ - lib/metaforce/rake.rb
123
+ - lib/metaforce/rake/deploy.rb
124
+ - lib/metaforce/rake/retrieve.rb
125
+ - lib/metaforce/rake/tests.rb
111
126
  - lib/metaforce/services.rb
112
127
  - lib/metaforce/services/client.rb
113
128
  - lib/metaforce/tasks/README.md
@@ -134,7 +149,6 @@ files:
134
149
  - spec/fixtures/sample/src/classes/TestClass.cls-meta.xml
135
150
  - spec/fixtures/sample/src/package.xml
136
151
  - spec/lib/config_spec.rb
137
- - spec/lib/dsl_spec.rb
138
152
  - spec/lib/manifest_spec.rb
139
153
  - spec/lib/metadata/metadata_spec.rb
140
154
  - spec/lib/metadata/transaction_spec.rb
@@ -185,7 +199,6 @@ test_files:
185
199
  - spec/fixtures/sample/src/classes/TestClass.cls-meta.xml
186
200
  - spec/fixtures/sample/src/package.xml
187
201
  - spec/lib/config_spec.rb
188
- - spec/lib/dsl_spec.rb
189
202
  - spec/lib/manifest_spec.rb
190
203
  - spec/lib/metadata/metadata_spec.rb
191
204
  - spec/lib/metadata/transaction_spec.rb
data/lib/metaforce/dsl.rb DELETED
@@ -1,42 +0,0 @@
1
- require 'tempfile'
2
- require 'zip/zip'
3
-
4
- module Metaforce
5
- module DSL
6
- module Metadata
7
-
8
- # Logs in and creates a new instance of Metaforce::Metadata::Client
9
- def login(options)
10
- @client = Metaforce::Metadata::Client.new options
11
- yield if block_given?
12
- end
13
-
14
- # Deploy the contents of _dir_ to the target organization
15
- def deploy(dir, options={})
16
- deployment = @client.deploy(dir, options)
17
- result = deployment.result(:wait_until_done => true)
18
- raise "Deploy failed." if !result[:success]
19
- yield result if block_given?
20
- end
21
-
22
- # Retrieve the metadata specified in the manifest file. If manifest is a
23
- # Hash, the underlying .retrieve method is used instead of
24
- # .retrieve_unpackaged.
25
- #
26
- # If _options_ # contains a key _:to_, the resulting zip
27
- # file that is retrieved is unzipped to the directory specified.
28
- def retrieve(manifest, options={})
29
- if manifest.is_a?(Hash)
30
- retrieval = @client.retrieve(manifest)
31
- else
32
- retrieval = @client.retrieve_unpackaged(manifest)
33
- end
34
- result = retrieval.result(:wait_until_done => true)
35
- zip_contents = retrieval.zip_file
36
- retrieval.unzip(options[:to]) if options.has_key?(:to)
37
- yield result, zip_contents if block_given?
38
- end
39
-
40
- end
41
- end
42
- end
data/spec/lib/dsl_spec.rb DELETED
@@ -1,93 +0,0 @@
1
- require "spec_helper"
2
- require "metaforce/dsl"
3
- include Metaforce::DSL::Metadata
4
-
5
- describe Metaforce::DSL::Metadata do
6
-
7
- let(:manifest) do
8
- Metaforce::Manifest.new(File.open(File.expand_path('../../fixtures/sample/src/package.xml', __FILE__)).read)
9
- end
10
-
11
- let(:valid_credentials) do
12
- { :username => 'valid', :password => 'password' }
13
- end
14
-
15
- describe ".login" do
16
-
17
- before(:each) do
18
- savon.expects(:login).with(valid_credentials).returns(:success)
19
- end
20
-
21
- it "logs the user in" do
22
- expect { login valid_credentials }.to_not raise_error
23
- end
24
-
25
- end
26
-
27
- describe ".deploy" do
28
-
29
- before(:each) do
30
- Metaforce::Metadata::Client.any_instance.stubs(:create_deploy_file).returns('')
31
- savon.expects(:login).with(valid_credentials).returns(:success)
32
- savon.expects(:deploy).with(:zip_file => '', :deploy_options => {}).returns(:in_progress)
33
- savon.expects(:check_status).with(:ids => [ "04sU0000000WNWoIAO" ]).returns(:done)
34
- savon.expects(:check_deploy_status).with(:ids => [ "04sU0000000WNWoIAO" ]).returns(:done)
35
- end
36
-
37
- context "when given a directory" do
38
-
39
- it "deploys the directory" do
40
- login valid_credentials
41
- expect {
42
- deploy File.expand_path('../../../fixtures/sample', __FILE__) do |result|
43
- result.should be_a(Hash)
44
- end
45
- }.to_not raise_error
46
- end
47
-
48
- end
49
-
50
- end
51
-
52
- describe ".retrieve" do
53
- before(:each) do
54
- savon.expects(:login).with(valid_credentials).returns(:success)
55
- savon.expects(:retrieve).with(:retrieve_request => { :api_version => Metaforce.configuration.api_version, :single_package => true, :unpackaged => { :types => manifest.to_package } }).returns(:in_progress)
56
- savon.expects(:check_status).with(:ids => ['04sU0000000WkdIIAS']).returns(:done)
57
- savon.expects(:check_retrieve_status).with(:ids => ['04sU0000000WkdIIAS']).returns(:success)
58
- end
59
-
60
- context "when given a manifest file" do
61
-
62
- it "retrieves the components" do
63
- login valid_credentials
64
- expect {
65
- retrieve manifest do |result, zip|
66
- result.should be_a(Hash)
67
- zip.should be_a(String)
68
- end
69
- }.to_not raise_error
70
- end
71
-
72
- context "and :to is specified" do
73
-
74
- before(:each) do
75
- Metaforce::Transaction.any_instance.stubs(:unzip).returns('')
76
- end
77
-
78
- it "retrieves the components and unzips them to the directory" do
79
- login valid_credentials
80
- expect {
81
- retrieve manifest, :to => "test_retrieve" do |result, zip|
82
- result.should be_a(Hash)
83
- zip.should be_a(String)
84
- end
85
- }.to_not raise_error
86
- end
87
-
88
- end
89
-
90
- end
91
-
92
- end
93
- end