metaforce 0.3.5 → 0.4.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/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