leap_salesforce 0.1.18 → 0.2.0
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.
- checksums.yaml +4 -4
- data/.gitignore +4 -0
- data/.gitlab-ci.yml +589 -2
- data/.idea/.rakeTasks +2 -2
- data/.idea/leap-salesforce.iml +6 -2
- data/.leap_salesforce.yml +2 -1
- data/ChangeLog +4 -0
- data/Rakefile +1 -1
- data/assets/server.key.enc +0 -0
- data/config/general.rb +2 -0
- data/config/project-scratch-def.json +12 -0
- data/exe/leap_salesforce +7 -4
- data/lib/leap_salesforce/auth.rb +87 -0
- data/lib/leap_salesforce/generator/exe_helpers.rb +15 -17
- data/lib/leap_salesforce/generator/generator.rb +1 -1
- data/lib/leap_salesforce/generator/templates/.gitignore.erb +6 -2
- data/lib/leap_salesforce/generator/templates/.leap_salesforce.yml.erb +1 -0
- data/lib/leap_salesforce/generator/templates/config/credentials/salesforce_oauth2.yml.erb +3 -1
- data/lib/leap_salesforce/generator/templates/config/general.rb.erb +6 -0
- data/lib/leap_salesforce/get_prod_auth.sh +2 -0
- data/lib/leap_salesforce/get_scratch_auth.sh +2 -0
- data/lib/leap_salesforce/loader.rb +26 -0
- data/lib/leap_salesforce/parameters.rb +38 -3
- data/lib/leap_salesforce/rake/sfdx.rake +28 -0
- data/lib/leap_salesforce/soql_data/soql_global_object_data.rb +24 -5
- data/lib/leap_salesforce/soql_data/soql_handler.rb +9 -3
- data/lib/leap_salesforce/soql_data/tooling.rb +15 -0
- data/lib/leap_salesforce/version.rb +1 -1
- data/lib/leap_salesforce.rb +37 -44
- metadata +10 -2
data/ChangeLog
CHANGED
data/Rakefile
CHANGED
Binary file
|
data/config/general.rb
CHANGED
data/exe/leap_salesforce
CHANGED
@@ -16,6 +16,7 @@ module LeapSalesforce
|
|
16
16
|
include LeapSalesforce::ExeHelpers
|
17
17
|
|
18
18
|
OAUTH_WIKI = 'https://gitlab.com/leap-dojo/leap_salesforce/wikis/SetUpOAuthApp'
|
19
|
+
SFDX_WIKI = 'https://gitlab.com/leap-dojo/leap_salesforce/wikis/UsingSfdxAuth'
|
19
20
|
|
20
21
|
desc 'init', 'Create new leap salesforce repository'
|
21
22
|
option :setup_done, default: false, type: :boolean, banner: 'Whether setup is done'
|
@@ -25,14 +26,16 @@ module LeapSalesforce
|
|
25
26
|
option :user_key, banner: 'Key to identify user by'
|
26
27
|
option :password, banner: 'User password'
|
27
28
|
option :environment, banner: 'Environment to set automation code up for'
|
29
|
+
option :sfdx, banner: 'Whether to use sfdx for authentication', default: false, type: :boolean
|
28
30
|
def init
|
29
|
-
|
31
|
+
LeapSalesforce.sfdx = options[:sfdx]
|
32
|
+
wiki = LeapSalesforce.sfdx ? SFDX_WIKI : OAUTH_WIKI
|
30
33
|
unless options[:setup_done]
|
31
|
-
|
34
|
+
# Ask user to create OAuth application by following doc
|
35
|
+
oauth_setup = input_for "Have you set up OAuth application by following #{wiki} (y/n)?", :red
|
32
36
|
exit if oauth_setup.downcase == 'n'
|
33
37
|
end
|
34
|
-
|
35
|
-
query_for_parameters
|
38
|
+
query_for_parameters # TODO: for sfdx
|
36
39
|
generate_files binding, ['Gemfile', 'Rakefile', '.leap_salesforce.yml', '.rspec', '.gitignore',
|
37
40
|
{ config: ['general.rb', { credentials: 'salesforce_oauth2.yml' }] },
|
38
41
|
{ spec: %w[spec_helper.rb limit_spec.rb crud_eg_spec.rb picklists_spec.rb] }]
|
@@ -0,0 +1,87 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require_relative 'error'
|
3
|
+
|
4
|
+
module LeapSalesforce
|
5
|
+
# Code related to authorising in LeapSalesforce
|
6
|
+
# Specific authorisation parameters are stored here. More general settings
|
7
|
+
# are stored at the layer above this
|
8
|
+
module Auth
|
9
|
+
@access_token = nil
|
10
|
+
@instance_url = nil
|
11
|
+
# @return [String] Setup JWT trail head
|
12
|
+
SETUP_JWT_LINK = 'https://trailhead.salesforce.com/content/learn/projects/automate-cicd-with-gitlab/https://trailhead.salesforce.com/content/learn/projects/automate-cicd-with-gitlab/integrate-with-gitlab'
|
13
|
+
class << self
|
14
|
+
# @return [String] Access token taken from sfdx
|
15
|
+
attr_writer :access_token
|
16
|
+
# Instance Url taken from sfdx
|
17
|
+
attr_writer :instance_url
|
18
|
+
# @return [String] Output from SFDX command
|
19
|
+
attr_accessor :sfdx_display_output
|
20
|
+
|
21
|
+
# @return [String] Access token taken from sfdx. Value is extracted if
|
22
|
+
# not cached. If not using sfdx this will not be stored here but
|
23
|
+
# within Soaspec which caches the OAuth result
|
24
|
+
def access_token
|
25
|
+
return @access_token if @access_token
|
26
|
+
|
27
|
+
extract_sfdx_variables
|
28
|
+
@access_token
|
29
|
+
end
|
30
|
+
|
31
|
+
# @return [String] Instance URL taken from sfdx. Value is extracted if
|
32
|
+
# not cached
|
33
|
+
def instance_url
|
34
|
+
return @instance_url if @instance_url
|
35
|
+
|
36
|
+
extract_sfdx_variables
|
37
|
+
@instance_url
|
38
|
+
end
|
39
|
+
|
40
|
+
# @return [Boolean] Whether Sfdx authentication variables are set
|
41
|
+
def sfdx_variables?
|
42
|
+
!(access_token && instance_url).nil?
|
43
|
+
end
|
44
|
+
|
45
|
+
# @return [TrueClass] Whether JWT file exists Exception is raised if it
|
46
|
+
# is not
|
47
|
+
def jwt_file?
|
48
|
+
ENV['JWT_FOLDER'] ||= Dir.exist?('JWT') ? 'JWT' : 'assets'
|
49
|
+
unless File.exist?(File.join(ENV['JWT_FOLDER'], 'server.key'))
|
50
|
+
raise LeapSalesforce::SetupError 'Please create JWT file in ' \
|
51
|
+
" '#{ENV['JWT_FOLDER']}/server.key' following #{SETUP_JWT_LINK}"
|
52
|
+
end
|
53
|
+
|
54
|
+
true
|
55
|
+
end
|
56
|
+
|
57
|
+
# Extract sfdx variables and store them
|
58
|
+
# Set ENV['SCRATCH_ORG'] to true to authenticate and run against sandbox
|
59
|
+
def extract_sfdx_variables
|
60
|
+
script_name = if ENV['SCRATCH_ORG'] && !ENV['SCRATCH_ORG'].empty?
|
61
|
+
puts "Using sandbox #{ENV['SCRATCH_ORG_ALIAS']}"
|
62
|
+
'get_scratch_auth'
|
63
|
+
else
|
64
|
+
'get_prod_auth'
|
65
|
+
end
|
66
|
+
self.sfdx_display_output = `sh #{__dir__}/#{script_name}.sh`
|
67
|
+
self.access_token = from_output 'Access Token'
|
68
|
+
url_obtained = from_output 'Instance Url'
|
69
|
+
self.instance_url = url_obtained[-1] == '/' ? url_obtained[0..-2] : url_obtained
|
70
|
+
LeapSalesforce.client_id = ENV['SF_CONSUMER_KEY']
|
71
|
+
LeapSalesforce.password = :not_needed
|
72
|
+
LeapSalesforce.client_secret = :not_needed
|
73
|
+
end
|
74
|
+
|
75
|
+
private
|
76
|
+
|
77
|
+
def from_output(variable)
|
78
|
+
var_line = sfdx_display_output.lines.find do |line|
|
79
|
+
line.start_with? variable
|
80
|
+
end
|
81
|
+
raise LeapSalesforce::SetupError, "Error retrieving from #{sfdx_display_output}" unless var_line
|
82
|
+
|
83
|
+
var_line.split[-1]
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
@@ -21,28 +21,26 @@ module LeapSalesforce
|
|
21
21
|
|
22
22
|
# Retrieve environment and ensure that environment can be connected to
|
23
23
|
def verify_environment
|
24
|
-
LeapSalesforce.
|
25
|
-
|
26
|
-
'
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
message = "Unable to connect to #{LeapSalesforce.general_url}. Potentially problem with" \
|
31
|
-
' internet or proxy settings'.colorize :red
|
32
|
-
raise LeapSalesforce::SetupError, message
|
33
|
-
else
|
24
|
+
unless LeapSalesforce.sfdx
|
25
|
+
LeapSalesforce.environment = options[:environment] || input_for('Enter the environment you want to set things up for ' \
|
26
|
+
'(This will be parameterised so can be changed later). For production used "prod". Otherwise preference is to use the' \
|
27
|
+
' part of the URL that is unique for the environment')
|
28
|
+
end
|
29
|
+
LeapSalesforce.salesforce_reachable?
|
34
30
|
puts "\u2713 Connection to #{LeapSalesforce.general_url} successful".colorize :green
|
35
31
|
end
|
36
32
|
|
37
33
|
# Retrieve OAuth credentials and verify that they're correct
|
38
34
|
def verify_oauth
|
39
|
-
LeapSalesforce.
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
'
|
44
|
-
|
45
|
-
|
35
|
+
unless LeapSalesforce.sfdx
|
36
|
+
LeapSalesforce.client_id = options[:client_id] || input_for('Client id (Customer Id)')
|
37
|
+
LeapSalesforce.client_secret = options[:client_secret] || STDIN.getpass('Client secret (Consumer Secret)')
|
38
|
+
LeapSalesforce.api_user = ERB.new(options[:username] || input_for('Salesforce username. It is ideal to start with a System admin' \
|
39
|
+
' so that any necessary metadata can be read. More users can be added later. You can use ERB to make name' \
|
40
|
+
' vary according to environment (e.g., test.user@<%= LeapSalesforce.environment %>.my.company.com)')).result(binding)
|
41
|
+
LeapSalesforce.password = options[:password] || STDIN.getpass('Password (Recommendation is that 1 password' \
|
42
|
+
' be shared across all test users to be easier to manage):')
|
43
|
+
end
|
46
44
|
LeapSalesforce.oauth_working?
|
47
45
|
end
|
48
46
|
|
@@ -32,7 +32,7 @@ module LeapSalesforce
|
|
32
32
|
|
33
33
|
# @example Create a spec_helper file and test file in spec folder
|
34
34
|
# generate_files [ { spec: [ 'spec_helper.rb', 'limit_spec.rb' ] } ]
|
35
|
-
# @param [Hash] list_of_files Hash of files to generate for
|
35
|
+
# @param [Hash, Array] list_of_files Hash of files to generate for
|
36
36
|
def generate_files(binding, list_of_files, folder: nil)
|
37
37
|
return create_inner_file(folder, list_of_files, binding) unless list_of_files.respond_to? :each
|
38
38
|
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module LeapSalesforce
|
4
|
+
# For loading dependent code based on configuration
|
5
|
+
module Loader
|
6
|
+
# @return [String] Location of leap_salesforce YAML file
|
7
|
+
LEAP_CONFIG_FILE = '.leap_salesforce.yml'
|
8
|
+
class << self
|
9
|
+
def load_config_file
|
10
|
+
if File.exist? LEAP_CONFIG_FILE
|
11
|
+
leap_config = YAML.load_file LEAP_CONFIG_FILE
|
12
|
+
LeapSalesforce.soql_objects = leap_config.delete('soql_objects')
|
13
|
+
leap_config.each do |key, value|
|
14
|
+
if %w[SF_CONSUMER_KEY client_id client_secret password].include? key
|
15
|
+
LeapSalesforce.logger.warn "Secret key '#{key}' should be in non version" \
|
16
|
+
" controlled #{LeapSalesforce::CREDENTIAL_FILE} not in #{LEAP_CONFIG_FILE}"
|
17
|
+
end
|
18
|
+
LeapSalesforce.send("#{key}=", value)
|
19
|
+
end
|
20
|
+
else
|
21
|
+
LeapSalesforce.logger.warn "No config file found at #{LEAP_CONFIG_FILE} for Leap Salesforce"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -3,6 +3,9 @@
|
|
3
3
|
require_relative 'users/users'
|
4
4
|
require_relative 'soql_object'
|
5
5
|
require 'logger'
|
6
|
+
require_relative 'auth'
|
7
|
+
# @return [String] Tutorial on creating an sfdx app
|
8
|
+
CREATE_APP_LINK = 'https://trailhead.salesforce.com/content/learn/projects/automate-cicd-with-gitlab/enable-dev-hub-and-create-a-connected-app'
|
6
9
|
|
7
10
|
# Adding parameters to set for authentication, environment and other common settings
|
8
11
|
module LeapSalesforce
|
@@ -16,6 +19,10 @@ module LeapSalesforce
|
|
16
19
|
@environment = nil
|
17
20
|
@logger = Logger.new STDOUT
|
18
21
|
@sfdx = false
|
22
|
+
# @access_token = nil
|
23
|
+
@instance_url = nil
|
24
|
+
# @return [String] File where Salesforce credentials are stored
|
25
|
+
CREDENTIAL_FILE = File.join('config', 'credentials', 'salesforce_oauth2.yml')
|
19
26
|
class << self
|
20
27
|
# @return [String] Environment to use for tests. This can be accessed to change the username used to login
|
21
28
|
# to test.salesforce with. This can be set on the command line with 'LEAP_ENV'
|
@@ -23,10 +30,25 @@ module LeapSalesforce
|
|
23
30
|
ENV['LEAP_ENV'] || @environment
|
24
31
|
end
|
25
32
|
|
26
|
-
#
|
33
|
+
# Verify connection to Salesforce environment
|
34
|
+
def salesforce_reachable?
|
35
|
+
RestClient.get(LeapSalesforce.general_url)
|
36
|
+
rescue SocketError
|
37
|
+
message = "Unable to connect to #{LeapSalesforce.general_url}. Potentially problem with" \
|
38
|
+
' internet or proxy settings'.colorize :red
|
39
|
+
raise LeapSalesforce::SetupError, message
|
40
|
+
end
|
41
|
+
|
42
|
+
# @return [TrueClass] If OAuth authentication is working, return true.
|
43
|
+
# Otherwise raise exception
|
27
44
|
def oauth_working?
|
28
|
-
|
29
|
-
|
45
|
+
salesforce_reachable?
|
46
|
+
if LeapSalesforce.sfdx
|
47
|
+
sfdx_auth_setup?
|
48
|
+
else
|
49
|
+
Soaspec::OAuth2.debug_oauth = true
|
50
|
+
Soaspec::OAuth2.new(LeapSalesforce.oauth_settings).access_token
|
51
|
+
end
|
30
52
|
rescue StandardError
|
31
53
|
raise LeapSalesforce::SetupError, "Cannot perform OAuth. See 'logs' folder for details of what was sent"
|
32
54
|
else
|
@@ -35,6 +57,19 @@ module LeapSalesforce
|
|
35
57
|
true
|
36
58
|
end
|
37
59
|
|
60
|
+
# Checks whether sfdx is setup according to standard approach. Errors are
|
61
|
+
# logged
|
62
|
+
# @return [Boolean] Whether sfdx is setup correctly
|
63
|
+
def sfdx_auth_setup?
|
64
|
+
Auth.jwt_file?
|
65
|
+
return true if LeapSalesforce::Auth.sfdx_variables?
|
66
|
+
|
67
|
+
raise LeapSalesforce::SetupError, 'LeapSalesforce::Auth.access_token and ' \
|
68
|
+
'instance_url were not able to be retrieved by sfdx'
|
69
|
+
end
|
70
|
+
|
71
|
+
# OAuth parameters when using a custom Connected application not
|
72
|
+
# using sfdx
|
38
73
|
# @return [Hash] OAuth2 parameters used in connecting to salesforce
|
39
74
|
def oauth_settings
|
40
75
|
settings = {
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Convenience tasks that use sfdx according to common environment variables
|
4
|
+
namespace :sfdx do
|
5
|
+
desc 'Login with credentials'
|
6
|
+
task :login do
|
7
|
+
puts `sfdx force:auth:jwt:grant --clientid $SF_CONSUMER_KEY --jwtkeyfile JWT/server.key --username $SF_USERNAME --setdefaultdevhubusername --setalias HubOrg`
|
8
|
+
end
|
9
|
+
|
10
|
+
task :display do
|
11
|
+
puts `sfdx force:org:display --targetusername samuel.garratt@brave-otter-ttxype.com`
|
12
|
+
end
|
13
|
+
|
14
|
+
desc 'Create dev environment'
|
15
|
+
task :create_dev do
|
16
|
+
puts `sfdx force:org:create --targetdevhubusername HubOrg --setdefaultusername --definitionfile config/project-scratch-def.json --setalias $SCRATCH_ORG_ALIAS --wait 10 --durationdays 7`
|
17
|
+
end
|
18
|
+
|
19
|
+
desc 'Open environment in browser'
|
20
|
+
task :open do
|
21
|
+
puts `sfdx force:org:open`
|
22
|
+
end
|
23
|
+
|
24
|
+
desc 'Delete dev environment'
|
25
|
+
task :delete_dev do
|
26
|
+
puts `sfdx force:org:delete --targetusername $SCRATCH_ORG_ALIAS --noprompt`
|
27
|
+
end
|
28
|
+
end
|
@@ -1,12 +1,16 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require_relative 'tooling'
|
4
|
+
|
3
5
|
# Methods for working with instances of global to soql objects, not global overall
|
4
6
|
# See https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/resources_sobject_describe.htm
|
5
7
|
module SoqlGlobalObjectData
|
8
|
+
include LeapSalesforce::Tooling
|
6
9
|
# @return [Hash] List of ids to delete when deleting a particular object
|
7
10
|
attr_accessor :ids_to_delete
|
8
11
|
|
9
12
|
# Override to handle removing dependent records
|
13
|
+
# @param [String] _id Id of record being deleted
|
10
14
|
def remove_dependent_records(_id); end
|
11
15
|
|
12
16
|
# Return key and value to look up for a provided hash
|
@@ -52,13 +56,14 @@ module SoqlGlobalObjectData
|
|
52
56
|
# @return [String] SOQL query to filter results
|
53
57
|
def soql_lookup_filter(lookup)
|
54
58
|
limit = lookup.delete(:limit)
|
59
|
+
@default_filter ||= 'CreatedDate'
|
55
60
|
conditional = ''
|
56
61
|
lookup.each do |key, value|
|
57
62
|
conditional_term = conditional.empty? ? 'WHERE' : 'AND'
|
58
63
|
key_used = map_key key
|
59
64
|
conditional += "#{conditional_term} #{key_used} #{condition_for(value)} "
|
60
65
|
end
|
61
|
-
query = conditional +
|
66
|
+
query = conditional + "ORDER BY #{@default_filter} DESC NULLS FIRST"
|
62
67
|
query += " LIMIT #{limit}" if limit
|
63
68
|
query
|
64
69
|
end
|
@@ -153,19 +158,19 @@ module SoqlGlobalObjectData
|
|
153
158
|
# @param [Hash] data Key value pairs with data to update
|
154
159
|
# @return [self] SoqlData object representing result of API update call
|
155
160
|
def update(id, data)
|
161
|
+
enforce_type_for id
|
156
162
|
must_pass = data.delete(:must_pass)
|
157
163
|
data = data.transform_values do |value|
|
158
164
|
value.is_a?(Time) ? value.salesforce_format : value
|
159
165
|
end
|
160
166
|
data.transform_keys! { |key| map_key(key) } # Map keys to valid field names
|
161
167
|
SoqlHandler.new("Update #{id}").use
|
162
|
-
|
163
168
|
update = new("Update #{self}, #{id} with '#{data}'", method: :patch,
|
164
169
|
suburl: "sobjects/#{soql_object_name}/#{id}", body: data)
|
165
170
|
update.call
|
166
171
|
return update unless must_pass
|
167
172
|
|
168
|
-
successful?
|
173
|
+
update.successful?
|
169
174
|
update
|
170
175
|
end
|
171
176
|
|
@@ -173,10 +178,11 @@ module SoqlGlobalObjectData
|
|
173
178
|
# @example Delete a contact with a specified id, failing if the delete fails
|
174
179
|
# Contact.delete '0032v00002rgv2pAAA', must_pass: true
|
175
180
|
#
|
176
|
-
# @param [String] id Id of element to remove
|
181
|
+
# @param [String, Symbol] id Id of element to remove
|
177
182
|
# @param [Boolean] must_pass Whether to raise exception if call is not successful
|
178
183
|
# @return [self] Exchange object making delete call
|
179
184
|
def delete(id, must_pass: false)
|
185
|
+
enforce_type_for id
|
180
186
|
SoqlData.ids_to_delete.reject! { |table, id_to_remove| table == self && id_to_remove == id } # Remove id from list to delete
|
181
187
|
remove_dependent_records(id)
|
182
188
|
|
@@ -225,8 +231,10 @@ module SoqlGlobalObjectData
|
|
225
231
|
# @param [Symbol, String] key Key to map to Table field name
|
226
232
|
# @return [String] Field name of Salesforce entity to use
|
227
233
|
def map_key(key)
|
228
|
-
if field_names.include?
|
234
|
+
if field_names.include?(key.to_s)
|
229
235
|
key.to_s
|
236
|
+
elsif field_names.include?(key.to_s.camelize)
|
237
|
+
key.to_s.camelize
|
230
238
|
else
|
231
239
|
return new.send("#{key}_element") if new.respond_to?("#{key}_element")
|
232
240
|
|
@@ -266,4 +274,15 @@ module SoqlGlobalObjectData
|
|
266
274
|
[value[0], value[1..-1]]
|
267
275
|
end
|
268
276
|
end
|
277
|
+
|
278
|
+
private
|
279
|
+
|
280
|
+
# Raise error if incorrect type passed
|
281
|
+
# @param [String, Symbol] id Id to verify
|
282
|
+
def enforce_type_for(id)
|
283
|
+
return if [String, Symbol].include? id.class
|
284
|
+
|
285
|
+
raise ArgumentError,
|
286
|
+
"Id must be String or Symbol but was #{id.class} to delete"
|
287
|
+
end
|
269
288
|
end
|
@@ -7,12 +7,18 @@ require 'soaspec'
|
|
7
7
|
# Credentials are stored either in 'config/credentials' folder or via environment variables
|
8
8
|
# To check out SOQL SCHEMA go to workbench.developerforce.com. Use Sandbox and login
|
9
9
|
class SoqlHandler < Soaspec::RestHandler
|
10
|
-
oauth2 LeapSalesforce.oauth_settings unless LeapSalesforce.sfdx
|
11
10
|
if LeapSalesforce.sfdx
|
12
|
-
# @return [String]
|
11
|
+
# @return [String] Instance Url taken from sfdx
|
13
12
|
def instance_url
|
14
|
-
|
13
|
+
LeapSalesforce::Auth.instance_url
|
15
14
|
end
|
15
|
+
|
16
|
+
# @return [String] Access token taken from sfdx
|
17
|
+
def access_token
|
18
|
+
LeapSalesforce::Auth.access_token
|
19
|
+
end
|
20
|
+
else
|
21
|
+
oauth2 LeapSalesforce.oauth_settings
|
16
22
|
end
|
17
23
|
base_url '<%= instance_url %>/services/data/v<%= api_version %>/'
|
18
24
|
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module LeapSalesforce
|
2
|
+
# Methods to interact with tooling API.
|
3
|
+
# See https://developer.salesforce.com/docs/atlas.en-us.api_tooling.meta/api_tooling/intro_rest_resources.htm
|
4
|
+
module Tooling
|
5
|
+
def tooling_objects
|
6
|
+
new("Tooling sobjects",
|
7
|
+
method: :get, suburl: "tooling/sobjects")
|
8
|
+
end
|
9
|
+
|
10
|
+
def run_test_asynchronous
|
11
|
+
new('Test run async', method: :post,
|
12
|
+
suburl: 'tooling/runTestsAsynchronous/')
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
data/lib/leap_salesforce.rb
CHANGED
@@ -17,58 +17,51 @@ require 'rake'
|
|
17
17
|
require 'factory_bot' # For mass production of data
|
18
18
|
require 'faker' # For fake data
|
19
19
|
require 'leap_salesforce/error'
|
20
|
+
require 'leap_salesforce/loader'
|
20
21
|
|
21
|
-
|
22
|
-
|
22
|
+
module LeapSalesforce
|
23
|
+
leap_logger = LeapSalesforce.logger
|
24
|
+
leap_logger.level = Logger::DEBUG
|
25
|
+
leap_logger.datetime_format = '%Y-%m-%d %H:%M:%S'
|
23
26
|
|
24
|
-
|
25
|
-
|
26
|
-
leap_logger.datetime_format = '%Y-%m-%d %H:%M:%S'
|
27
|
+
LeapSalesforce::Loader.load_config_file
|
28
|
+
raise SetupError, 'LeapSalesforce.environment not set' if environment.nil? && !sfdx
|
27
29
|
|
28
|
-
if File.exist?
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
if %w[client_id client_secret password].include? key
|
33
|
-
leap_logger.warn "Secret key '#{key}' should be in non version" \
|
34
|
-
" controlled #{CREDENTIAL_FILE} not in #{LEAP_CONFIG_FILE}"
|
30
|
+
if File.exist? CREDENTIAL_FILE
|
31
|
+
# Set credentials from credentials file for ConnectedApp
|
32
|
+
YAML.load_file(CREDENTIAL_FILE).each do |key, value|
|
33
|
+
send("#{key}=", value)
|
35
34
|
end
|
36
|
-
LeapSalesforce.send("#{key}=", value)
|
37
35
|
end
|
38
|
-
|
39
|
-
|
40
|
-
|
36
|
+
# Either can be set
|
37
|
+
ENV['SF_CONSUMER_KEY'] ||= client_id
|
38
|
+
self.client_id ||= ENV['SF_CONSUMER_KEY']
|
41
39
|
|
42
|
-
|
40
|
+
config_folder_path = File.join(Dir.pwd, config_folder)
|
41
|
+
general_file = File.join(config_folder_path, 'general')
|
42
|
+
specific_environment_file = File.join(config_folder_path, 'environments',
|
43
|
+
environment)
|
44
|
+
require general_file if File.exist? "#{general_file}.rb"
|
45
|
+
require specific_environment_file if File.exist? "#{specific_environment_file}.rb"
|
43
46
|
|
44
|
-
if
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
47
|
+
if sfdx
|
48
|
+
# Assume authentication already made through 'sfdx force:auth:jwt:grant'
|
49
|
+
unless ENV['SF_USERNAME'] && ENV['SF_CONSUMER_KEY']
|
50
|
+
raise SetupError,
|
51
|
+
'Please set SF_USERNAME and SF_CONSUMER_KEY environment variables'
|
52
|
+
end
|
53
|
+
Auth.jwt_file?
|
54
|
+
else
|
55
|
+
%w[client_id client_secret password].each do |param|
|
56
|
+
raise SetupError, "LeapSalesforce.#{param} not set" if send(param).nil?
|
57
|
+
end
|
55
58
|
end
|
56
|
-
end
|
57
59
|
|
58
|
-
|
59
|
-
|
60
|
-
end
|
61
|
-
|
62
|
-
config_folder = File.join(Dir.pwd, LeapSalesforce.config_folder)
|
63
|
-
general_file = File.join(config_folder, 'general')
|
64
|
-
specific_environment_file = File.join(config_folder, 'environments', LeapSalesforce.environment)
|
65
|
-
require general_file if File.exist? "#{general_file}.rb"
|
66
|
-
require specific_environment_file if File.exist? "#{specific_environment_file}.rb"
|
60
|
+
require 'leap_salesforce/soql_data/soql_data'
|
61
|
+
require 'leap_salesforce/limits'
|
67
62
|
|
68
|
-
|
69
|
-
|
63
|
+
FileUtils.mkdir_p lib_folder unless Dir.exist? lib_folder
|
64
|
+
require_all lib_folder
|
70
65
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
LeapSalesforce.objects_to_verify = SoqlData.descendants if LeapSalesforce.objects_to_verify.empty?
|
66
|
+
self.objects_to_verify = SoqlData.descendants if objects_to_verify.empty?
|
67
|
+
end
|