def test_check_org_overwrite_scratch_exists(self): config = CliRuntime() config.keychain.get_org = mock.Mock( return_value=OrgConfig({ "scratch": True, "created": True }, "test")) with self.assertRaises(click.ClickException): config.check_org_overwrite("test")
def test_check_org_expired(self): config = CliRuntime() config.keychain = mock.Mock() org_config = OrgConfig( { "scratch": True, "date_created": date.today() - timedelta(days=2), "expired": True, }, "test", ) config.check_org_expired("test", org_config) config.keychain.create_scratch_org.assert_called_once()
def test_check_org_expired_decline(self, confirm): config = CliRuntime() config.keychain = mock.Mock() org_config = OrgConfig( { "scratch": True, "date_created": date.today() - timedelta(days=2), "expired": True, }, "test", ) confirm.return_value = False with self.assertRaises(click.ClickException): config.check_org_expired("test", org_config)
def test_get_keychain_key__env_takes_precedence(self, keyring): if os.environ.get("CUMULUSCI_KEYCHAIN_CLASS"): del os.environ["CUMULUSCI_KEYCHAIN_CLASS"] keyring.get_password.return_value = "overridden" config = CliRuntime() self.assertEqual(self.key, config.keychain.key)
def test_get_keychain_key__generates_key(self, keyring): del os.environ["CUMULUSCI_KEY"] keyring.get_password.return_value = None config = CliRuntime() self.assertNotEqual(self.key, config.keychain.key) self.assertEqual(16, len(config.keychain.key))
def test_get_keychain_key__warns_if_generated_key_cannot_be_stored( self, keyring): del os.environ["CUMULUSCI_KEY"] keyring.get_password.side_effect = Exception with self.assertRaises(click.UsageError): CliRuntime()
def test_get_keychain_key__migrates_from_env_to_keyring(self, keyring): keyring.get_password.return_value = None config = CliRuntime() self.assertEqual(self.key, config.keychain.key) keyring.set_password.assert_called_once_with("cumulusci", "CUMULUSCI_KEY", self.key)
def project_config(self): if self._project_config is None: if CURRENT_TASK.stack and isinstance(CURRENT_TASK.stack[0], Robot): # If CumulusCI is running a task, use that task's config return CURRENT_TASK.stack[0].project_config else: logger.console("Initializing CumulusCI config\n") self._project_config = CliRuntime().project_config return self._project_config
def runtime(request): """Get the CumulusCI runtime for the current working directory.""" # if there is a real orgname, use a real CliRuntime # to get access to it if sf_pytest_cli_orgname(request): return CliRuntime() else: return BaseCumulusCI()
def test_init(self): config = CliRuntime() for key in {"cumulusci", "tasks", "flows", "services", "orgs", "project"}: self.assertIn(key, config.global_config.config) self.assertEqual("CumulusCI", config.project_config.project__name) for key in {"services", "orgs", "app"}: self.assertIn(key, config.keychain.config) self.assertIn(config.project_config.repo_root, sys.path)
def test_get_keychain_key__generates_key(self, keyring): with mock.patch.dict(os.environ): del os.environ["CUMULUSCI_KEY"] if os.environ.get("CUMULUSCI_KEYCHAIN_CLASS"): del os.environ["CUMULUSCI_KEYCHAIN_CLASS"] keyring.get_password.return_value = None config = CliRuntime() self.assertNotEqual(self.key, config.keychain.key) self.assertEqual(16, len(config.keychain.key))
def main(args=None): """Main CumulusCI CLI entry point. This runs as the first step in processing any CLI command. This wraps the `click` library in order to do some initialization and centralized error handling. """ with contextlib.ExitStack() as stack: args = args or sys.argv # Check for updates _unless_ we've been asked to output JSON, # or if we're going to check anyway as part of the `version` command. is_version_command = len(args) > 1 and args[1] == "version" if "--json" not in args and not is_version_command: check_latest_version() # Load CCI config global RUNTIME RUNTIME = CliRuntime(load_keychain=False) RUNTIME.check_cumulusci_version() # Configure logging debug = "--debug" in args if debug: args.remove("--debug") # Only create logfiles for commands # that are not `cci gist` is_gist_command = len(args) > 2 and args[2] == "gist" if not is_gist_command: logger = get_gist_logger() stack.enter_context(tee_stdout_stderr(args, logger)) init_logger(log_requests=debug) # Hand CLI processing over to click, but handle exceptions try: cli(standalone_mode=False) except click.Abort: # Keyboard interrupt show_debug_info() if debug else click.echo("\nAborted!") sys.exit(1) except Exception as e: show_debug_info() if debug else handle_exception( e, is_gist_command) sys.exit(1)
def _get_CliRuntime(self): if self._runtime: return self._runtime # pragma: no cover try: from cumulusci.cli.runtime import CliRuntime self._runtime = CliRuntime(load_keychain=True) return self._runtime except Exception as e: # pragma: no cover raise DataGenError("CumulusCI Runtime cannot be loaded", *e.args)
def test_get_keychain_key__env_takes_precedence(self, keyring): keyring.get_password.return_value = "overridden" config = CliRuntime() self.assertEqual(self.key, config.keychain.key)
def test_load_project_config_error(self, load_proj_cfg_mock): load_proj_cfg_mock.side_effect = ConfigError with self.assertRaises(click.UsageError): CliRuntime()
def test_alert__os_error(self, echo_mock, shell_mock): shell_mock.side_effect = OSError config = CliRuntime() config.alert("hello") echo_mock.assert_called_once() shell_mock.assert_called_once()
def test_check_cumulusci_version(self): config = CliRuntime() config.project_config.minimum_cumulusci_version = "999" with self.assertRaises(click.UsageError): config.check_cumulusci_version()
def runtime(): """Get the CumulusCI runtime for the current working directory.""" return CliRuntime()
def test_check_org_overwrite_not_found(self): config = CliRuntime() config.keychain.get_org = mock.Mock(side_effect=OrgNotFound) self.assertTrue(config.check_org_overwrite("test"))
def get_github_user(): keychain_class = CliRuntime().get_keychain_class() keychain = keychain_class(CliRuntime().project_config, CliRuntime().get_keychain_key()) github_config = keychain.get_service("github") return github_config.username, github_config.password