metaforce 0.3.1 → 0.3.2
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/Gemfile +2 -0
- data/README.md +8 -2
- data/lib/metaforce/api/metadata.rb +62 -21
- data/lib/metaforce/api/transaction.rb +14 -5
- data/lib/metaforce/version.rb +1 -1
- data/spec/lib/api/transaction_spec.rb +11 -0
- metadata +16 -15
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,9 +1,10 @@
|
|
1
|
-
# Metaforce
|
2
|
-

|
1
|
+
# Metaforce [](https://secure.travis-ci.org/ejholmes/metaforce)
|
3
2
|
|
4
3
|
Metaforce is a Ruby gem for interacting with the [Salesforce Metadata API](http://www.salesforce.com/us/developer/docs/api_meta/index.htm).
|
5
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.
|
6
5
|
|
6
|
+
[Documentation](http://rubydoc.info/gems/metaforce/frames)
|
7
|
+
|
7
8
|
## Installation
|
8
9
|
```bash
|
9
10
|
gem install metaforce
|
@@ -74,6 +75,11 @@ feature on a new branch, then send me a pull request with a detailed
|
|
74
75
|
description. Please provide applicable rspec specs.
|
75
76
|
|
76
77
|
## Version History
|
78
|
+
**0.3.2** (February 3, 2012)
|
79
|
+
|
80
|
+
* Improved documentation.
|
81
|
+
* Added `.status` method to Transaction class.
|
82
|
+
|
77
83
|
**0.3.1** (February 3, 2012)
|
78
84
|
|
79
85
|
* Dynamically defined helper methods for .list (e.g. `client.list_apex_classes`, `client.list_custom_objects`).
|
@@ -11,12 +11,15 @@ module Metaforce
|
|
11
11
|
RETRIEVE_ZIP = 'retrieve.zip' # :nodoc:
|
12
12
|
|
13
13
|
# Performs a login and sets the session_id and metadata_server_url.
|
14
|
-
# _options_ should be hash containing the :username, :password and
|
15
|
-
# :security_token keys.
|
16
14
|
#
|
17
|
-
#
|
18
|
-
#
|
19
|
-
#
|
15
|
+
# +options+ should be hash containing the +:username+, +:password+ and
|
16
|
+
# +:security_token+ keys.
|
17
|
+
#
|
18
|
+
# == Examples
|
19
|
+
#
|
20
|
+
# Metaforce::Metadata::Client.new :username => "username",
|
21
|
+
# :password => "password",
|
22
|
+
# :security_token => "security token"
|
20
23
|
def initialize(options=nil)
|
21
24
|
@session = Services::Client.new(options).session
|
22
25
|
@client = Savon::Client.new File.expand_path("../../../../wsdl/#{Metaforce.configuration.api_version}/metadata.xml", __FILE__) do |wsdl|
|
@@ -30,12 +33,17 @@ module Metaforce
|
|
30
33
|
}
|
31
34
|
end
|
32
35
|
|
33
|
-
# Specify an array of component types to list
|
36
|
+
# Specify an array of component types to list.
|
37
|
+
#
|
38
|
+
# == Examples
|
39
|
+
#
|
40
|
+
# # Get a list of apex classes on the server and output the names of each
|
41
|
+
# client.list(:type => "ApexClass").collect { |t| t[:full_name] }
|
42
|
+
# #=> ["al__SObjectPaginatorListenerForTesting", "al__IndexOutOfBoundsException", ... ]
|
34
43
|
#
|
35
|
-
#
|
36
|
-
#
|
37
|
-
#
|
38
|
-
# ]
|
44
|
+
# # Get a list of apex components and apex classes
|
45
|
+
# client.list([{ :type => "CustomObject" }, { :type => "ApexComponent" }])
|
46
|
+
# #=> ["ContractContactRole", "Solution", "Invoice_Statements__c", ... ]
|
39
47
|
def list(queries=[])
|
40
48
|
unless queries.is_a?(Array)
|
41
49
|
queries = [ queries ]
|
@@ -51,10 +59,15 @@ module Metaforce
|
|
51
59
|
|
52
60
|
# Defines some helper methods for listing metadata types
|
53
61
|
#
|
54
|
-
#
|
62
|
+
# == Examples
|
55
63
|
#
|
56
|
-
#
|
57
|
-
# client.
|
64
|
+
# # List the names of all apex classes
|
65
|
+
# client.list_apex_classes.collect { |t| t[:full_name] }
|
66
|
+
# #=> ["al__SObjectPaginatorListenerForTesting", "al__IndexOutOfBoundsException", ... ]
|
67
|
+
#
|
68
|
+
# # List the names of all custom objects
|
69
|
+
# client.list_custom_objects.collect { |t| t[:full_name] }
|
70
|
+
# #=> ["Asset", "estore__Ida_Menu_Item__c", "SfoMatchHistoryItem", ... ]
|
58
71
|
METADATA_TYPES.each do |type, value|
|
59
72
|
define_method("list_#{value[:plural]}".to_sym) do
|
60
73
|
list :type => value[:name]
|
@@ -62,11 +75,17 @@ module Metaforce
|
|
62
75
|
end
|
63
76
|
|
64
77
|
# Describe the organization's metadata and cache the response
|
78
|
+
#
|
79
|
+
# == Examples
|
80
|
+
#
|
81
|
+
# # List the names of all metedata types
|
82
|
+
# client.describe[:metadata_objects].collect { |t| t[:xml_name] }
|
83
|
+
# #=> ["CustomLabels", "StaticResource", "Scontrol", "ApexComponent", ... ]
|
65
84
|
def describe
|
66
85
|
@describe ||= describe!
|
67
86
|
end
|
68
87
|
|
69
|
-
#
|
88
|
+
# See +describe+
|
70
89
|
def describe!
|
71
90
|
response = @client.request(:describe_metadata) do |soap|
|
72
91
|
soap.header = @header
|
@@ -74,10 +93,13 @@ module Metaforce
|
|
74
93
|
@describe = response.body[:describe_metadata_response][:result]
|
75
94
|
end
|
76
95
|
|
77
|
-
# Checks the status of an async result
|
96
|
+
# Checks the status of an async result. If type is +:retrieve+ or +:deploy+,
|
97
|
+
# it returns the RetrieveResult or DeployResult, respectively
|
78
98
|
#
|
79
|
-
#
|
80
|
-
#
|
99
|
+
# == Examples
|
100
|
+
#
|
101
|
+
# client.status('04sU0000000Wx6KIAS')
|
102
|
+
# #=> {:done=>true, :id=>"04sU0000000Wx6KIAS", :state=>"Completed", :state_detail_last_modified_date=>#<DateTime: 2012-02-03T18:30:38+00:00 ((2455961j,66638s,0n),+0s,2299161j)>}
|
81
103
|
def status(ids, type=nil)
|
82
104
|
request = "check_status"
|
83
105
|
request = "check_#{type.to_s}_status" unless type.nil?
|
@@ -93,15 +115,31 @@ module Metaforce
|
|
93
115
|
end
|
94
116
|
|
95
117
|
# Returns true if the deployment with id id is done, false otherwise
|
118
|
+
#
|
119
|
+
# == Examples
|
120
|
+
#
|
121
|
+
# client.done?('04sU0000000Wx6KIAS')
|
122
|
+
# #=> true
|
96
123
|
def done?(id)
|
97
|
-
self.status(id)[:done]
|
124
|
+
self.status(id)[:done] || false
|
98
125
|
end
|
99
126
|
|
100
|
-
# Deploys
|
127
|
+
# Deploys +dir+ to the organisation.
|
101
128
|
#
|
102
129
|
# See http://www.salesforce.com/us/developer/docs/api_meta/Content/meta_deploy.htm#deploy_options
|
103
130
|
# for a list of _deploy_options_. Options should be convereted from
|
104
131
|
# camelCase to an :underscored_symbol.
|
132
|
+
#
|
133
|
+
# == Examples
|
134
|
+
#
|
135
|
+
# deploy = client.deploy File.expand_path("myeclipseproj")
|
136
|
+
# #=> #<Metaforce::Transaction:0x1159bd0 @id='04sU0000000Wx6KIAS' @type=:deploy>
|
137
|
+
#
|
138
|
+
# deploy.done?
|
139
|
+
# #=> true
|
140
|
+
#
|
141
|
+
# deploy.status[:state]
|
142
|
+
# #=> "Completed"
|
105
143
|
def deploy(dir, deploy_options={})
|
106
144
|
if dir.is_a?(String)
|
107
145
|
filename = File.join(File.dirname(dir), DEPLOY_ZIP)
|
@@ -135,9 +173,12 @@ module Metaforce
|
|
135
173
|
Transaction.retrieval self, response[:retrieve_response][:result][:id]
|
136
174
|
end
|
137
175
|
|
138
|
-
# Retrieves files specified in the manifest file (package.xml)
|
176
|
+
# Retrieves files specified in the manifest file (package.xml). Specificy any extra +retrieve_request+ options in +extra+.
|
177
|
+
#
|
178
|
+
# == Examples
|
139
179
|
#
|
140
|
-
#
|
180
|
+
# retrieve = client.retrieve_unpackaged File.expand_path("spec/fixtures/sample/src/package.xml")
|
181
|
+
# #=> #<Metaforce::Transaction:0x1159bd0 @id='04sU0000000Wx6KIAS' @type=:retrieve>
|
141
182
|
def retrieve_unpackaged(manifest, extra=nil)
|
142
183
|
if manifest.is_a?(Metaforce::Manifest)
|
143
184
|
package = manifest.to_package
|
@@ -4,24 +4,33 @@ module Metaforce
|
|
4
4
|
|
5
5
|
# Convenience class for deployment/retrieval results
|
6
6
|
class Transaction
|
7
|
+
# The Salesforce ID for this task
|
7
8
|
attr_reader :id
|
9
|
+
# The type of transaction (e.g. _:deploy_, _:retrieve_)
|
8
10
|
attr_reader :type
|
9
11
|
|
10
12
|
def initialize(client, id, type)
|
11
|
-
@id
|
13
|
+
@id = id
|
12
14
|
@client = client
|
13
|
-
@type
|
15
|
+
@type = type
|
14
16
|
end
|
15
17
|
|
18
|
+
# Creates a new transaction and sets type to +:deploy+.
|
16
19
|
def self.deployment(client, id)
|
17
20
|
self.new client, id, :deploy
|
18
21
|
end
|
19
22
|
|
23
|
+
# Creates a new transaction and sets type to +:retrieve+.
|
20
24
|
def self.retrieval(client, id)
|
21
25
|
self.new client, id, :retrieve
|
22
26
|
end
|
23
27
|
|
24
|
-
#
|
28
|
+
# Wrapper for <tt>Client.status</tt>.
|
29
|
+
def status
|
30
|
+
@status = @client.status(@id)
|
31
|
+
end
|
32
|
+
|
33
|
+
# Wrapper for <tt>Client.done?</tt>.
|
25
34
|
def done?
|
26
35
|
@done = @client.done?(@id) unless @done
|
27
36
|
@done
|
@@ -29,13 +38,13 @@ module Metaforce
|
|
29
38
|
alias :complete? :done?
|
30
39
|
alias :completed? :done?
|
31
40
|
|
32
|
-
# Returns the
|
41
|
+
# Returns the decoded content of the returned zip file.
|
33
42
|
def zip_file
|
34
43
|
raise "Request was not a retrieve." if @type != :retrieve
|
35
44
|
Base64.decode64(@result[:zip_file])
|
36
45
|
end
|
37
46
|
|
38
|
-
# Unzips the returned zip file to
|
47
|
+
# Unzips the returned zip file to +destination+.
|
39
48
|
def unzip(destination)
|
40
49
|
zip = zip_file
|
41
50
|
file = Tempfile.new("retrieve")
|
data/lib/metaforce/version.rb
CHANGED
@@ -30,6 +30,17 @@ describe Metaforce::Transaction do
|
|
30
30
|
|
31
31
|
end
|
32
32
|
|
33
|
+
describe ".status" do
|
34
|
+
|
35
|
+
it "returns the status" do
|
36
|
+
savon.expects(:deploy).with(:zip_file => '', :deploy_options => {}).returns(:in_progress)
|
37
|
+
deployment = client.deploy(File.expand_path('../../../fixtures/sample', __FILE__))
|
38
|
+
savon.expects(:check_status).with(:ids => [ "04sU0000000WNWoIAO" ]).returns(:done)
|
39
|
+
deployment.status.should be_a(Hash)
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
|
33
44
|
describe ".result" do
|
34
45
|
|
35
46
|
it "raises an error if .done? hasn't been called" do
|
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.
|
4
|
+
version: 0.3.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -13,7 +13,7 @@ date: 2012-02-03 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: nokogiri
|
16
|
-
requirement: &
|
16
|
+
requirement: &8411610 !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: *
|
24
|
+
version_requirements: *8411610
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: savon
|
27
|
-
requirement: &
|
27
|
+
requirement: &8409890 !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: *
|
35
|
+
version_requirements: *8409890
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: rubyzip
|
38
|
-
requirement: &
|
38
|
+
requirement: &8424970 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ~>
|
@@ -43,10 +43,10 @@ dependencies:
|
|
43
43
|
version: 0.9.5
|
44
44
|
type: :runtime
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *8424970
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: rake
|
49
|
-
requirement: &
|
49
|
+
requirement: &8422930 !ruby/object:Gem::Requirement
|
50
50
|
none: false
|
51
51
|
requirements:
|
52
52
|
- - ! '>='
|
@@ -54,10 +54,10 @@ dependencies:
|
|
54
54
|
version: '0'
|
55
55
|
type: :development
|
56
56
|
prerelease: false
|
57
|
-
version_requirements: *
|
57
|
+
version_requirements: *8422930
|
58
58
|
- !ruby/object:Gem::Dependency
|
59
59
|
name: rspec
|
60
|
-
requirement: &
|
60
|
+
requirement: &8422420 !ruby/object:Gem::Requirement
|
61
61
|
none: false
|
62
62
|
requirements:
|
63
63
|
- - ! '>='
|
@@ -65,10 +65,10 @@ dependencies:
|
|
65
65
|
version: '0'
|
66
66
|
type: :development
|
67
67
|
prerelease: false
|
68
|
-
version_requirements: *
|
68
|
+
version_requirements: *8422420
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: mocha
|
71
|
-
requirement: &
|
71
|
+
requirement: &8421570 !ruby/object:Gem::Requirement
|
72
72
|
none: false
|
73
73
|
requirements:
|
74
74
|
- - ! '>='
|
@@ -76,10 +76,10 @@ dependencies:
|
|
76
76
|
version: '0'
|
77
77
|
type: :development
|
78
78
|
prerelease: false
|
79
|
-
version_requirements: *
|
79
|
+
version_requirements: *8421570
|
80
80
|
- !ruby/object:Gem::Dependency
|
81
81
|
name: savon_spec
|
82
|
-
requirement: &
|
82
|
+
requirement: &8420670 !ruby/object:Gem::Requirement
|
83
83
|
none: false
|
84
84
|
requirements:
|
85
85
|
- - ~>
|
@@ -87,7 +87,7 @@ dependencies:
|
|
87
87
|
version: 0.1.6
|
88
88
|
type: :development
|
89
89
|
prerelease: false
|
90
|
-
version_requirements: *
|
90
|
+
version_requirements: *8420670
|
91
91
|
description: A Ruby gem for interacting with the Salesforce Metadata API
|
92
92
|
email:
|
93
93
|
- eric@ejholmes.net
|
@@ -184,3 +184,4 @@ test_files:
|
|
184
184
|
- spec/lib/dsl_spec.rb
|
185
185
|
- spec/lib/manifest_spec.rb
|
186
186
|
- spec/spec_helper.rb
|
187
|
+
has_rdoc:
|