metaforce 0.2.0.alpha → 0.3.0.alpha
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/.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
|
+

|
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
|
-
|