Skip to content

Commit 7fb0cca

Browse files
author
Paul Prescod
authored
Merge branch 'main' into feature/fake-data-docs
2 parents 6959ed2 + 526c0d2 commit 7fb0cca

6 files changed

Lines changed: 124 additions & 74 deletions

File tree

docs/salesforce.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -219,11 +219,11 @@ In general, you can test Snowfakery files outside of CumulusCI to see if they wo
219219
$ snowfakery recipe.yml
220220
```
221221

222-
If you have a recipe which depends on data from an org, specify the CumulusCI orgname
223-
like this:
222+
If you have a recipe which depends on data from an org,
223+
specify the CumulusCI org name like this:
224224

225225
```s
226-
$ snowfakery recipe.yml --plugin-options orgname qa
226+
$ snowfakery recipe.yml --plugin-options org_name qa
227227
```
228228

229229
When you run the recipe in this way, it will connect to the org to pull data but

snowfakery/data_generator.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ def process_plugins_options(
192192
) -> Mapping[str, object]:
193193
"""Replace option short names with fully qualified names
194194
and convert types of options.
195-
e.g. the option name that the user specifies on the CLI or API is just "orgname"
195+
e.g. the option name that the user specifies on the CLI or API is just "org_name"
196196
but we use the long name internally to avoid clashing with the
197197
user's variable names."""
198198

snowfakery/standard_plugins/Salesforce.py

Lines changed: 73 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -29,26 +29,35 @@
2929

3030
MAX_SALESFORCE_OFFSET = 2000 # Any way around this?
3131

32-
# the option name that the user specifies on the CLI or API is just "orgname"
32+
# the option name that the user specifies on the CLI or API is just "org_name"
3333
# but using this long name internally prevents us from clashing with the
3434
# user's variable names.
35-
plugin_option_name = "snowfakery.standard_plugins.Salesforce.SalesforceQuery.orgname"
35+
plugin_option_org_name = (
36+
"snowfakery.standard_plugins.Salesforce.SalesforceQuery.org_name"
37+
)
38+
plugin_option_org_config = (
39+
"snowfakery.standard_plugins.Salesforce.SalesforceQuery.org_config"
40+
)
41+
plugin_option_project_config = (
42+
"snowfakery.standard_plugins.Salesforce.SalesforceQuery.project_config"
43+
)
3644

3745

3846
class SalesforceConnection:
3947
"""Helper layer above simple_salesforce and salesforce_bulk"""
4048

4149
_sf = None
4250

43-
def __init__(self, get_orgname):
44-
self.get_orgname = get_orgname
51+
def __init__(self, get_project_config_and_org_config):
52+
self.get_project_config_and_org_config = get_project_config_and_org_config
4553
self.logger = getLogger(__name__)
4654

4755
@property
4856
def sf(self):
4957
"""simple_salesforce client"""
5058
if not self._sf:
51-
self._sf, self._bulk = self._get_sf_clients(self.orgname)
59+
project_config, org_config = self.get_project_config_and_org_config()
60+
self._sf, self._bulk = self._get_sf_clients(project_config, org_config)
5261
return self._sf
5362

5463
@property
@@ -57,11 +66,6 @@ def bulk(self):
5766
self.sf # initializes self._bulk as a side-effect
5867
return self._bulk
5968

60-
@property
61-
def orgname(self):
62-
"""Look up the orgname in the scope"""
63-
return self.get_orgname()
64-
6569
def query(self, *args, **kwargs):
6670
"""Query Salesforce through simple_salesforce"""
6771
return self.sf.query(*args, **kwargs)
@@ -108,50 +112,85 @@ def compose_query(self, context_name, **kwargs):
108112
return query
109113

110114
@staticmethod
111-
def _get_sf_clients(orgname):
115+
def _get_sf_clients(project_config, org_config):
116+
from cumulusci.salesforce_api.utils import get_simple_salesforce_connection
112117

113-
try:
114-
from cumulusci.cli.runtime import CliRuntime
115-
from cumulusci.salesforce_api.utils import get_simple_salesforce_connection
118+
sf = get_simple_salesforce_connection(project_config, org_config)
119+
return sf, _init_bulk(sf, org_config)
116120

117-
runtime = CliRuntime(load_keychain=True)
118-
except Exception as e: # pragma: no cover
119-
raise DataGenError("CumulusCI Runtime cannot be loaded", *e.args)
120121

121-
name, org_config = runtime.get_org(orgname)
122-
sf = get_simple_salesforce_connection(runtime.project_config, org_config)
123-
return sf, SalesforceConnection._init_bulk(sf, org_config)
122+
def _init_bulk(sf, org_config):
123+
from salesforce_bulk import SalesforceBulk
124124

125-
@staticmethod
126-
def _init_bulk(sf, org_config):
127-
from salesforce_bulk import SalesforceBulk
125+
return SalesforceBulk(
126+
host=org_config.instance_url.replace("https://", "").rstrip("/"),
127+
sessionId=org_config.access_token,
128+
API_version=sf.sf_version,
129+
)
128130

129-
return SalesforceBulk(
130-
host=org_config.instance_url.replace("https://", "").rstrip("/"),
131-
sessionId=org_config.access_token,
132-
API_version=sf.sf_version,
133-
)
131+
132+
def check_orgconfig(config):
133+
from cumulusci.core.config import BaseConfig
134+
135+
if isinstance(config, BaseConfig):
136+
return config
137+
raise TypeError(f"Should be a CCI Config, not {type(config)}")
134138

135139

136140
class SalesforceConnectionMixin:
137141
_sf_connection = None
138-
allowed_options = [PluginOption(plugin_option_name, str)]
142+
_runtime = None
143+
allowed_options = [
144+
PluginOption(plugin_option_org_name, str),
145+
PluginOption(plugin_option_org_config, check_orgconfig),
146+
PluginOption(plugin_option_project_config, check_orgconfig),
147+
]
139148

140149
@property
141150
def sf_connection(self):
142151
assert self.context
143152
if not self._sf_connection:
144-
self._sf_connection = SalesforceConnection(self.get_orgname)
153+
self._sf_connection = SalesforceConnection(
154+
self.get_project_config_and_org_config
155+
)
145156
return self._sf_connection
146157

147-
def get_orgname(self):
148-
"""Look up the orgname in the scope"""
158+
def get_project_config_and_org_config(self):
159+
fieldvars = self.context.field_vars()
160+
project_config = fieldvars.get(plugin_option_project_config)
161+
org_config = fieldvars.get(plugin_option_org_config)
162+
163+
if not project_config or not org_config:
164+
project_config, org_config = self._get_org_info_from_cli_keychain()
165+
166+
return project_config, org_config
167+
168+
def _get_org_info_from_cli_keychain(self):
169+
org_name = self.get_org_name() # from command line argument
170+
runtime = self._get_CliRuntime() # from CCI CliRuntime
171+
name, org_config = runtime.get_org(org_name)
172+
return runtime.project_config, org_config
173+
174+
def _get_CliRuntime(self):
175+
if self._runtime:
176+
return self._runtime # pragma: no cover
177+
178+
try:
179+
from cumulusci.cli.runtime import CliRuntime
180+
181+
self._runtime = CliRuntime(load_keychain=True)
182+
return self._runtime
183+
except Exception as e: # pragma: no cover
184+
raise DataGenError("CumulusCI Runtime cannot be loaded", *e.args)
185+
186+
def get_org_name(self):
187+
"""Look up the org_name in the scope"""
149188
fieldvars = self.context.field_vars()
150189
try:
151-
return fieldvars[plugin_option_name]
190+
return fieldvars[plugin_option_org_name]
152191
except KeyError:
153192
raise DataGenNameError(
154-
"Orgname is not specified. Use --plugin-option orgname <yourorgname>",
193+
"Orgname is not specified. Use --plugin-option org_name <yourorgname>",
155194
None,
156195
None,
157196
)

snowfakery/version.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
2.0.dev0
1+
2.0.dev1

tests/salesforce/test_where.recipe.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# execute this recipe like this:
22

3-
# snowfakery tests/salesforce/test_where.recipe.yml --plugin-option orgname qa
3+
# snowfakery tests/salesforce/test_where.recipe.yml --plugin-option org_name qa
44

55
- plugin: snowfakery.standard_plugins.Salesforce.SalesforceQuery
66

0 commit comments

Comments
 (0)