From e0fbbc57a6420265314f3429c1054c52e4f4f21a Mon Sep 17 00:00:00 2001 From: Paul Prescod Date: Tue, 17 Jan 2023 16:16:18 -0800 Subject: [PATCH] Add a better error message for scratch orgs that cannot be recreated (#3469) 1. Fix up some imports to "modern" syntax. Makes Pylance happy 2. Add a better error for the case where a scratch org config went away after a scratch org was created and before the system tries to re-create it based on its name. 3. Add some assertions that Pylance likes about missing orgs 4. Add a test for the new code. Co-authored-by: James Estevez --- cumulusci/core/keychain/base_project_keychain.py | 15 +++++++++------ .../keychain/tests/test_base_project_keychain.py | 6 ++++++ 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/cumulusci/core/keychain/base_project_keychain.py b/cumulusci/core/keychain/base_project_keychain.py index 10795875e8..78f40a9035 100644 --- a/cumulusci/core/keychain/base_project_keychain.py +++ b/cumulusci/core/keychain/base_project_keychain.py @@ -1,11 +1,8 @@ import sarge -from cumulusci.core.config import ( - BaseConfig, - ConnectedAppOAuthConfig, - ScratchOrgConfig, - ServiceConfig, -) +from cumulusci.core.config import ConnectedAppOAuthConfig, ServiceConfig +from cumulusci.core.config.base_config import BaseConfig +from cumulusci.core.config.scratch_org_config import ScratchOrgConfig from cumulusci.core.exceptions import ( CumulusCIException, CumulusCIUsageError, @@ -60,6 +57,8 @@ def _validate_key(self): def create_scratch_org(self, org_name, config_name, days=None, set_password=True): """Adds/Updates a scratch org config to the keychain from a named config""" scratch_config = self.project_config.lookup(f"orgs__scratch__{config_name}") + if scratch_config is None: + raise OrgNotFound(f"No such org configured: `{config_name}`") if days is not None: # Allow override of scratch config's default days scratch_config["days"] = days @@ -86,6 +85,7 @@ def set_org(self, org_config, global_org=False, save=True): def set_default_org(self, name): """set the default org for tasks and flows by name""" org = self.get_org(name) + assert org is not None self.unset_default_org() org.config["default"] = True org.save() @@ -100,6 +100,7 @@ def unset_default_org(self): """unset the default orgs for tasks""" for org in self.list_orgs(): org_config = self.get_org(org) + assert org_config is not None if org_config.default: del org_config.config["default"] org_config.save() @@ -114,6 +115,7 @@ def get_default_org(self): """retrieve the name and configuration of the default org""" for org in self.list_orgs(): org_config = self.get_org(org) + assert org_config is not None if org_config.default: return org, org_config return None, None @@ -121,6 +123,7 @@ def get_default_org(self): def get_org(self, name: str): """retrieve an org configuration by name key""" org = self._get_org(name) + assert org if org.keychain: assert org.keychain is self else: diff --git a/cumulusci/core/keychain/tests/test_base_project_keychain.py b/cumulusci/core/keychain/tests/test_base_project_keychain.py index 6f18f3f173..06e9757fdc 100644 --- a/cumulusci/core/keychain/tests/test_base_project_keychain.py +++ b/cumulusci/core/keychain/tests/test_base_project_keychain.py @@ -290,3 +290,9 @@ def test_remove_org( keychain.remove_org("test") assert "test" not in keychain.orgs keychain.cleanup_org_cache_dirs.assert_called_once() + + def test_org_definition__missing(self, project_config, key): + """What if a scratch org was created with a YAML definition which was deleted more recently?""" + keychain = BaseProjectKeychain(project_config, key) + with pytest.raises(OrgNotFound, match="No such org"): + keychain.create_scratch_org("no_such_org", "no_such_org")