def upgrade_user_v7_to_v8(v7_user_config): """ Upgrade a v7 user config file to a v8 user config file. """ errors = get_validation_errors(v7_user_config, version=V7) if errors: raise ValueError( "Cannot upgrade invalid config. Please ensure that your current " "configuration file is valid:\n\n{0}".format( format_errors(errors), ) ) v7_default = load_user_default_config(version=V7) v7_default_config = Config(v7_default) if v7_user_config == v7_default_config: return {} # V8 just removes all of the `$ref` values from the config. upgraded_v7_user_config = Config(copy.deepcopy(v7_user_config)) upgraded_v7_user_config.unref() upgraded_v7_user_config['version'] = V8 return upgraded_v7_user_config
def test_upgrade_custom_key(project): legacy_config_file_path = get_legacy_json_config_file_path(project_dir=project.project_dir) shutil.copyfile( get_default_config_path(version=V3), legacy_config_file_path ) legacy_key = 'compilation.import_remapping' legacy_value = ['import-path-from-legacy=contracts'] upgraded_key = 'compilation.import_remappings' legacy_config = Config(load_config(legacy_config_file_path)) legacy_config[legacy_key] = legacy_value write_config(legacy_config, legacy_config_file_path) logger = logging.getLogger("test.test_upgrade_custom_key") upgrade_configs(project.project_dir, logger, V8) upgraded_project = Project( project_dir=project.project_dir, user_config_file_path=project.user_config_file_path ) assert upgraded_project.config.get(upgraded_key) == legacy_value assert upgraded_project.project_config.get(upgraded_key) == legacy_value default_user_config = Config(load_user_default_config(version=V8)) assert upgraded_project.user_config.get(upgraded_key) == default_user_config.get(upgraded_key)
def test_upgrade_custom_key(project): legacy_config_file_path = get_legacy_json_config_file_path( project_dir=project.project_dir) shutil.copyfile(get_default_config_path(version=V3), legacy_config_file_path) os.remove(project.config_file_path) legacy_key = 'compilation.import_remapping' legacy_value = ['import-path-from-legacy=contracts'] upgraded_key = 'compilation.import_remappings' legacy_config = Config(load_config(legacy_config_file_path)) legacy_config[legacy_key] = legacy_value write_config(legacy_config, legacy_config_file_path) logger = logging.getLogger("test.test_upgrade_custom_key") upgrade_configs(project.project_dir, logger, FIRST_USER_CONFIG_VERSION) upgraded_project = Project( project_dir=project.project_dir, user_config_file_path=project.user_config_file_path) assert upgraded_project.config.get(upgraded_key) == legacy_value assert upgraded_project.project_config.get(upgraded_key) == legacy_value default_user_config = Config( load_user_default_config(version=FIRST_USER_CONFIG_VERSION)) assert upgraded_project.user_config.get( upgraded_key) == default_user_config.get(upgraded_key)
def test_checking_config_truthyness(): empty_config = Config() assert not empty_config assert bool(empty_config) is False non_empty_config = Config({'a': 3}) assert non_empty_config assert bool(non_empty_config) is True
def test_sub_config_does_not_mutate_parent_config(): config = Config({'a': {'b': {'c': 1}}}) assert 'a.b.d' not in config sub_config = config.get_config('a.b') sub_config['d'] = 2 assert 'a.b.d' not in config
def test_checking_config_equality(): config = Config({'a': 1, 'b': 2}) other_config = Config({'a': 1, 'b': 2}) plain_dict = {'a': 1, 'b': 2} m9dict_value = anyconfig.to_container({'a': 1, 'b': 2}) assert config == other_config assert config == plain_dict assert config == m9dict_value
def upgrade_v6_to_v7(v6_base_config): """ Upgrade a v6 config file to a v7 config file. """ errors = get_validation_errors(v6_base_config, version=V6) if errors: raise ValueError( "Cannot upgrade invalid config. Please ensure that your current " "configuration file is valid:\n\n{0}".format( format_errors(errors), ) ) v6_config = Config(v6_base_config) v6_config.unref() v6_default = load_default_config(version=V6) v7_default = load_default_config(version=V7) v6_default_config = Config(v6_default) v6_default_config.unref() v7_default_config = Config(v7_default) v7_default_config.unref() if v6_config == v6_default_config: return v7_default_config # V7 just moved to user config, no change in keys upgraded_v6_config = copy.deepcopy(v6_config) upgraded_v6_config['version'] = V7 return upgraded_v6_config
def upgrade_v7_to_v8(v7_config): """ Upgrade a v7 config file to a v8 config file. """ errors = get_validation_errors(v7_config, version=V7) if errors: raise ValueError( "Cannot upgrade invalid config. Please ensure that your current " "configuration file is valid:\n\n{0}".format( format_errors(errors), )) v7_default = load_default_config(version=V7) v7_default_config = Config(v7_default) v8_default = load_default_config(version=V8) v8_default_config = Config(v8_default) v8_default_config.unref() if v7_config == v7_default_config: return v8_default_config # V8 just removes all of the `$ref` values from the config. upgraded_v7_config = Config(copy.deepcopy(v7_config)) upgraded_v7_config.unref() upgraded_v7_config['version'] = V8 return upgraded_v7_config
def clean_config(self): items = self.project_config.items(flatten=True) default_config = Config(load_default_config(version=self.project_config['version'])) default_config.unref() default_project_keys = [x[0] for x in default_config.items(flatten=True)] for key, value in items: if self.user_config.get(key) == value and key not in default_project_keys: self.project_config.pop(key)
def user_config(self): if self._user_config_cache is None: user_config = Config( config=self._user_config, schema=self._config_schema, ) user_config.unref() self._user_config_cache = user_config self.merge_user_and_project_configs(user_config, self.project_config) return self._user_config_cache
def project_config(self): if self._project_config_cache is None: project_config = Config(config=self._project_config, parent=Config(self._user_config)) project_config.unref() self._project_config_cache = project_config # schema validation # partial project config must be merged to get the entire schema self.merge_user_and_project_configs(self.user_config, project_config) return self._project_config_cache
def project_config(self): if self._project_config_cache is None: project_config = Config( config=self._project_config, parent=Config(self._user_config) ) project_config.unref() self._project_config_cache = project_config # schema validation # partial project config must be merged to get the entire schema self.merge_user_and_project_configs(self.user_config, project_config) return self._project_config_cache
def test_upgrade_to_user_config(project, from_legacy_version): shutil.copyfile( get_default_config_path(version=from_legacy_version), get_legacy_json_config_file_path(project_dir=project.project_dir)) os.remove(project.config_file_path) logger = logging.getLogger("test.test_upgrade_to_user_config") upgrade_configs(project.project_dir, logger, FIRST_USER_CONFIG_VERSION) upgraded_project = Project( project_dir=project.project_dir, user_config_file_path=project.user_config_file_path) expected_user_config = Config( load_user_default_config(FIRST_USER_CONFIG_VERSION)) expected_user_config.unref() expected_project_config = Config( load_default_config(FIRST_USER_CONFIG_VERSION)) expected_project_config.unref() assert upgraded_project.legacy_config_path is None assert upgraded_project.config == expected_user_config assert upgraded_project.user_config == expected_user_config assert upgraded_project.project_config == expected_project_config
def upgrade_user_v6_to_v7(v6_user_config): """ Upgrade a v6 config file to a v7 config file. """ errors = get_validation_errors(v6_user_config, version=V6) if errors: raise ValueError( "Cannot upgrade invalid config. Please ensure that your current " "configuration file is valid:\n\n{0}".format( format_errors(errors), )) v6_default = load_user_default_config(version=V6) v7_default = load_user_default_config(version=V7) v6_default_config = Config(v6_default) v6_default_config.unref() v7_default_config = Config(v7_default) v7_default_config.unref() if v6_user_config == v6_default_config: return v7_default_config # V7 just moved to user config, no change in keys upgraded_v6_user_config = copy.deepcopy(v6_user_config) upgraded_v6_user_config['version'] = V7 return upgraded_v6_user_config
def clean_config(self): items = self.project_config.items(flatten=True) default_config = Config( load_default_config(version=self.project_config['version'])) default_config.unref() default_project_keys = [ x[0] for x in default_config.items(flatten=True) ] for key, value in items: if self.user_config.get( key) == value and key not in default_project_keys: self.project_config.pop(key)
def config(self): if self._config_cache is None: self._config_cache = Config( config=self._project_config, schema=self._project_config_schema, ) return self._config_cache
def test_get_config(): class SubConfig(Config): pass config = Config({'a': {'b': {'c': 1}}}) sub_config_a = config.get_config('a') assert isinstance(sub_config_a, Config) assert not isinstance(sub_config_a, SubConfig) sub_config_b = config.get_config('a', config_class=SubConfig) assert isinstance(sub_config_b, Config) assert isinstance(sub_config_b, SubConfig) sub_config_c = sub_config_b.get_config('b') assert isinstance(sub_config_c, Config) assert not isinstance(sub_config_c, SubConfig)
def merge_user_and_project_configs(self, user_config, project_config): if self._merged_config_cache is None: merged_config = copy.deepcopy(self.user_config) for key, value in self.project_config.items(flatten=True): if key != 'version': merged_config[key] = value Config(config=merged_config, schema=self._config_schema) self._merged_config_cache = merged_config return self._merged_config_cache
def config(self, value): if isinstance(value, Config): self._config_cache = value else: self._project_config = value config_version = self._project_config['version'] self._project_config_schema = load_config_schema(config_version) self._config_cache = Config( config=self._project_config, schema=self._project_config_schema, )
def test_upgrade_to_user_config(project, from_legacy_version): shutil.copyfile( get_default_config_path(version=from_legacy_version), get_legacy_json_config_file_path(project_dir=project.project_dir) ) logger = logging.getLogger("test.test_upgrade_to_user_config") upgrade_configs(project.project_dir, logger, LATEST_VERSION) upgraded_project = Project( project_dir=project.project_dir, user_config_file_path=project.user_config_file_path ) expected_user_config = Config(load_user_default_config(LATEST_VERSION)) expected_user_config.unref() expected_project_config = Config(load_default_config(LATEST_VERSION)) expected_project_config.unref() legacy_config_path = get_legacy_json_config_file_path(project.project_dir) assert not os.path.exists(legacy_config_path) assert upgraded_project.user_config == expected_user_config assert upgraded_project.project_config == expected_project_config
def test_default_config_upgrade(from_to_version, use_config_object): from_version, to_version = from_to_version base_initial_config = load_default_config(version=from_version) expected_config = load_default_config(version=to_version) if use_config_object: config_schema = load_config_schema(version=from_version) initial_config = Config(base_initial_config, schema=config_schema) else: initial_config = base_initial_config upgraded_config = upgrade_config(initial_config, to_version=to_version) assert upgraded_config == expected_config
def test_upgrade_to_user_config(project, from_legacy_version): shutil.copyfile( get_default_config_path(version=from_legacy_version), get_legacy_json_config_file_path(project_dir=project.project_dir)) logger = logging.getLogger("test.test_upgrade_to_user_config") upgrade_configs(project.project_dir, logger, LATEST_VERSION) upgraded_project = Project( project_dir=project.project_dir, user_config_file_path=project.user_config_file_path) expected_user_config = Config(load_user_default_config(LATEST_VERSION)) expected_user_config.unref() expected_project_config = Config(load_default_config(LATEST_VERSION)) expected_project_config.unref() legacy_config_path = get_legacy_json_config_file_path(project.project_dir) assert not os.path.exists(legacy_config_path) assert upgraded_project.user_config == expected_user_config assert upgraded_project.project_config == expected_project_config
) from populus.config.helpers import ( resolve_config, ) MASTER_CONFIG = Config({ 'a': { 'a': 'a.a', }, 'b': { 'a': 'b.a', 'b': 'b.b', }, 'c': { 'a': { 'a': 'c.a.a', 'b': 'c.a.b', }, 'b': { 'a': 'c.b.a', 'b': 'c.b.b', }, }, }) @pytest.mark.parametrize( 'config,expected', ( ({'b': 'b'}, {'b': 'b'}),
def backend_config(): return Config({ 'file_path': FILE_NAME, })
def configure_chain(project, chain_name): """ Interactive configuration of an existing or new chain. - is it external? - rpc or ipc? - rpc/ipc configuration - select default account (web3.eth.defaultAccount) """ try: chain_config = project.get_chain_config(chain_name) is_existing_chain = True except KeyError: chain_config = Config({}) is_existing_chain = False start_msg = "Configuring {status} chain: {chain_name}".format( status="existing" if is_existing_chain else "**new**", chain_name=chain_name, ) logger = logging.getLogger('populus.cli.utils.configure_chain') logger.info(start_msg) logger.info('-' * len(start_msg)) if is_existing_chain: current_configuration_msg = "\n".join(itertools.chain(( "Current Configuration", ), ( " {key} = {value}".format(key=key, value=value) for key, value in chain_config.items() ))) logger.info(current_configuration_msg) # Internal or External internal_or_external_msg = ( "\n\nPopulus can run the blockchain client for you, including " "connecting to the public main and test networks.\n\n " "Should populus manage running this chain?" ) is_internal = click.confirm(internal_or_external_msg, default=True) if not is_internal: chain_config['is_external'] = True # Web3 Provider web3_provider_msg = ( "\n\nWeb3 Provider Choices:\n" "1) IPC socket (default)\n" "2) RPC via HTTP\n\n" "How should populus connect web3.py to this chain?" ) provider = click.prompt(web3_provider_msg, default='ipc') if provider.lower() in {'ipc', '1'}: chain_config['web3.provider.class'] = 'web3.providers.ipc.IPCProvider' elif provider.lower() in {'rpc', '2'}: chain_config['web3.provider.class'] = 'web3.providers.rpc.HTTPProvider' else: unknown_provider_message = ( "Invalid response. Allowed responses are 1/2/ipc/rpc" ) raise click.ClickException(unknown_provider_message) if chain_config['web3.provider.class'] == 'web3.providers.ipc.IPCProvider': custom_ipc_path_msg = ( "\n\nWill this blockchain be running with a non-standard `geth.ipc`" "path?\n\n" ) if click.confirm(custom_ipc_path_msg, default=False): ipc_path_msg = "Path to `geth.ipc` socket?" ipc_path = click.prompt(ipc_path_msg) chain_config['web3.providers.settings.ipc_path'] = ipc_path elif chain_name not in {"mainnet", "ropsten"}: chain_config['web3.providers.settings.ipc_path'] = get_geth_ipc_path( get_local_chain_datadir(project.project_dir, chain_name), ) elif chain_config['web3.provider.class'] == 'web3.providers.rpc.HTTPProvider': custom_rpc_host = ( "\n\nWill the RPC server be bound to `localhost`?" ) if not click.confirm(custom_rpc_host, default=True): rpc_host_msg = "Hostname?" rpc_host = click.prompt(rpc_host_msg) else: rpc_host = 'localhost' custom_rpc_port = ( "\n\nWill the RPC server be listening on port 8545?" ) if not click.confirm(custom_rpc_port, default=True): rpc_port_msg = "Port?" rpc_port = click.prompt(rpc_port_msg) else: rpc_port = '8545' chain_config['web3.providers.settings.rpc_host'] = 'http://{0}:{1}'.format( rpc_host, rpc_port, ) # Save config so that we can spin this chain up. project.config['chains'][chain_name] = chain_config project.write_config() project.load_config() if chain_config.is_external: is_chain_ready_msg = ( "Populus needs to connect to the chain. Press [Enter] when the " "chain is ready for populus" ) click.prompt(is_chain_ready_msg) with project.get_chain(chain_name) as chain: web3 = chain.web3 choose_default_account_msg = ( "This chain will default to sending transactions from " "{0}. Would you like to set a different default " "account?".format(web3.eth.defaultAccount or web3.eth.coinbase) ) if click.confirm(choose_default_account_msg, default=True): default_account = select_account(chain) default_account_key = 'chains.{0}.web3.eth.default_account'.format(chain_name) project.config[default_account_key] = default_account logger.info("Writing project configuration ...") project.write_config() logger.info("Success!")
def config(self, value): if isinstance(value, Config): self._merged_config_cache = value else: self._merged_config_cache = Config(config=value, schema=self._config_schema)