metaforce 0.3.0.alpha → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -4,12 +4,9 @@
4
4
  Metaforce is a Ruby gem for interacting with the [Salesforce Metadata API](http://www.salesforce.com/us/developer/docs/api_meta/index.htm).
5
5
  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
6
 
7
- **Metaforce is in active development and is currently in alpha status. Don't use
8
- it to deploy code to production instances. You've been warned!**
9
-
10
7
  ## Installation
11
8
  ```bash
12
- gem install metaforce --pre
9
+ gem install metaforce
13
10
  ```
14
11
 
15
12
  ## Usage
@@ -64,9 +61,10 @@ end
64
61
  This gem is far from being feature complete. Here's a list of things that still
65
62
  need to be done.
66
63
 
67
- * <del>Implement .retrieve for retrieving metadata.</del>
68
64
  * Implement CRUD based calls <http://www.salesforce.com/us/developer/docs/api_meta/Content/meta_crud_based_calls_intro.htm>.
69
65
  * Implement some helper methods for diffing metadata.
66
+ * Ability to deploy directly from a git repository.
67
+ * <del>Implement .retrieve for retrieving metadata.</del>
70
68
  * <del>Implement a DSL.</del>
71
69
  * And some other stuff that I haven't quite thought of yet...
72
70
 
@@ -76,6 +74,12 @@ feature on a new branch, then send me a pull request with a detailed
76
74
  description. Please provide applicable rspec specs.
77
75
 
78
76
  ## Version History
77
+ **0.3.1** (February 3, 2012)
78
+
79
+ * Dynamically defined helper methods for .list (e.g. `client.list_apex_classes`, `client.list_custom_objects`).
80
+ * The `describe` method now caches the results to minimize latency. `describe!`
81
+ can be used to force a refresh.
82
+
79
83
  **0.3.0.alpha** (January 29, 2012)
80
84
 
81
85
  * Ability to retrieve metadata from an organization.
@@ -49,12 +49,29 @@ module Metaforce
49
49
  response.body[:list_metadata_response][:result]
50
50
  end
51
51
 
52
- # Describe the organization's metadata
52
+ # Defines some helper methods for listing metadata types
53
+ #
54
+ # Example
55
+ #
56
+ # client.list_apex_classes
57
+ # client.list_custom_objects
58
+ METADATA_TYPES.each do |type, value|
59
+ define_method("list_#{value[:plural]}".to_sym) do
60
+ list :type => value[:name]
61
+ end
62
+ end
63
+
64
+ # Describe the organization's metadata and cache the response
53
65
  def describe
66
+ @describe ||= describe!
67
+ end
68
+
69
+ # Describe the organization's metadata
70
+ def describe!
54
71
  response = @client.request(:describe_metadata) do |soap|
55
72
  soap.header = @header
56
73
  end
57
- response.body[:describe_metadata_response][:result]
74
+ @describe = response.body[:describe_metadata_response][:result]
58
75
  end
59
76
 
60
77
  # Checks the status of an async result
@@ -1,4 +1,5 @@
1
1
  require 'nokogiri'
2
+ require 'metaforce/types'
2
3
 
3
4
  module Metaforce
4
5
  class Manifest
@@ -101,17 +102,17 @@ module Metaforce
101
102
 
102
103
  # Returns the components name
103
104
  def component_name(key) # :nodoc:
104
- COMPONENT_TYPE_MAP[key][:name]
105
+ METADATA_TYPES[key][:name]
105
106
  end
106
107
 
107
108
  # Returns the components folder
108
109
  def component_folder(key) # :nodoc:
109
- COMPONENT_TYPE_MAP[key][:folder]
110
+ METADATA_TYPES[key][:folder]
110
111
  end
111
112
 
112
113
  # Returns a key for the component name
113
114
  def component_key(name) # :nodoc:
114
- COMPONENT_TYPE_MAP.each do |key, component|
115
+ METADATA_TYPES.each do |key, component|
115
116
  return key if component[:name] == name
116
117
  end
117
118
  end
@@ -172,10 +173,7 @@ module Metaforce
172
173
  components = []
173
174
  @components.each do |type, members|
174
175
  name = component_name(type)
175
- components.push({
176
- :members => members,
177
- :name => name
178
- })
176
+ components.push :members => members, :name => name
179
177
  end
180
178
  components
181
179
  end
@@ -197,175 +195,5 @@ module Metaforce
197
195
  self
198
196
  end
199
197
 
200
- COMPONENT_TYPE_MAP = {
201
- :action_override => {
202
- :name => "ActionOverride",
203
- :folder => "objects"
204
- },
205
- :analytics_snapshot => {
206
- :name => "AnalyticsSnapshot",
207
- :folder => "analyticsnapshots"
208
- },
209
- :apex_class => {
210
- :name => "ApexClass",
211
- :folder => "classes"
212
- },
213
- :article_type => {
214
- :name => "ArticleType",
215
- :folder => "objects"
216
- },
217
- :apex_component => {
218
- :name => "ApexComponent",
219
- :folder => "components"
220
- },
221
- :apex_page => {
222
- :name => "ApexPage",
223
- :folder => "pages"
224
- },
225
- :apex_trigger => {
226
- :name => "ApexTrigger",
227
- :folder => "triggers"
228
- },
229
- :business_process => {
230
- :name => "BusinessProcess",
231
- :folder => "objects"
232
- },
233
- :custom_application => {
234
- :name => "CustomApplication",
235
- :folder => "applications"
236
- },
237
- :custom_field => {
238
- :name => "CustomField",
239
- :folder => "objects"
240
- },
241
- :custom_labels => {
242
- :name => "CustomLabels",
243
- :folder => "labels"
244
- },
245
- :custom_object => {
246
- :name => "CustomObject",
247
- :folder => "objects"
248
- },
249
- :custom_object_translation => {
250
- :name => "CustomObjectTranslation",
251
- :folder => "objectTranslations"
252
- },
253
- :custom_page_web_link => {
254
- :name => "CustomPageWebLink",
255
- :folder => "weblinks"
256
- },
257
- :custom_site => {
258
- :name => "CustomSite",
259
- :folder => "sites"
260
- },
261
- :custom_tab => {
262
- :name => "CustomTab",
263
- :folder => "tabs"
264
- },
265
- :dashboard => {
266
- :name => "Dashboard",
267
- :folder => "dashboards"
268
- },
269
- :data_category_group => {
270
- :name => "DataCategoryGroup",
271
- :folder => "datacategorygroups"
272
- },
273
- :document => {
274
- :name => "Document",
275
- :folder => "document"
276
- },
277
- :email_template => {
278
- :name => "EmailTemplate",
279
- :folder => "email"
280
- },
281
- :entitlement_template => {
282
- :name => "EntitlementTemplate",
283
- :folder => "entitlementTemplates"
284
- },
285
- :field_set => {
286
- :name => "FieldSet",
287
- :folder => "objects"
288
- },
289
- :home_page_component => {
290
- :name => "HomePageComponent",
291
- :folder => "homePageComponents"
292
- },
293
- :layout => {
294
- :name => "Layout",
295
- :folder => "layouts"
296
- },
297
- :letterhead => {
298
- :name => "Letterhead",
299
- :folder => "letterhead"
300
- },
301
- :list_view => {
302
- :name => "ListView",
303
- :folder => "objects"
304
- },
305
- :named_filter => {
306
- :name => "NamedFilter",
307
- :folder => "objects"
308
- },
309
- :permission_set => {
310
- :name => "PermissionSet",
311
- :folder => "permissionsets"
312
- },
313
- :portal => {
314
- :name => "Portal",
315
- :folder => "portals"
316
- },
317
- :profile => {
318
- :name => "Profile",
319
- :folder => "profiles"
320
- },
321
- :record_type => {
322
- :name => "RecordType",
323
- :folder => "objects"
324
- },
325
- :remote_site_setting => {
326
- :name => "RemoteSiteSetting",
327
- :folder => "remoteSiteSettings"
328
- },
329
- :report => {
330
- :name => "Report",
331
- :folder => "reports"
332
- },
333
- :report_type => {
334
- :name => "ReportType",
335
- :folder => "reportTypes"
336
- },
337
- :scontroler => {
338
- :name => "Scontroler",
339
- :folder => "scontrols"
340
- },
341
- :sharing_reason => {
342
- :name => "SharingReason",
343
- :folder => "objects"
344
- },
345
- :sharing_recalculation => {
346
- :name => "SharingRecalculation",
347
- :folder => "objects"
348
- },
349
- :static_resource => {
350
- :name => "StaticResource",
351
- :folder => "staticResources"
352
- },
353
- :translations => {
354
- :name => "Translations",
355
- :folder => "translations"
356
- },
357
- :validation_rule => {
358
- :name => "ValidationRule",
359
- :folder => "objects"
360
- },
361
- :weblink => {
362
- :name => "Weblink",
363
- :folder => "objects"
364
- },
365
- :workflow => {
366
- :name => "Workflow",
367
- :folder => "workflows"
368
- }
369
- }
370
198
  end
371
199
  end
@@ -0,0 +1,214 @@
1
+ module Metaforce
2
+ METADATA_TYPES = {
3
+ :action_override => {
4
+ :name => "ActionOverride",
5
+ :folder => "objects",
6
+ :plural => :action_overrides
7
+ },
8
+ :analytics_snapshot => {
9
+ :name => "AnalyticsSnapshot",
10
+ :folder => "analyticsnapshots",
11
+ :plural => :analytics_snapshots
12
+ },
13
+ :apex_class => {
14
+ :name => "ApexClass",
15
+ :folder => "classes",
16
+ :plural => :apex_classes
17
+ },
18
+ :article_type => {
19
+ :name => "ArticleType",
20
+ :folder => "objects",
21
+ :plural => :article_types
22
+ },
23
+ :apex_component => {
24
+ :name => "ApexComponent",
25
+ :folder => "components",
26
+ :plural => :apex_components
27
+ },
28
+ :apex_page => {
29
+ :name => "ApexPage",
30
+ :folder => "pages",
31
+ :plural => :apex_pages
32
+ },
33
+ :apex_trigger => {
34
+ :name => "ApexTrigger",
35
+ :folder => "triggers",
36
+ :plural => :apex_triggers
37
+ },
38
+ :business_process => {
39
+ :name => "BusinessProcess",
40
+ :folder => "objects",
41
+ :plural => :business_processes
42
+ },
43
+ :custom_application => {
44
+ :name => "CustomApplication",
45
+ :folder => "applications",
46
+ :plural => :custom_applications
47
+ },
48
+ :custom_field => {
49
+ :name => "CustomField",
50
+ :folder => "objects",
51
+ :plural => :custom_fields
52
+ },
53
+ :custom_labels => {
54
+ :name => "CustomLabels",
55
+ :folder => "labels",
56
+ :plural => :custom_labels
57
+ },
58
+ :custom_object => {
59
+ :name => "CustomObject",
60
+ :folder => "objects",
61
+ :plural => :custom_objects
62
+ },
63
+ :custom_object_translation => {
64
+ :name => "CustomObjectTranslation",
65
+ :folder => "objectTranslations",
66
+ :plural => :custom_object_translations
67
+ },
68
+ :custom_page_web_link => {
69
+ :name => "CustomPageWebLink",
70
+ :folder => "weblinks",
71
+ :plural => :custom_page_web_links
72
+ },
73
+ :custom_site => {
74
+ :name => "CustomSite",
75
+ :folder => "sites",
76
+ :plural => :custom_sites
77
+ },
78
+ :custom_tab => {
79
+ :name => "CustomTab",
80
+ :folder => "tabs",
81
+ :plural => :custom_tabs
82
+ },
83
+ :dashboard => {
84
+ :name => "Dashboard",
85
+ :folder => "dashboards",
86
+ :plural => :dashboards
87
+ },
88
+ :data_category_group => {
89
+ :name => "DataCategoryGroup",
90
+ :folder => "datacategorygroups",
91
+ :plural => :data_category_groups
92
+ },
93
+ :document => {
94
+ :name => "Document",
95
+ :folder => "document",
96
+ :plural => :documents
97
+ },
98
+ :email_template => {
99
+ :name => "EmailTemplate",
100
+ :folder => "email",
101
+ :plural => :email_templates
102
+ },
103
+ :entitlement_template => {
104
+ :name => "EntitlementTemplate",
105
+ :folder => "entitlementTemplates",
106
+ :plural => :entitlement_templates
107
+ },
108
+ :field_set => {
109
+ :name => "FieldSet",
110
+ :folder => "objects",
111
+ :plural => :field_sets
112
+ },
113
+ :home_page_component => {
114
+ :name => "HomePageComponent",
115
+ :folder => "homePageComponents",
116
+ :plural => :home_page_components
117
+ },
118
+ :layout => {
119
+ :name => "Layout",
120
+ :folder => "layouts",
121
+ :plural => :layouts
122
+ },
123
+ :letterhead => {
124
+ :name => "Letterhead",
125
+ :folder => "letterhead",
126
+ :plural => :letterheads
127
+ },
128
+ :list_view => {
129
+ :name => "ListView",
130
+ :folder => "objects",
131
+ :plural => :list_views
132
+ },
133
+ :named_filter => {
134
+ :name => "NamedFilter",
135
+ :folder => "objects",
136
+ :plural => :named_filters
137
+ },
138
+ :permission_set => {
139
+ :name => "PermissionSet",
140
+ :folder => "permissionsets",
141
+ :plural => :permission_sets
142
+ },
143
+ :portal => {
144
+ :name => "Portal",
145
+ :folder => "portals",
146
+ :plural => :portals
147
+ },
148
+ :profile => {
149
+ :name => "Profile",
150
+ :folder => "profiles",
151
+ :plural => :profiles
152
+ },
153
+ :record_type => {
154
+ :name => "RecordType",
155
+ :folder => "objects",
156
+ :plural => :record_types
157
+ },
158
+ :remote_site_setting => {
159
+ :name => "RemoteSiteSetting",
160
+ :folder => "remoteSiteSettings",
161
+ :plural => :remote_site_settings
162
+ },
163
+ :report => {
164
+ :name => "Report",
165
+ :folder => "reports",
166
+ :plural => :reports
167
+ },
168
+ :report_type => {
169
+ :name => "ReportType",
170
+ :folder => "reportTypes",
171
+ :plural => :report_types
172
+ },
173
+ :scontroler => {
174
+ :name => "Scontroler",
175
+ :folder => "scontrols",
176
+ :plural => :scontrolers
177
+ },
178
+ :sharing_reason => {
179
+ :name => "SharingReason",
180
+ :folder => "objects",
181
+ :plural => :sharing_reasons
182
+ },
183
+ :sharing_recalculation => {
184
+ :name => "SharingRecalculation",
185
+ :folder => "objects",
186
+ :plural => :sharing_recalculations
187
+ },
188
+ :static_resource => {
189
+ :name => "StaticResource",
190
+ :folder => "staticResources",
191
+ :plural => :static_resources
192
+ },
193
+ :translations => {
194
+ :name => "Translations",
195
+ :folder => "translations",
196
+ :plural => :translations
197
+ },
198
+ :validation_rule => {
199
+ :name => "ValidationRule",
200
+ :folder => "objects",
201
+ :plural => :validation_rules
202
+ },
203
+ :weblink => {
204
+ :name => "Weblink",
205
+ :folder => "objects",
206
+ :plural => :weblinks
207
+ },
208
+ :workflow => {
209
+ :name => "Workflow",
210
+ :folder => "workflows",
211
+ :plural => :workflows
212
+ }
213
+ }
214
+ end
@@ -1,3 +1,3 @@
1
1
  module Metaforce
2
- VERSION = "0.3.0.alpha"
2
+ VERSION = "0.3.1"
3
3
  end
@@ -12,13 +12,17 @@ describe Metaforce::Metadata::Client do
12
12
  end
13
13
 
14
14
  describe ".list" do
15
- context "when given valid information" do
16
15
 
17
- it "returns an array" do
18
- savon.expects(:list_metadata).with(:queries => [ :type => "ApexClass"]).returns(:objects)
19
- client.list(:type => "ApexClass").should be_an(Array)
20
- end
16
+ it "returns an array" do
17
+ savon.expects(:list_metadata).with(:queries => [ :type => "ApexClass"]).returns(:objects)
18
+ client.list(:type => "ApexClass").should be_an(Array)
19
+ end
21
20
 
21
+ end
22
+
23
+ it "should respond to dynamically defined list methods" do
24
+ Metaforce::METADATA_TYPES.each do |type, value|
25
+ client.respond_to?("list_#{value[:plural]}").should eq(true)
22
26
  end
23
27
  end
24
28
 
@@ -30,6 +34,30 @@ describe Metaforce::Metadata::Client do
30
34
  client.describe.should be_a(Hash)
31
35
  end
32
36
 
37
+ it "caches the response" do
38
+ savon.expects(:describe_metadata).returns(:success)
39
+ client.describe.should be_a(Hash)
40
+ expect { client.describe }.to_not raise_error
41
+ end
42
+
43
+ end
44
+ end
45
+
46
+ describe ".describe!" do
47
+ context "when given valid information" do
48
+
49
+ it "returns a hash" do
50
+ savon.expects(:describe_metadata).returns(:success)
51
+ client.describe!.should be_a(Hash)
52
+ end
53
+
54
+ it "doesn't cache the response" do
55
+ savon.expects(:describe_metadata).returns(:success)
56
+ client.describe!.should be_a(Hash)
57
+ savon.expects(:describe_metadata).returns(:success)
58
+ expect { client.describe! }.to_not raise_error
59
+ end
60
+
33
61
  end
34
62
  end
35
63
 
metadata CHANGED
@@ -1,19 +1,19 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: metaforce
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0.alpha
5
- prerelease: 6
4
+ version: 0.3.1
5
+ prerelease:
6
6
  platform: ruby
7
7
  authors:
8
8
  - Eric J. Holmes
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-01-30 00:00:00.000000000 Z
12
+ date: 2012-02-03 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: nokogiri
16
- requirement: &3632840 !ruby/object:Gem::Requirement
16
+ requirement: &9206270 !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: *3632840
24
+ version_requirements: *9206270
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: savon
27
- requirement: &3631640 !ruby/object:Gem::Requirement
27
+ requirement: &9187580 !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: *3631640
35
+ version_requirements: *9187580
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: rubyzip
38
- requirement: &3630690 !ruby/object:Gem::Requirement
38
+ requirement: &9170720 !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: *3630690
46
+ version_requirements: *9170720
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: rake
49
- requirement: &3629920 !ruby/object:Gem::Requirement
49
+ requirement: &9164330 !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: *3629920
57
+ version_requirements: *9164330
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: rspec
60
- requirement: &3629280 !ruby/object:Gem::Requirement
60
+ requirement: &9145350 !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: *3629280
68
+ version_requirements: *9145350
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: mocha
71
- requirement: &3627890 !ruby/object:Gem::Requirement
71
+ requirement: &9142060 !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: *3627890
79
+ version_requirements: *9142060
80
80
  - !ruby/object:Gem::Dependency
81
81
  name: savon_spec
82
- requirement: &3625600 !ruby/object:Gem::Requirement
82
+ requirement: &9115390 !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: *3625600
90
+ version_requirements: *9115390
91
91
  description: A Ruby gem for interacting with the Salesforce Metadata API
92
92
  email:
93
93
  - eric@ejholmes.net
@@ -109,6 +109,7 @@ files:
109
109
  - lib/metaforce/config.rb
110
110
  - lib/metaforce/dsl.rb
111
111
  - lib/metaforce/manifest.rb
112
+ - lib/metaforce/types.rb
112
113
  - lib/metaforce/version.rb
113
114
  - metaforce.gemspec
114
115
  - spec/.gitignore
@@ -151,9 +152,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
151
152
  required_rubygems_version: !ruby/object:Gem::Requirement
152
153
  none: false
153
154
  requirements:
154
- - - ! '>'
155
+ - - ! '>='
155
156
  - !ruby/object:Gem::Version
156
- version: 1.3.1
157
+ version: '0'
157
158
  requirements: []
158
159
  rubyforge_project: metaforce
159
160
  rubygems_version: 1.8.15