metaforce 0.2.0.alpha → 0.3.0.alpha
Sign up to get free protection for your applications and to get access to all the features.
- data/.travis.yml +5 -0
- data/README.md +53 -5
- data/lib/metaforce/api/metadata.rb +56 -14
- data/lib/metaforce/api/services.rb +7 -0
- data/lib/metaforce/api/transaction.rb +26 -1
- data/lib/metaforce/config.rb +16 -0
- data/lib/metaforce/dsl.rb +42 -0
- data/lib/metaforce/manifest.rb +71 -13
- data/lib/metaforce/version.rb +1 -1
- data/metaforce.gemspec +5 -4
- data/spec/fixtures/requests/check_retrieve_status/success.xml +37 -0
- data/spec/fixtures/requests/retrieve/in_progress.xml +12 -0
- data/spec/lib/api/metadata_spec.rb +54 -18
- data/spec/lib/dsl_spec.rb +93 -0
- metadata +40 -22
- data/.rvmrc +0 -55
data/.travis.yml
ADDED
data/README.md
CHANGED
@@ -1,13 +1,15 @@
|
|
1
1
|
# Metaforce
|
2
|
+
![travis-ci](https://secure.travis-ci.org/ejholmes/metaforce.png)
|
3
|
+
|
2
4
|
Metaforce is a Ruby gem for interacting with the [Salesforce Metadata API](http://www.salesforce.com/us/developer/docs/api_meta/index.htm).
|
3
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.
|
4
6
|
|
5
|
-
Metaforce is in active development and is currently in alpha status. Don't use
|
6
|
-
it to deploy code to production instances. You've been warned
|
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!**
|
7
9
|
|
8
10
|
## Installation
|
9
11
|
```bash
|
10
|
-
gem install metaforce
|
12
|
+
gem install metaforce --pre
|
11
13
|
```
|
12
14
|
|
13
15
|
## Usage
|
@@ -22,7 +24,7 @@ client.describe
|
|
22
24
|
client.list(:type => "CustomObject")
|
23
25
|
# => [{ :created_by_id => "005U0000000EGpcIAG", :created_by_name => "Eric Holmes", ... }]
|
24
26
|
|
25
|
-
deployment = client.deploy(File.
|
27
|
+
deployment = client.deploy(File.dirname(__FILE__))
|
26
28
|
# => #<Metaforce::Transaction:0x00000102779bf8 @id="04sU0000000WNWoIAO" @type=:deploy>
|
27
29
|
|
28
30
|
deployment.done?
|
@@ -32,15 +34,61 @@ deployment.result(:wait_until_done => true)
|
|
32
34
|
# => { :id => "04sU0000000WNWoIAO", :messages => [{ :changed => true ... :success => true }
|
33
35
|
```
|
34
36
|
|
37
|
+
## DSL
|
38
|
+
Metaforce includes a lightweight DSL to make deployments and retrieve's easier.
|
39
|
+
|
40
|
+
```ruby
|
41
|
+
require "metaforce/dsl"
|
42
|
+
include Metaforce::DSL::Metadata
|
43
|
+
|
44
|
+
login :username => 'username', :password => 'password', :security_token => 'security token' do
|
45
|
+
|
46
|
+
deploy File.dirname(__FILE__) do |result|
|
47
|
+
puts "Successful deployment!"
|
48
|
+
puts result
|
49
|
+
end
|
50
|
+
|
51
|
+
retrieve File.expand_path("../src/package.xml", __FILE__) |result, zip|
|
52
|
+
puts "Successful retrieve!"
|
53
|
+
puts result
|
54
|
+
File.open("retrieve.zip", "wb") do |file|
|
55
|
+
file.write(zip)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
retrieve File.expand_path("../src/package.xml", __FILE__), :to => "directory"
|
60
|
+
end
|
61
|
+
```
|
62
|
+
|
35
63
|
## Roadmap
|
36
64
|
This gem is far from being feature complete. Here's a list of things that still
|
37
65
|
need to be done.
|
38
66
|
|
39
|
-
* Implement .retrieve for retrieving metadata
|
67
|
+
* <del>Implement .retrieve for retrieving metadata.</del>
|
40
68
|
* Implement CRUD based calls <http://www.salesforce.com/us/developer/docs/api_meta/Content/meta_crud_based_calls_intro.htm>.
|
41
69
|
* Implement some helper methods for diffing metadata.
|
70
|
+
* <del>Implement a DSL.</del>
|
42
71
|
* And some other stuff that I haven't quite thought of yet...
|
43
72
|
|
73
|
+
## Contributing
|
74
|
+
If you'd like to contribute code, please fork the repository and implement your
|
75
|
+
feature on a new branch, then send me a pull request with a detailed
|
76
|
+
description. Please provide applicable rspec specs.
|
77
|
+
|
78
|
+
## Version History
|
79
|
+
**0.3.0.alpha** (January 29, 2012)
|
80
|
+
|
81
|
+
* Ability to retrieve metadata from an organization.
|
82
|
+
* Added a DSL.
|
83
|
+
|
84
|
+
**0.2.0.alpha** (January 28, 2012)
|
85
|
+
|
86
|
+
* Gem now supports interacting with the metadata api.
|
87
|
+
|
88
|
+
**0.1.0.alpha** (January 10, 2012)
|
89
|
+
|
90
|
+
* Ability to parse and modify package.xml files easily.
|
91
|
+
|
44
92
|
## License
|
45
93
|
Copyright (C) 2012 Eric Holmes
|
46
94
|
|
@@ -7,14 +7,22 @@ require 'ostruct'
|
|
7
7
|
module Metaforce
|
8
8
|
module Metadata
|
9
9
|
class Client
|
10
|
-
DEPLOY_ZIP = 'deploy.zip'
|
11
|
-
RETRIEVE_ZIP = 'retrieve.zip'
|
10
|
+
DEPLOY_ZIP = 'deploy.zip' # :nodoc:
|
11
|
+
RETRIEVE_ZIP = 'retrieve.zip' # :nodoc:
|
12
12
|
|
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
|
+
#
|
17
|
+
# Metaforce::Metadata::Client.new :username => "username",
|
18
|
+
# :password => "password",
|
19
|
+
# :security_token => "security token"
|
13
20
|
def initialize(options=nil)
|
14
21
|
@session = Services::Client.new(options).session
|
15
22
|
@client = Savon::Client.new File.expand_path("../../../../wsdl/#{Metaforce.configuration.api_version}/metadata.xml", __FILE__) do |wsdl|
|
16
23
|
wsdl.endpoint = @session[:metadata_server_url]
|
17
24
|
end
|
25
|
+
@client.http.auth.ssl.verify_mode = :none
|
18
26
|
@header = {
|
19
27
|
"ins0:SessionHeader" => {
|
20
28
|
"ins0:sessionId" => @session[:session_id]
|
@@ -24,11 +32,10 @@ module Metaforce
|
|
24
32
|
|
25
33
|
# Specify an array of component types to list
|
26
34
|
#
|
27
|
-
#
|
28
|
-
#
|
29
|
-
#
|
30
|
-
#
|
31
|
-
# ]
|
35
|
+
# [
|
36
|
+
# { :type => "ApexClass" },
|
37
|
+
# { :type => "ApexComponent" }
|
38
|
+
# ]
|
32
39
|
def list(queries=[])
|
33
40
|
unless queries.is_a?(Array)
|
34
41
|
queries = [ queries ]
|
@@ -73,10 +80,12 @@ module Metaforce
|
|
73
80
|
self.status(id)[:done]
|
74
81
|
end
|
75
82
|
|
76
|
-
# Deploys
|
77
|
-
|
78
|
-
|
79
|
-
|
83
|
+
# Deploys _dir_ to the organisation
|
84
|
+
#
|
85
|
+
# See http://www.salesforce.com/us/developer/docs/api_meta/Content/meta_deploy.htm#deploy_options
|
86
|
+
# for a list of _deploy_options_. Options should be convereted from
|
87
|
+
# camelCase to an :underscored_symbol.
|
88
|
+
def deploy(dir, deploy_options={})
|
80
89
|
if dir.is_a?(String)
|
81
90
|
filename = File.join(File.dirname(dir), DEPLOY_ZIP)
|
82
91
|
zip_contents = create_deploy_file(filename, dir)
|
@@ -84,18 +93,51 @@ module Metaforce
|
|
84
93
|
zip_contents = Base64.encode64(dir.read)
|
85
94
|
end
|
86
95
|
|
87
|
-
yield options if block_given?
|
88
|
-
|
89
96
|
response = @client.request(:deploy) do |soap|
|
90
97
|
soap.header = @header
|
91
98
|
soap.body = {
|
92
99
|
:zip_file => zip_contents,
|
93
|
-
:deploy_options =>
|
100
|
+
:deploy_options => deploy_options
|
94
101
|
}
|
95
102
|
end
|
96
103
|
Transaction.deployment self, response[:deploy_response][:result][:id]
|
97
104
|
end
|
98
105
|
|
106
|
+
# Performs a retrieve
|
107
|
+
#
|
108
|
+
# See http://www.salesforce.com/us/developer/docs/api_meta/Content/meta_retrieve_request.htm
|
109
|
+
# for a list of _retrieve_request_ options. Options should be convereted from
|
110
|
+
# camelCase to an :underscored_symbol.
|
111
|
+
def retrieve(retrieve_request={})
|
112
|
+
response = @client.request(:retrieve) do |soap|
|
113
|
+
soap.header = @header
|
114
|
+
soap.body = {
|
115
|
+
:retrieve_request => retrieve_request
|
116
|
+
}
|
117
|
+
end
|
118
|
+
Transaction.retrieval self, response[:retrieve_response][:result][:id]
|
119
|
+
end
|
120
|
+
|
121
|
+
# Retrieves files specified in the manifest file (package.xml)
|
122
|
+
#
|
123
|
+
# Specificy any extra _retrieve_request_ options in _extra_.
|
124
|
+
def retrieve_unpackaged(manifest, extra=nil)
|
125
|
+
if manifest.is_a?(Metaforce::Manifest)
|
126
|
+
package = manifest.to_package
|
127
|
+
elsif manifest.is_a?(String)
|
128
|
+
package = Metaforce::Manifest.new(File.open(manifest).read).to_package
|
129
|
+
end
|
130
|
+
retrieve_request = {
|
131
|
+
:api_version => Metaforce.configuration.api_version,
|
132
|
+
:single_package => true,
|
133
|
+
:unpackaged => {
|
134
|
+
:types => package
|
135
|
+
}
|
136
|
+
}
|
137
|
+
retrieve_request.merge!(extra) if extra.is_a?(Hash)
|
138
|
+
retrieve(retrieve_request)
|
139
|
+
end
|
140
|
+
|
99
141
|
private
|
100
142
|
|
101
143
|
# Creates the deploy file, reads in the contents and returns the base64
|
@@ -3,8 +3,13 @@ require 'savon'
|
|
3
3
|
module Metaforce
|
4
4
|
module Services
|
5
5
|
class Client
|
6
|
+
# Contains the session_id and metadata_server_url
|
6
7
|
attr_reader :session
|
7
8
|
|
9
|
+
# Initializes a new instance of Client and logs in. _options_ should be a
|
10
|
+
# hash containing the username, password and security token. If options
|
11
|
+
# is nil, it will get the username, password and security token from the
|
12
|
+
# configuration.
|
8
13
|
def initialize(options=nil)
|
9
14
|
options = {
|
10
15
|
:username => Metaforce.configuration.username,
|
@@ -14,11 +19,13 @@ module Metaforce
|
|
14
19
|
@session = self.login(options[:username], options[:password], options[:security_token])
|
15
20
|
end
|
16
21
|
|
22
|
+
# Performs a login and sets @session
|
17
23
|
def login(username, password, security_token=nil)
|
18
24
|
password = "#{password}#{security_token}" unless security_token.nil?
|
19
25
|
client = Savon::Client.new File.expand_path("../../../../wsdl/#{Metaforce.configuration.api_version}/partner.xml", __FILE__) do |wsdl|
|
20
26
|
wsdl.endpoint = wsdl.endpoint.to_s.sub(/login/, 'test') if Metaforce.configuration.test
|
21
27
|
end
|
28
|
+
client.http.auth.ssl.verify_mode = :none
|
22
29
|
response = client.request(:login) do
|
23
30
|
soap.body = {
|
24
31
|
:username => username,
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'base64'
|
2
|
+
|
1
3
|
module Metaforce
|
2
4
|
|
3
5
|
# Convenience class for deployment/retrieval results
|
@@ -26,11 +28,34 @@ module Metaforce
|
|
26
28
|
end
|
27
29
|
alias :complete? :done?
|
28
30
|
alias :completed? :done?
|
31
|
+
|
32
|
+
# Returns the zip file from a retrieval
|
33
|
+
def zip_file
|
34
|
+
raise "Request was not a retrieve." if @type != :retrieve
|
35
|
+
Base64.decode64(@result[:zip_file])
|
36
|
+
end
|
37
|
+
|
38
|
+
# Unzips the returned zip file to _destination_
|
39
|
+
def unzip(destination)
|
40
|
+
zip = zip_file
|
41
|
+
file = Tempfile.new("retrieve")
|
42
|
+
file.write(zip)
|
43
|
+
path = file.path
|
44
|
+
file.close
|
45
|
+
|
46
|
+
Zip::ZipFile.open(path) do |zip|
|
47
|
+
zip.each do |f|
|
48
|
+
path = File.join(destination, f.name)
|
49
|
+
FileUtils.mkdir_p(File.dirname(path))
|
50
|
+
zip.extract(f, path)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
29
54
|
|
30
55
|
# Returns the deploy or retrieve result
|
31
56
|
def result(options={})
|
32
57
|
self.wait_until_done if options[:wait_until_done]
|
33
|
-
raise "Request
|
58
|
+
raise "Request has not completed." unless @done
|
34
59
|
@result = @client.status(@id, @type) if @result.nil?
|
35
60
|
@result
|
36
61
|
end
|
data/lib/metaforce/config.rb
CHANGED
@@ -1,19 +1,35 @@
|
|
1
1
|
module Metaforce
|
2
2
|
class << self
|
3
|
+
# Returns the current Configuration
|
4
|
+
#
|
5
|
+
# Metaforce.configuration.username = "username"
|
6
|
+
# Metaforce.configuration.password = "password"
|
3
7
|
def configuration
|
4
8
|
@configuration ||= Configuration.new
|
5
9
|
end
|
6
10
|
|
11
|
+
# Yields the Configuration
|
12
|
+
#
|
13
|
+
# Metaforce.configure do |config|
|
14
|
+
# config.username = "username"
|
15
|
+
# config.password = "password"
|
16
|
+
# end
|
7
17
|
def configure
|
8
18
|
yield configuration
|
9
19
|
end
|
10
20
|
end
|
11
21
|
|
12
22
|
class Configuration
|
23
|
+
# The Salesforce API version to use. Defaults to 23.0
|
13
24
|
attr_accessor :api_version
|
25
|
+
# The username to use during login.
|
14
26
|
attr_accessor :username
|
27
|
+
# The password to use during login.
|
15
28
|
attr_accessor :password
|
29
|
+
# The security token to use during login.
|
16
30
|
attr_accessor :security_token
|
31
|
+
# Set this to true if you're authentication with a Sandbox instance.
|
32
|
+
# Defaults to false.
|
17
33
|
attr_accessor :test
|
18
34
|
|
19
35
|
def initialize
|
@@ -0,0 +1,42 @@
|
|
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/lib/metaforce/manifest.rb
CHANGED
@@ -4,16 +4,38 @@ module Metaforce
|
|
4
4
|
class Manifest
|
5
5
|
SFDC_API_VERSION = "23.0"
|
6
6
|
|
7
|
-
#
|
8
|
-
#
|
9
|
-
#
|
10
|
-
#
|
11
|
-
#
|
12
|
-
#
|
13
|
-
#
|
14
|
-
#
|
15
|
-
#
|
16
|
-
#
|
7
|
+
# Initializes a new instance of a manifest (package.xml) file.
|
8
|
+
#
|
9
|
+
# It can either take a hash:
|
10
|
+
# {
|
11
|
+
# :apex_class => [
|
12
|
+
# "TestController",
|
13
|
+
# "TestClass"
|
14
|
+
# ],
|
15
|
+
# :apex_component => [
|
16
|
+
# "SiteLogin"
|
17
|
+
# ]
|
18
|
+
# }
|
19
|
+
#
|
20
|
+
# Or an xml string containing the contents of a packge.xml file:
|
21
|
+
# <?xml version="1.0"?>
|
22
|
+
# <Package xmlns="http://soap.sforce.com/2006/04/metadata">
|
23
|
+
# <types>
|
24
|
+
# <members>TestClass</members>
|
25
|
+
# <members>AnotherClass</members>
|
26
|
+
# <name>ApexClass</name>
|
27
|
+
# </types>
|
28
|
+
# <types>
|
29
|
+
# <members>Component</members>
|
30
|
+
# <name>ApexComponent</name>
|
31
|
+
# </types>
|
32
|
+
# <types>
|
33
|
+
# <members>Assets</members>
|
34
|
+
# <name>StaticResource</name>
|
35
|
+
# </types>
|
36
|
+
# <version>23.0</version>
|
37
|
+
# </Package>
|
38
|
+
#
|
17
39
|
def initialize(components={})
|
18
40
|
# Map component type => folder
|
19
41
|
if components.is_a?(Hash)
|
@@ -25,6 +47,8 @@ module Metaforce
|
|
25
47
|
end
|
26
48
|
|
27
49
|
# Adds components to the package
|
50
|
+
#
|
51
|
+
# manifest.add :apex_class, 'SomeClass'
|
28
52
|
def add(type, members=nil)
|
29
53
|
unless members.nil?
|
30
54
|
@components[type] = [] if @components[type].nil?
|
@@ -38,6 +62,8 @@ module Metaforce
|
|
38
62
|
end
|
39
63
|
|
40
64
|
# Removes components from the package
|
65
|
+
#
|
66
|
+
# manifest.remove :apex_class, 'SomeClass'
|
41
67
|
def remove(type, members=nil)
|
42
68
|
unless members.nil?
|
43
69
|
members = [members] if members.is_a?(String)
|
@@ -53,6 +79,8 @@ module Metaforce
|
|
53
79
|
end
|
54
80
|
|
55
81
|
# Filters the components based on a list of files
|
82
|
+
#
|
83
|
+
# manifest.only(['classes/SomeClass'])
|
56
84
|
def only(files)
|
57
85
|
components = @components
|
58
86
|
@components = {}
|
@@ -72,23 +100,41 @@ module Metaforce
|
|
72
100
|
end
|
73
101
|
|
74
102
|
# Returns the components name
|
75
|
-
def component_name(key)
|
103
|
+
def component_name(key) # :nodoc:
|
76
104
|
COMPONENT_TYPE_MAP[key][:name]
|
77
105
|
end
|
78
106
|
|
79
107
|
# Returns the components folder
|
80
|
-
def component_folder(key)
|
108
|
+
def component_folder(key) # :nodoc:
|
81
109
|
COMPONENT_TYPE_MAP[key][:folder]
|
82
110
|
end
|
83
111
|
|
84
112
|
# Returns a key for the component name
|
85
|
-
def component_key(name)
|
113
|
+
def component_key(name) # :nodoc:
|
86
114
|
COMPONENT_TYPE_MAP.each do |key, component|
|
87
115
|
return key if component[:name] == name
|
88
116
|
end
|
89
117
|
end
|
90
118
|
|
91
119
|
# Returns a string containing a package.xml file
|
120
|
+
#
|
121
|
+
# <?xml version="1.0"?>
|
122
|
+
# <Package xmlns="http://soap.sforce.com/2006/04/metadata">
|
123
|
+
# <types>
|
124
|
+
# <members>TestClass</members>
|
125
|
+
# <members>AnotherClass</members>
|
126
|
+
# <name>ApexClass</name>
|
127
|
+
# </types>
|
128
|
+
# <types>
|
129
|
+
# <members>Component</members>
|
130
|
+
# <name>ApexComponent</name>
|
131
|
+
# </types>
|
132
|
+
# <types>
|
133
|
+
# <members>Assets</members>
|
134
|
+
# <name>StaticResource</name>
|
135
|
+
# </types>
|
136
|
+
# <version>23.0</version>
|
137
|
+
# </Package>
|
92
138
|
def to_xml
|
93
139
|
xml_builder = Nokogiri::XML::Builder.new do |xml|
|
94
140
|
xml.Package("xmlns" => "http://soap.sforce.com/2006/04/metadata") {
|
@@ -106,10 +152,22 @@ module Metaforce
|
|
106
152
|
xml_builder.to_xml
|
107
153
|
end
|
108
154
|
|
155
|
+
# Returns the underlying hash structure
|
156
|
+
#
|
157
|
+
# {
|
158
|
+
# :apex_class => [
|
159
|
+
# "TestController",
|
160
|
+
# "TestClass"
|
161
|
+
# ],
|
162
|
+
# :apex_component => [
|
163
|
+
# "SiteLogin"
|
164
|
+
# ]
|
165
|
+
# }
|
109
166
|
def to_hash
|
110
167
|
@components
|
111
168
|
end
|
112
169
|
|
170
|
+
# Used internall my Metaforce::Metadata::Client
|
113
171
|
def to_package
|
114
172
|
components = []
|
115
173
|
@components.each do |type, members|
|
data/lib/metaforce/version.rb
CHANGED
data/metaforce.gemspec
CHANGED
@@ -18,11 +18,12 @@ Gem::Specification.new do |s|
|
|
18
18
|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
19
19
|
s.require_paths = ["lib"]
|
20
20
|
|
21
|
-
s.add_dependency "nokogiri"
|
22
|
-
s.add_dependency "savon"
|
23
|
-
s.add_dependency "rubyzip"
|
21
|
+
s.add_dependency "nokogiri", "~> 1.5.0"
|
22
|
+
s.add_dependency "savon", "~> 0.9.7"
|
23
|
+
s.add_dependency "rubyzip", "~> 0.9.5"
|
24
24
|
|
25
|
+
s.add_development_dependency "rake"
|
25
26
|
s.add_development_dependency "rspec"
|
26
27
|
s.add_development_dependency "mocha"
|
27
|
-
s.add_development_dependency "savon_spec"
|
28
|
+
s.add_development_dependency "savon_spec", "~> 0.1.6"
|
28
29
|
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns="http://soap.sforce.com/2006/04/metadata">
|
3
|
+
<soapenv:Body>
|
4
|
+
<checkRetrieveStatusResponse>
|
5
|
+
<result>
|
6
|
+
<fileProperties>
|
7
|
+
<createdById>005U0000000EGpcIAG</createdById>
|
8
|
+
<createdByName>Eric Holmes</createdByName>
|
9
|
+
<createdDate>2012-01-14T22:11:17.000Z</createdDate>
|
10
|
+
<fileName>classes/TestClass.cls</fileName>
|
11
|
+
<fullName>TestClass</fullName>
|
12
|
+
<id>01pU0000000pDrtIAE</id>
|
13
|
+
<lastModifiedById>005U0000000EGpcIAG</lastModifiedById>
|
14
|
+
<lastModifiedByName>Eric Holmes</lastModifiedByName>
|
15
|
+
<lastModifiedDate>2012-01-15T03:17:28.000Z</lastModifiedDate>
|
16
|
+
<manageableState>unmanaged</manageableState>
|
17
|
+
<type>ApexClass</type>
|
18
|
+
</fileProperties>
|
19
|
+
<fileProperties>
|
20
|
+
<createdById>005U0000000EGpcIAG</createdById>
|
21
|
+
<createdByName>Eric Holmes</createdByName>
|
22
|
+
<createdDate>2012-01-28T03:35:13.400Z</createdDate>
|
23
|
+
<fileName>package.xml</fileName>
|
24
|
+
<fullName>package.xml</fullName>
|
25
|
+
<id/>
|
26
|
+
<lastModifiedById>005U0000000EGpcIAG</lastModifiedById>
|
27
|
+
<lastModifiedByName>Eric Holmes</lastModifiedByName>
|
28
|
+
<lastModifiedDate>2012-01-28T03:35:13.400Z</lastModifiedDate>
|
29
|
+
<manageableState>unmanaged</manageableState>
|
30
|
+
<type>Package</type>
|
31
|
+
</fileProperties>
|
32
|
+
<id>04sU0000000WkdIIAS</id>
|
33
|
+
<zipFile>UEsDBBQACAAIAGYcPEAAAAAAAAAAAAAAAAAVAAAAY2xhc3Nlcy9UZXN0Q2xhc3MuY2xzKyhNyslMVkjOSSwuVghJLS5xBrOquWoBUEsHCKYgavMYAAAAGgAAAFBLAwQUAAgACABmHDxAAAAAAAAAAAAAAAAAHgAAAGNsYXNzZXMvVGVzdENsYXNzLmNscy1tZXRhLnhtbK2RTWsCMRCG7/srltzdibZUkWxECj321PY+xtGmbj7IRPHnN3SluwdBD87tffMM80DU6uy6+kSJbfCtmDZS1ORN2Fq/b8Xnx9tkIVa6UutI59cOmevCe27Fd85xCcABY8O7kAw1JjiYSfkC8hkcZdxiRqGruozCaL/6I3r21EgFo6InIpoD7ulSct/+vTj8Cen96DaU9FTBOI4g6wdoXqhRHiiPjrhcIo2dgiH1CnDV4ZFm8rYYcQ6J7pbjjPnIem2yPZWtS6wU/P+Yrn4BUEsHCKXszAvOAAAA5QEAAFBLAwQUAAgACABmHDxAAAAAAAAAAAAAAAAACwAAAHBhY2thZ2UueG1sTY7LCsIwEEX3/YqQvZlYRUTSFBFcu6gfENNRi82DTpD695Y+0FnNGQ53rip717I3dtQEX/C1kJyht6Fu/KPg1+q82vNSZ+pi7Ms8kA22p4I/U4oHAAomCrqHzqKwwUEu5Q7kFhwmU5tkuM7YMCp9ItK0j+zQ3YaXukJKp9YQKVhOP8kbh/oYsZ+Nkac8+AtUc3mdb4RUsFCmYO6ssy9QSwcIe4wRVJ4AAADlAAAAUEsBAhQAFAAIAAgAZhw8QKYgavMYAAAAGgAAABUAAAAAAAAAAAAAAAAAAAAAAGNsYXNzZXMvVGVzdENsYXNzLmNsc1BLAQIUABQACAAIAGYcPECl7MwLzgAAAOUBAAAeAAAAAAAAAAAAAAAAAFsAAABjbGFzc2VzL1Rlc3RDbGFzcy5jbHMtbWV0YS54bWxQSwECFAAUAAgACABmHDxAe4wRVJ4AAADlAAAACwAAAAAAAAAAAAAAAAB1AQAAcGFja2FnZS54bWxQSwUGAAAAAAMAAwDIAAAATAIAAAAA</zipFile>
|
34
|
+
</result>
|
35
|
+
</checkRetrieveStatusResponse>
|
36
|
+
</soapenv:Body>
|
37
|
+
</soapenv:Envelope>
|
@@ -0,0 +1,12 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns="http://soap.sforce.com/2006/04/metadata">
|
3
|
+
<soapenv:Body>
|
4
|
+
<retrieveResponse>
|
5
|
+
<result>
|
6
|
+
<done>false</done>
|
7
|
+
<id>04sU0000000WkdIIAS</id>
|
8
|
+
<state>InProgress</state>
|
9
|
+
</result>
|
10
|
+
</retrieveResponse>
|
11
|
+
</soapenv:Body>
|
12
|
+
</soapenv:Envelope>
|
@@ -108,17 +108,6 @@ describe Metaforce::Metadata::Client do
|
|
108
108
|
|
109
109
|
end
|
110
110
|
|
111
|
-
# context "when given a file" do
|
112
|
-
|
113
|
-
# it "deploys the file and returns the id of the result" do
|
114
|
-
# path = Tempfile.new('zipfile').tap { |f| f.write('h'); f.close }.path
|
115
|
-
# savon.expects(:deploy).with(:zip_file => "aA==\n", :deploy_options => {}).returns(:in_progress)
|
116
|
-
# id = client.deploy(File.open(path))
|
117
|
-
# id.should eq("04sU0000000WNWoIAO")
|
118
|
-
# end
|
119
|
-
|
120
|
-
# end
|
121
|
-
|
122
111
|
it "allows deploy options to be configured via a hash" do
|
123
112
|
savon.expects(:deploy).with(:zip_file => '', :deploy_options => { :run_all_tests => true }).returns(:in_progress)
|
124
113
|
expect {
|
@@ -126,14 +115,61 @@ describe Metaforce::Metadata::Client do
|
|
126
115
|
}.to_not raise_error
|
127
116
|
end
|
128
117
|
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
118
|
+
end
|
119
|
+
|
120
|
+
describe ".retrieve" do
|
121
|
+
|
122
|
+
let(:manifest) do
|
123
|
+
Metaforce::Manifest.new(File.open(File.expand_path('../../../fixtures/sample/src/package.xml', __FILE__)).read)
|
124
|
+
end
|
125
|
+
|
126
|
+
describe ".retrieve_unpackaged" do
|
127
|
+
|
128
|
+
context "when given a manifest file" do
|
129
|
+
before(:each) do
|
130
|
+
savon.expects(:retrieve).with(:retrieve_request => { :api_version => Metaforce.configuration.api_version, :single_package => true, :unpackaged => { :types => manifest.to_package } }).returns(:in_progress)
|
131
|
+
savon.expects(:check_status).with(:ids => ['04sU0000000WkdIIAS']).returns(:done)
|
132
|
+
savon.expects(:check_retrieve_status).with(:ids => ['04sU0000000WkdIIAS']).returns(:success)
|
134
133
|
end
|
135
|
-
|
134
|
+
|
135
|
+
it "returns a valid retrieve result" do
|
136
|
+
retrieval = client.retrieve_unpackaged(manifest)
|
137
|
+
retrieval.done?
|
138
|
+
result = retrieval.result
|
139
|
+
result.should be_a(Hash)
|
140
|
+
end
|
141
|
+
|
142
|
+
end
|
143
|
+
|
144
|
+
context "when given the path to a manifest file" do
|
145
|
+
before(:each) do
|
146
|
+
savon.expects(:retrieve).with(:retrieve_request => { :api_version => Metaforce.configuration.api_version, :single_package => true, :unpackaged => { :types => manifest.to_package } }).returns(:in_progress)
|
147
|
+
savon.expects(:check_status).with(:ids => ['04sU0000000WkdIIAS']).returns(:done)
|
148
|
+
savon.expects(:check_retrieve_status).with(:ids => ['04sU0000000WkdIIAS']).returns(:success)
|
149
|
+
end
|
150
|
+
|
151
|
+
it "returns a valid retrieve result" do
|
152
|
+
retrieval = client.retrieve_unpackaged(File.expand_path('../../../fixtures/sample/src/package.xml', __FILE__))
|
153
|
+
retrieval.done?
|
154
|
+
result = retrieval.result
|
155
|
+
result.should be_a(Hash)
|
156
|
+
end
|
157
|
+
|
158
|
+
end
|
159
|
+
|
160
|
+
context "when given extra retrieve options" do
|
161
|
+
before(:each) do
|
162
|
+
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)
|
163
|
+
end
|
164
|
+
|
165
|
+
it "merges the options" do
|
166
|
+
expect {
|
167
|
+
retrieval = client.retrieve_unpackaged(File.expand_path('../../../fixtures/sample/src/package.xml', __FILE__), { :extra => true })
|
168
|
+
}.to_not raise_error
|
169
|
+
end
|
170
|
+
|
171
|
+
end
|
136
172
|
end
|
137
|
-
|
173
|
+
|
138
174
|
end
|
139
175
|
end
|
@@ -0,0 +1,93 @@
|
|
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
|
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.
|
4
|
+
version: 0.3.0.alpha
|
5
5
|
prerelease: 6
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,44 +9,55 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-01-
|
12
|
+
date: 2012-01-30 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: nokogiri
|
16
|
-
requirement: &
|
16
|
+
requirement: &3632840 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
|
-
- -
|
19
|
+
- - ~>
|
20
20
|
- !ruby/object:Gem::Version
|
21
|
-
version:
|
21
|
+
version: 1.5.0
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *3632840
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: savon
|
27
|
-
requirement: &
|
27
|
+
requirement: &3631640 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
|
-
- -
|
30
|
+
- - ~>
|
31
31
|
- !ruby/object:Gem::Version
|
32
|
-
version:
|
32
|
+
version: 0.9.7
|
33
33
|
type: :runtime
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *3631640
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: rubyzip
|
38
|
-
requirement: &
|
38
|
+
requirement: &3630690 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ~>
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: 0.9.5
|
44
|
+
type: :runtime
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *3630690
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: rake
|
49
|
+
requirement: &3629920 !ruby/object:Gem::Requirement
|
39
50
|
none: false
|
40
51
|
requirements:
|
41
52
|
- - ! '>='
|
42
53
|
- !ruby/object:Gem::Version
|
43
54
|
version: '0'
|
44
|
-
type: :
|
55
|
+
type: :development
|
45
56
|
prerelease: false
|
46
|
-
version_requirements: *
|
57
|
+
version_requirements: *3629920
|
47
58
|
- !ruby/object:Gem::Dependency
|
48
59
|
name: rspec
|
49
|
-
requirement: &
|
60
|
+
requirement: &3629280 !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: *
|
68
|
+
version_requirements: *3629280
|
58
69
|
- !ruby/object:Gem::Dependency
|
59
70
|
name: mocha
|
60
|
-
requirement: &
|
71
|
+
requirement: &3627890 !ruby/object:Gem::Requirement
|
61
72
|
none: false
|
62
73
|
requirements:
|
63
74
|
- - ! '>='
|
@@ -65,18 +76,18 @@ dependencies:
|
|
65
76
|
version: '0'
|
66
77
|
type: :development
|
67
78
|
prerelease: false
|
68
|
-
version_requirements: *
|
79
|
+
version_requirements: *3627890
|
69
80
|
- !ruby/object:Gem::Dependency
|
70
81
|
name: savon_spec
|
71
|
-
requirement: &
|
82
|
+
requirement: &3625600 !ruby/object:Gem::Requirement
|
72
83
|
none: false
|
73
84
|
requirements:
|
74
|
-
- -
|
85
|
+
- - ~>
|
75
86
|
- !ruby/object:Gem::Version
|
76
|
-
version:
|
87
|
+
version: 0.1.6
|
77
88
|
type: :development
|
78
89
|
prerelease: false
|
79
|
-
version_requirements: *
|
90
|
+
version_requirements: *3625600
|
80
91
|
description: A Ruby gem for interacting with the Salesforce Metadata API
|
81
92
|
email:
|
82
93
|
- eric@ejholmes.net
|
@@ -85,7 +96,7 @@ extensions: []
|
|
85
96
|
extra_rdoc_files: []
|
86
97
|
files:
|
87
98
|
- .gitignore
|
88
|
-
- .
|
99
|
+
- .travis.yml
|
89
100
|
- Gemfile
|
90
101
|
- Guardfile
|
91
102
|
- README.md
|
@@ -96,6 +107,7 @@ files:
|
|
96
107
|
- lib/metaforce/api/services.rb
|
97
108
|
- lib/metaforce/api/transaction.rb
|
98
109
|
- lib/metaforce/config.rb
|
110
|
+
- lib/metaforce/dsl.rb
|
99
111
|
- lib/metaforce/manifest.rb
|
100
112
|
- lib/metaforce/version.rb
|
101
113
|
- metaforce.gemspec
|
@@ -103,6 +115,7 @@ files:
|
|
103
115
|
- spec/fixtures/package.xml
|
104
116
|
- spec/fixtures/requests/check_deploy_status/done.xml
|
105
117
|
- spec/fixtures/requests/check_deploy_status/error.xml
|
118
|
+
- spec/fixtures/requests/check_retrieve_status/success.xml
|
106
119
|
- spec/fixtures/requests/check_status/done.xml
|
107
120
|
- spec/fixtures/requests/check_status/not_done.xml
|
108
121
|
- spec/fixtures/requests/deploy/in_progress.xml
|
@@ -110,6 +123,7 @@ files:
|
|
110
123
|
- spec/fixtures/requests/list_metadata/objects.xml
|
111
124
|
- spec/fixtures/requests/login/failure.xml
|
112
125
|
- spec/fixtures/requests/login/success.xml
|
126
|
+
- spec/fixtures/requests/retrieve/in_progress.xml
|
113
127
|
- spec/fixtures/sample/src/classes/TestClass.cls
|
114
128
|
- spec/fixtures/sample/src/classes/TestClass.cls-meta.xml
|
115
129
|
- spec/fixtures/sample/src/package.xml
|
@@ -117,6 +131,7 @@ files:
|
|
117
131
|
- spec/lib/api/services_spec.rb
|
118
132
|
- spec/lib/api/transaction_spec.rb
|
119
133
|
- spec/lib/config_spec.rb
|
134
|
+
- spec/lib/dsl_spec.rb
|
120
135
|
- spec/lib/manifest_spec.rb
|
121
136
|
- spec/spec_helper.rb
|
122
137
|
- wsdl/23.0/metadata.xml
|
@@ -149,6 +164,7 @@ test_files:
|
|
149
164
|
- spec/fixtures/package.xml
|
150
165
|
- spec/fixtures/requests/check_deploy_status/done.xml
|
151
166
|
- spec/fixtures/requests/check_deploy_status/error.xml
|
167
|
+
- spec/fixtures/requests/check_retrieve_status/success.xml
|
152
168
|
- spec/fixtures/requests/check_status/done.xml
|
153
169
|
- spec/fixtures/requests/check_status/not_done.xml
|
154
170
|
- spec/fixtures/requests/deploy/in_progress.xml
|
@@ -156,6 +172,7 @@ test_files:
|
|
156
172
|
- spec/fixtures/requests/list_metadata/objects.xml
|
157
173
|
- spec/fixtures/requests/login/failure.xml
|
158
174
|
- spec/fixtures/requests/login/success.xml
|
175
|
+
- spec/fixtures/requests/retrieve/in_progress.xml
|
159
176
|
- spec/fixtures/sample/src/classes/TestClass.cls
|
160
177
|
- spec/fixtures/sample/src/classes/TestClass.cls-meta.xml
|
161
178
|
- spec/fixtures/sample/src/package.xml
|
@@ -163,5 +180,6 @@ test_files:
|
|
163
180
|
- spec/lib/api/services_spec.rb
|
164
181
|
- spec/lib/api/transaction_spec.rb
|
165
182
|
- spec/lib/config_spec.rb
|
183
|
+
- spec/lib/dsl_spec.rb
|
166
184
|
- spec/lib/manifest_spec.rb
|
167
185
|
- spec/spec_helper.rb
|
data/.rvmrc
DELETED
@@ -1,55 +0,0 @@
|
|
1
|
-
#!/usr/bin/env bash
|
2
|
-
|
3
|
-
# This is an RVM Project .rvmrc file, used to automatically load the ruby
|
4
|
-
# development environment upon cd'ing into the directory
|
5
|
-
|
6
|
-
# First we specify our desired <ruby>[@<gemset>], the @gemset name is optional.
|
7
|
-
environment_id="ruby-1.9.2-p290@metaforce"
|
8
|
-
|
9
|
-
#
|
10
|
-
# Uncomment following line if you want options to be set only for given project.
|
11
|
-
#
|
12
|
-
# PROJECT_JRUBY_OPTS=( --1.9 )
|
13
|
-
|
14
|
-
#
|
15
|
-
# First we attempt to load the desired environment directly from the environment
|
16
|
-
# file. This is very fast and efficient compared to running through the entire
|
17
|
-
# CLI and selector. If you want feedback on which environment was used then
|
18
|
-
# insert the word 'use' after --create as this triggers verbose mode.
|
19
|
-
#
|
20
|
-
if [[ -d "${rvm_path:-$HOME/.rvm}/environments" \
|
21
|
-
&& -s "${rvm_path:-$HOME/.rvm}/environments/$environment_id" ]]
|
22
|
-
then
|
23
|
-
\. "${rvm_path:-$HOME/.rvm}/environments/$environment_id"
|
24
|
-
|
25
|
-
if [[ -s "${rvm_path:-$HOME/.rvm}/hooks/after_use" ]]
|
26
|
-
then
|
27
|
-
. "${rvm_path:-$HOME/.rvm}/hooks/after_use"
|
28
|
-
fi
|
29
|
-
else
|
30
|
-
# If the environment file has not yet been created, use the RVM CLI to select.
|
31
|
-
if ! rvm --create "$environment_id"
|
32
|
-
then
|
33
|
-
echo "Failed to create RVM environment '${environment_id}'."
|
34
|
-
return 1
|
35
|
-
fi
|
36
|
-
fi
|
37
|
-
|
38
|
-
#
|
39
|
-
# If you use an RVM gemset file to install a list of gems (*.gems), you can have
|
40
|
-
# it be automatically loaded. Uncomment the following and adjust the filename if
|
41
|
-
# necessary.
|
42
|
-
#
|
43
|
-
# filename=".gems"
|
44
|
-
# if [[ -s "$filename" ]]
|
45
|
-
# then
|
46
|
-
# rvm gemset import "$filename" | grep -v already | grep -v listed | grep -v complete | sed '/^$/d'
|
47
|
-
# fi
|
48
|
-
|
49
|
-
# If you use bundler, this might be useful to you:
|
50
|
-
# if command -v bundle && [[ -s Gemfile ]]
|
51
|
-
# then
|
52
|
-
# bundle install
|
53
|
-
# fi
|
54
|
-
|
55
|
-
|