metaforce 0.5.3 → 1.0.0a

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. data/.gitignore +1 -0
  2. data/.rspec +1 -0
  3. data/Gemfile +1 -11
  4. data/LICENSE +22 -0
  5. data/README.md +91 -96
  6. data/Rakefile +6 -14
  7. data/examples/example.rb +51 -0
  8. data/lib/metaforce/abstract_client.rb +76 -0
  9. data/lib/metaforce/client.rb +27 -0
  10. data/lib/metaforce/config.rb +41 -19
  11. data/lib/metaforce/job/crud.rb +13 -0
  12. data/lib/metaforce/job/deploy.rb +87 -0
  13. data/lib/metaforce/job/retrieve.rb +92 -0
  14. data/lib/metaforce/job.rb +183 -0
  15. data/lib/metaforce/login.rb +39 -0
  16. data/lib/metaforce/manifest.rb +18 -93
  17. data/lib/metaforce/metadata/client/crud.rb +86 -0
  18. data/lib/metaforce/metadata/client/file.rb +113 -0
  19. data/lib/metaforce/metadata/client.rb +7 -225
  20. data/lib/metaforce/services/client.rb +45 -86
  21. data/lib/metaforce/version.rb +1 -1
  22. data/lib/metaforce.rb +27 -7
  23. data/metaforce.gemspec +19 -16
  24. data/spec/fixtures/package.xml +1 -1
  25. data/spec/fixtures/payload.zip +0 -0
  26. data/spec/fixtures/requests/{describe_layout → foo}/invalid_session.xml +0 -0
  27. data/spec/fixtures/requests/send_email/success.xml +1 -0
  28. data/spec/lib/client_spec.rb +34 -0
  29. data/spec/lib/config_spec.rb +8 -50
  30. data/spec/lib/job/deploy_spec.rb +53 -0
  31. data/spec/lib/job/retrieve_spec.rb +28 -0
  32. data/spec/lib/job_spec.rb +95 -0
  33. data/spec/lib/login_spec.rb +18 -0
  34. data/spec/lib/manifest_spec.rb +22 -168
  35. data/spec/lib/metadata/client_spec.rb +84 -179
  36. data/spec/lib/metaforce_spec.rb +20 -0
  37. data/spec/lib/services/client_spec.rb +22 -35
  38. data/spec/spec_helper.rb +24 -3
  39. data/spec/support/client.rb +38 -0
  40. data/wsdl/26.0/metadata.xml +4750 -0
  41. data/wsdl/26.0/partner.xml +3340 -0
  42. metadata +114 -77
  43. data/Guardfile +0 -9
  44. data/bin/metaforce +0 -6
  45. data/lib/metaforce/core_extensions/string.rb +0 -31
  46. data/lib/metaforce/core_extensions.rb +0 -1
  47. data/lib/metaforce/custom_actions.rb +0 -29
  48. data/lib/metaforce/error.rb +0 -3
  49. data/lib/metaforce/login_details.rb +0 -28
  50. data/lib/metaforce/metadata/crud.rb +0 -103
  51. data/lib/metaforce/metadata/file.rb +0 -74
  52. data/lib/metaforce/metadata/transaction.rb +0 -100
  53. data/lib/metaforce/metadata.rb +0 -4
  54. data/lib/metaforce/rake/deploy.rb +0 -35
  55. data/lib/metaforce/rake/retrieve.rb +0 -39
  56. data/lib/metaforce/rake/tests.rb +0 -62
  57. data/lib/metaforce/rake.rb +0 -43
  58. data/lib/metaforce/services.rb +0 -1
  59. data/lib/metaforce/tasks/README.md +0 -62
  60. data/lib/metaforce/tasks/metaforce.rake +0 -5
  61. data/lib/metaforce/thor/metaforce.rb +0 -117
  62. data/lib/metaforce/types.rb +0 -249
  63. data/spec/.gitignore +0 -1
  64. data/spec/fixtures/sample/Rakefile +0 -2
  65. data/spec/fixtures/sample/metaforce.yml +0 -13
  66. data/spec/fixtures/sample/src/classes/TestClass.cls +0 -2
  67. data/spec/fixtures/sample/src/classes/TestClass.cls-meta.xml +0 -5
  68. data/spec/fixtures/sample/src/package.xml +0 -8
  69. data/spec/lib/core_extensions/string_spec.rb +0 -23
  70. data/spec/lib/metadata/crud_spec.rb +0 -66
  71. data/spec/lib/metadata/file_spec.rb +0 -17
  72. data/spec/lib/metadata/transaction_spec.rb +0 -68
data/.gitignore CHANGED
@@ -2,6 +2,7 @@
2
2
  .bundle
3
3
  Gemfile.lock
4
4
  pkg/*
5
+ examples/tmp
5
6
  deploy.zip
6
7
  retrieve.zip
7
8
  test.rb
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --colour
data/Gemfile CHANGED
@@ -1,14 +1,4 @@
1
- source "http://rubygems.org"
2
- gem 'highline'
3
- gem 'thor'
1
+ source :rubygems
4
2
 
5
3
  # Specify your gem's dependencies in metaforce.gemspec
6
4
  gemspec
7
-
8
- group :development do
9
- gem "guard"
10
- gem "guard-rspec"
11
- gem "growl"
12
- gem "yard"
13
- gem "redcarpet"
14
- end
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Eric J. Holmes
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md CHANGED
@@ -1,139 +1,134 @@
1
- # Metaforce [![travis-ci](https://secure.travis-ci.org/ejholmes/metaforce.png)](https://secure.travis-ci.org/ejholmes/metaforce)
1
+ # Metaforce
2
2
 
3
- Metaforce is a Ruby gem for interacting with the [Salesforce Metadata API](http://www.salesforce.com/us/developer/docs/api_meta/index.htm).
4
- The goal of this project is to make the [Migration Tool](http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_deploying_ant.htm) obsolete, favoring Rake over Ant.
3
+ [![travis-ci](https://secure.travis-ci.org/ejholmes/metaforce.png)](https://secure.travis-ci.org/ejholmes/metaforce) [![Code Climate](https://codeclimate.com/badge.png)](https://codeclimate.com/github/ejholmes/metaforce) [![Dependency Status](https://gemnasium.com/ejholmes/metaforce.png)](https://gemnasium.com/ejholmes/metaforce)
4
+
5
+ Metaforce is a Ruby gem for interacting with the Salesforce [Metadata](http://www.salesforce.com/us/developer/docs/api_meta/index.htm)
6
+ and [Services](http://www.salesforce.com/us/developer/docs/api/index.htm) APIs.
5
7
 
6
8
  [Documentation](http://rubydoc.info/gems/metaforce/frames)
7
9
 
8
10
  ## Installation
11
+
9
12
  ```bash
10
13
  gem install metaforce
11
14
  ```
12
15
 
13
16
  ## Usage
14
- ``` ruby
15
- client = Metaforce::Metadata::Client.new :username => 'username',
16
- :password => 'password',
17
- :security_token => 'security token')
18
-
19
- # Describe the metadata on the organization
20
- client.metadata_objects
21
- # => [{ :child_xml_names => "CustomLabel", :directory_name => "labels" ... }]
22
-
23
- # List all custom objects
24
- client.list(:custom_object)
25
- # => [{ :created_by_id => "005U0000000EGpcIAG", :created_by_name => "Eric Holmes", ... }]
26
-
27
- # Deploy metadata to the organization
28
- deployment = client.deploy(File.expand_path('path/to/src'))
29
- # => #<Metaforce::Transaction:0x00000102779bf8 @id="04sU0000000WNWoIAO" @type=:deploy>
30
17
 
31
- # Get the result
32
- deployment.result
33
- # => { :id => "04sU0000000WNWoIAO", :messages => [{ :changed => true ... :success => true }
18
+ ### Initialization
34
19
 
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')
20
+ #### Username and Password
37
21
 
38
- # Create a Visualforce page
39
- client.create_apex_page(:full_name => 'TestPage', :label => 'TestPage')
22
+ To initialize a new client, you call `Metaforce.new` with a hash that specifies
23
+ the `:username`, `:password`, and `:security_token`.
40
24
 
41
- # Update a Visualforce page
42
- client.update_apex_page('OldName', :full_name => 'NewName')
43
-
44
- # Delete a Visualforce page
45
- client.delete_apex_page('TestPage')
25
+ ```ruby
26
+ client = Metaforce.new :username => 'username',
27
+ :password => 'password',
28
+ :security_token => 'security token'
46
29
  ```
47
30
 
48
- ## Roadmap
49
- This gem is far from being feature complete. Here's a list of things that still
50
- need to be done.
51
-
52
- * Implement command line utility that can watch the directory and deploy when a
53
- file changes.
54
- * Implement some helper methods for diffing metadata.
55
- * Ability to deploy directly from a git repository.
56
- * And some other stuff that I haven't quite thought of yet...
57
-
58
- ## Contributing
59
- If you'd like to contribute code, please fork the repository and implement your
60
- feature on a new branch, then send me a pull request with a detailed
61
- description. Please provide applicable rspec specs.
62
-
63
- ## Version History
64
- **0.5.3** (June 8, 2012)
65
- * Only trigger reauthentication if the response contains `INVALID_SESSION_ID`.
31
+ #### Asynchronous Tasks
66
32
 
67
- **0.5.2** (June 8, 2012)
68
- * The services client now reauthentications on Savon::SOAP::Fault.
33
+ Some calls to the SOAP API's are performed asynchronously (such as deployments),
34
+ meaning the response needs to be polled for. Any call to the SOAP API's that
35
+ are performed asynchronously will return a Metaforce::Job object, which can be used to
36
+ subscribe to `on_complete` and `on_error` callbacks. The Metaforce::Job class
37
+ will poll the status of the asynchronous job in a thread until it completes or
38
+ fails.
69
39
 
70
- **0.5.1**
40
+ * * *
71
41
 
72
- * Add thor integration.
42
+ ### deploy(path, options={})
73
43
 
74
- **0.5.0** (March 23, 2012)
44
+ Takes a path (can be a path to a directory, or a zip file), and a set of
45
+ [DeployOptions](http://www.salesforce.com/us/developer/docs/api_meta/Content/meta_deploy.htm#deploy_options)
46
+ and returns a `Metaforce::Job::Deploy`.
75
47
 
76
- * Implemented CRUD calls.
77
-
78
- **0.4.1** (March 8, 2012)
79
-
80
- * Bug fixes
48
+ ```ruby
49
+ client.deploy(File.expand_path('./src'))
50
+ .on_complete { |job| puts "Finished deploy #{job.id}!" }
51
+ .on_error { |job| puts "Something bad happened!" }
52
+ .perform
53
+ #=> #<Metaforce::Job::Deploy @id='1234'>
54
+ ```
81
55
 
82
- **0.4.0** (March 2, 2012)
56
+ * * *
83
57
 
84
- * Various bug fixes and improvements.
85
- * Removed DSL to focus on core functionality.
58
+ ### retrieve\_unpackaged(manifest, options={})
86
59
 
87
- **0.3.5** (February 11, 2012)
60
+ Takes a manifest (`Metaforce::Manifest` or a path to a package.xml file) and a
61
+ set of [RetrieveOptions](http://www.salesforce.com/us/developer/docs/api_meta/Content/meta_retrieve_request.htm)
62
+ and returns a `Metaforce::Job::Retrieve`.
88
63
 
89
- * Allow rake tasks to get credentials from a metaforce.yml file.
64
+ ```ruby
65
+ manifest = Metaforce::Manifest.new(:custom_object => ['Account'])
66
+ client.retrieve_unpackaged(manifest)
67
+ .extract_to('./tmp')
68
+ .perform
69
+ #=> #<Metaforce::Job::Retrieve @id='1234'>
70
+ ```
90
71
 
91
- **0.3.4** (February 9, 2012)
72
+ * * *
92
73
 
93
- * Add rake tasks.
74
+ ### create(type, metadata={})
94
75
 
95
- **0.3.3** (February 9, 2012)
76
+ Takes a Symbol type and a Hash of [Metadata Attributes](http://www.salesforce.com/us/developer/docs/api_meta/Content/meta_types_list.htm)
77
+ and returns a `Metaforce::Job::CRUD`.
96
78
 
97
- * Added a logger for logging requests.
98
- * Allow api version to be set when calling `Metaforce::Metadata::Client.describe`.
79
+ ```ruby
80
+ client.create(:apex_page, full_name: 'Foobar', content: 'Hello World!')
81
+ .on_complete { |job| puts "ApexPage created." }
82
+ .perform
83
+ #=> #<Metaforce::Job::CRUD @id='1234'>
84
+ ```
99
85
 
100
- **0.3.2** (February 3, 2012)
86
+ * * *
101
87
 
102
- * Improved documentation.
103
- * Added `.status` method to Transaction class.
88
+ ### update(type, current\_name metadata={})
104
89
 
105
- **0.3.1** (February 3, 2012)
90
+ Takes a Symbol type, the current `full_name` of the resource, and a Hash of
91
+ [Metadata Attributes](http://www.salesforce.com/us/developer/docs/api_meta/Content/meta_types_list.htm)
92
+ and returns a `Metaforce::Job::CRUD`.
106
93
 
107
- * Dynamically defined helper methods for .list (e.g. `client.list_apex_class`, `client.list_custom_object`).
108
- * The `Metaforce::Metadata::Client.describe` method now caches the results to minimize latency. `describe!`
109
- can be used to force a refresh.
94
+ ```ruby
95
+ client.update(:apex_page, 'Foobar', content: 'Hello World! Some new content!')
96
+ .on_complete { |job| puts "ApexPage updated." }
97
+ .perform
98
+ #=> #<Metaforce::Job::CRUD @id='1234'>
99
+ ```
110
100
 
111
- **0.3.0.alpha** (January 29, 2012)
101
+ * * *
112
102
 
113
- * Ability to retrieve metadata from an organization.
114
- * Added a DSL.
103
+ ### delete(type, \*args)
115
104
 
116
- **0.2.0.alpha** (January 28, 2012)
105
+ Takes a Symbol type, and the `full_name` of a resource and returns a `Metaforce::Job::CRUD`.
117
106
 
118
- * Gem now supports interacting with the metadata api.
107
+ ```ruby
108
+ client.delete(:apex_page, 'Foobar')
109
+ .on_complete { |job| puts "ApexPage deleted." }
110
+ .perform
111
+ #=> #<Metaforce::Job::CRUD @id='1234'>
112
+ ```
119
113
 
120
- **0.1.0.alpha** (January 10, 2012)
114
+ * * *
121
115
 
122
- * Ability to parse and modify package.xml files easily.
116
+ ### send\_email(options={})
123
117
 
124
- ## License
125
- Copyright (C) 2012 Eric Holmes
118
+ Sends a [SingleEmailMessage](http://www.salesforce.com/us/developer/docs/api/Content/sforce_api_calls_sendemail.htm) using Salesforce.
126
119
 
127
- This program is free software; you can redistribute it and/or
128
- modify it under the terms of the GNU General Public License
129
- as published by the Free Software Foundation; either version 2
130
- of the License, or (at your option) any later version.
120
+ ```ruby
121
+ client.send_email(
122
+ to_addresses: ['foo@bar.com'],
123
+ subject: 'Hello World',
124
+ plain_text_body: 'Hello World'
125
+ )
126
+ ```
131
127
 
132
- This program is distributed in the hope that it will be useful,
133
- but WITHOUT ANY WARRANTY; without even the implied warranty of
134
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
135
- GNU General Public License for more details.
128
+ ## Contributing
136
129
 
137
- You should have received a copy of the GNU General Public License
138
- along with this program; if not, write to the Free Software
139
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
130
+ 1. Fork it
131
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
132
+ 3. Commit your changes (`git commit -am 'Added some feature'`)
133
+ 4. Push to the branch (`git push origin my-new-feature`)
134
+ 5. Create new Pull Request
data/Rakefile CHANGED
@@ -1,18 +1,10 @@
1
+ #!/usr/bin/env rake
1
2
  require "bundler/gem_tasks"
2
3
 
3
- task :default => :spec
4
+ task :default => [:spec]
4
5
 
5
- desc "Run rspec specs"
6
- task :spec do
7
- sh "bundle exec rspec spec"
8
- end
9
-
10
- desc "Start an irb session"
11
- task :console do
12
- sh "irb -I lib -r metaforce"
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"
6
+ require 'rspec/core/rake_task'
7
+ desc "Run specs"
8
+ RSpec::Core::RakeTask.new do |t|
9
+ t.pattern = 'spec/**/*_spec.rb'
18
10
  end
@@ -0,0 +1,51 @@
1
+ require 'metaforce'
2
+
3
+ # Run with: `USER=user PASS=pass TOKEN=securitytoken bundle exec ruby example.rb`
4
+
5
+ Metaforce.configuration.log = false
6
+
7
+ client = Metaforce.new :username => ENV['USER'],
8
+ :password => ENV['PASS'],
9
+ :security_token => ENV['TOKEN']
10
+
11
+ Metaforce::Job.disable_threading!
12
+
13
+ # Test sending an email.
14
+ print 'send email to: '
15
+ client.send_email(
16
+ to_addresses: [STDIN.gets.chomp],
17
+ subject: 'Test',
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
26
+
27
+ # Test retrieve.
28
+ manifest = Metaforce::Manifest.new(:custom_object => ['Account'])
29
+ client.retrieve_unpackaged(manifest)
30
+ .on_complete { |job| puts "Retrieve Completed: #{job.id}."}
31
+ .on_error { |job| puts "Retrieve Failed: #{job.id}."}
32
+ .extract_to('./tmp')
33
+ .perform
34
+
35
+ # Test delete.
36
+ client.delete(:apex_page, 'TestPage')
37
+ .on_complete { |job| puts "Delete Completed: #{job.id}."}
38
+ .on_error { |job| puts "Delete Failed: #{job.id}."}
39
+ .perform
40
+
41
+ # Test create.
42
+ client.create(:apex_page, :full_name => 'TestPage', label: 'Test page', :content => '<apex:page>foobar</apex:page>')
43
+ .on_complete { |job| puts "Create Completed: #{job.id}."}
44
+ .on_error { |job| puts "Create Failed: #{job.id}."}
45
+ .perform
46
+
47
+ # Test update.
48
+ client.update(:apex_page, 'TestPage', :full_name => 'TestPage', :label => 'Test page', :content => '<apex:page>hello world</apex:page>')
49
+ .on_complete { |job| puts "Update Completed: #{job.id}."}
50
+ .on_error { |job| puts "Update Failed: #{job.id}."}
51
+ .perform
@@ -0,0 +1,76 @@
1
+ module Metaforce
2
+ class AbstractClient
3
+ class << self
4
+ # Internal
5
+ def endpoint(key)
6
+ define_method :endpoint do; @options[key] end
7
+ end
8
+
9
+ # Internal
10
+ def wsdl(wsdl)
11
+ define_method :wsdl do; wsdl end
12
+ end
13
+ end
14
+
15
+ # Public: Initialize a new client.
16
+ #
17
+ # options - A hash of options, which should have a :session_id key
18
+ def initialize(options={})
19
+ raise 'Please specify a hash of options' unless options.is_a?(Hash)
20
+ @options = options
21
+ end
22
+
23
+ private
24
+
25
+ # Internal: The Savon client to send SOAP requests with.
26
+ def client
27
+ @client ||= Savon.client(wsdl) do |wsdl|
28
+ wsdl.endpoint = endpoint
29
+ end.tap do |client|
30
+ client.config.soap_header = soap_headers
31
+ client.http.auth.ssl.verify_mode = :none
32
+ end
33
+ end
34
+
35
+ # Internal: Performs a SOAP request. If the session is invalid, it will
36
+ # attempt to reauthenticate by called the reauthentication handler if
37
+ # present.
38
+ def request(*args, &block)
39
+ begin
40
+ authenticate! unless session_id
41
+ _request(*args, &block)
42
+ rescue Savon::SOAP::Fault => e
43
+ raise e unless e.message =~ /INVALID_SESSION_ID/ && authentication_handler
44
+ authenticate!
45
+ _request(*args, &block)
46
+ end
47
+ end
48
+
49
+ def _request(*args, &block)
50
+ response = client.request(*args, &block)
51
+ Hashie::Mash.new(response.body)[:"#{args[0]}_response"].result
52
+ end
53
+
54
+ # Internal Calls the authentication handler, which should set @options to a new
55
+ # hash.
56
+ def authenticate!
57
+ authentication_handler.call(self, @options)
58
+ end
59
+
60
+ # A proc object that gets called when the client needs to reauthenticate.
61
+ def authentication_handler
62
+ Metaforce.configuration.authentication_handler
63
+ end
64
+
65
+ # Internal: Soap headers to set for authenticate.
66
+ def soap_headers
67
+ { 'ins0:SessionHeader' => { 'ins0:sessionId' => session_id } }
68
+ end
69
+
70
+ # Internal: The session id, which can be obtained by calling
71
+ # Metaforce.login or through OAuth.
72
+ def session_id
73
+ @options[:session_id]
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,27 @@
1
+ module Metaforce
2
+ class Client
3
+ def initialize(options)
4
+ @options = options
5
+ end
6
+
7
+ # Public: Used to interact with the Metadata API.
8
+ def metadata
9
+ @metadata ||= Metaforce::Metadata::Client.new(@options)
10
+ end
11
+
12
+ # Public: Used to interact with the Services API.
13
+ def services
14
+ @services ||= Metaforce::Services::Client.new(@options)
15
+ end
16
+
17
+ def method_missing(method, *args, &block)
18
+ if metadata.respond_to? method, false
19
+ metadata.send(method, *args, &block)
20
+ elsif services.respond_to? method, false
21
+ services.send(method, *args, &block)
22
+ else
23
+ super
24
+ end
25
+ end
26
+ end
27
+ end
@@ -41,26 +41,48 @@ module Metaforce
41
41
  attr_accessor :security_token
42
42
  # Set this to true if you're authenticating with a Sandbox instance.
43
43
  # Defaults to false.
44
- attr_accessor :test
45
- # Causes Metaforce::Transaction.result to loop until the transaction is
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
57
- attr_accessor :wait_until_done
44
+ attr_accessor :host
45
+ # A block that gets called when the session becomes invalid and the
46
+ # client needs to reauthenticate. Passes in the client and the client
47
+ # options. The block should set the options to a hash containing a valid
48
+ # session_id and service urls.
49
+ attr_accessor :authentication_handler
50
+
51
+ def api_version
52
+ @api_version ||= '26.0'
53
+ end
54
+
55
+ def host
56
+ @host ||= 'login.salesforce.com'
57
+ end
58
+
59
+ def authentication_handler
60
+ @authentication_handler ||= lambda { |client, options|
61
+ options.merge!(Metaforce.login(options))
62
+ }
63
+ end
64
+
65
+ def log=(log)
66
+ Savon.configure do |config|
67
+ config.log = log
68
+ end
69
+ HTTPI.log = log
70
+ end
71
+
72
+ def partner_wsdl
73
+ File.join(wsdl, 'partner.xml')
74
+ end
75
+
76
+ def metadata_wsdl
77
+ File.join(wsdl, 'metadata.xml')
78
+ end
79
+
80
+ def endpoint
81
+ "https://#{host}/services/Soap/u/#{api_version}"
82
+ end
58
83
 
59
- def initialize
60
- HTTPI.log = false
61
- @api_version = "23.0"
62
- @test = false
63
- @wait_until_done = true
84
+ def wsdl
85
+ File.expand_path("../../../wsdl/#{api_version}", __FILE__)
64
86
  end
65
87
 
66
88
  def logger
@@ -0,0 +1,13 @@
1
+ module Metaforce
2
+ class Job::CRUD < Job
3
+ def initialize(client, method, args)
4
+ super(client)
5
+ @method, @args = method, args
6
+ end
7
+
8
+ def perform
9
+ @id = @client.send(@method, *@args).id
10
+ super
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,87 @@
1
+ module Metaforce
2
+ class Job::Deploy < Job
3
+
4
+ # Public: Instantiate a new deploy job.
5
+ #
6
+ # Examples
7
+ #
8
+ # job = Metaforce::Job::Deploy.new(client, './path/to/deploy')
9
+ # # => #<Metaforce::Job::Deploy @id=nil>
10
+ #
11
+ # Returns self.
12
+ def initialize(client, path, options={})
13
+ super(client)
14
+ @path, @options = path, options
15
+ end
16
+
17
+ # Public: Perform the job.
18
+ #
19
+ # Examples
20
+ #
21
+ # job = Metaforce::Job::Deploy.new(client, './path/to/deploy')
22
+ # job.perform
23
+ # # => #<Metaforce::Job::Deploy @id='1234'>
24
+ #
25
+ # Returns self.
26
+ def perform
27
+ @id = client._deploy(payload, @options).id
28
+ super
29
+ end
30
+
31
+ # Public: Get the detailed status of the deploy.
32
+ #
33
+ # Examples
34
+ #
35
+ # job.result
36
+ # # => { :id => '1234', :success => true, ... }
37
+ #
38
+ # Returns the DeployResult (http://www.salesforce.com/us/developer/docs/api_meta/Content/meta_deployresult.htm).
39
+ def result
40
+ client.status(id, :deploy)
41
+ end
42
+
43
+ # Public: Returns true if the deploy was successful.
44
+ #
45
+ # Examples
46
+ #
47
+ # job.success?
48
+ # # => true
49
+ #
50
+ # Returns true or false based on the DeployResult.
51
+ def success?
52
+ result.success
53
+ end
54
+
55
+ # Public: Base64 encodes the contents of the zip file.
56
+ #
57
+ # Examples
58
+ #
59
+ # job.payload
60
+ # # => '<lots of base64 encoded content>'
61
+ #
62
+ # Returns the content of the zip file encoded to base64.
63
+ def payload
64
+ Base64.encode64(File.open(file, 'rb').read)
65
+ end
66
+
67
+ private
68
+
69
+ # Internal: Returns the path to the zip file.
70
+ def file
71
+ File.file?(@path) ? @path : zip_file
72
+ end
73
+
74
+ # Internal: Creates a zip file with the contents of the directory.
75
+ def zip_file
76
+ path = Dir.mktmpdir
77
+ File.join(path, 'deploy.zip').tap do |path|
78
+ Zip::ZipFile.open(path, Zip::ZipFile::CREATE) do |zip|
79
+ Dir["#{@path}/**/**"].each do |file|
80
+ zip.add(file.sub("#{File.dirname(@path)}/", ''), file)
81
+ end
82
+ end
83
+ end
84
+ end
85
+
86
+ end
87
+ end