def _generate_full_mode( ctx: Context, protocol_generator: ProtocolGenerator, protocol_spec: ProtocolSpecification, existing_id_list: Set[PublicId], language: str, ) -> None: """Generate a protocol in 'full' mode, and add it to the configuration file and agent.""" try: warning_message = protocol_generator.generate(protobuf_only=False, language=language) if warning_message is not None: click.echo(warning_message) # Add the item to the configurations logger.debug("Registering the {} into {}".format( PROTOCOL, DEFAULT_AEA_CONFIG_FILE)) existing_id_list.add( PublicId(protocol_spec.author, protocol_spec.name, protocol_spec.version)) ctx.agent_loader.dump( ctx.agent_config, open_file(os.path.join(ctx.cwd, DEFAULT_AEA_CONFIG_FILE), "w"), ) except FileExistsError: raise click.ClickException( # pragma: no cover "A {} with this name already exists. Please choose a different name and try again." .format(PROTOCOL)) except Exception as e: raise click.ClickException( "Protocol is NOT generated. The following error happened while generating the protocol:\n" + str(e)) fingerprint_item(ctx, PROTOCOL, protocol_spec.public_id)
def fingerprint_all(ctx: Context) -> None: """ Fingerprint all non-vendor packages. :param ctx: the CLI context. :return: None """ aea_project_path = Path(ctx.cwd) for package_path in get_non_vendor_package_path(aea_project_path): item_type = package_path.parent.name[:-1] config = load_item_config(item_type, package_path) fingerprint_item(ctx, item_type, config.public_id)
def _eject_item(ctx: Context, item_type: str, public_id: PublicId): """ Eject item from installed (vendor) to custom folder. :param ctx: context object. :param item_type: item type. :param public_id: item public ID. :return: None :raises: ClickException if item is absent at source path or present at destenation path. """ item_type_plural = item_type + "s" if not is_item_present(ctx, item_type, public_id): # pragma: no cover raise click.ClickException( "{} {} not found in agent's vendor items.".format( item_type.title(), public_id)) src = get_package_path(ctx, item_type, public_id) dst = get_package_path(ctx, item_type, public_id, is_vendor=False) if is_item_present(ctx, item_type, public_id, is_vendor=False): # pragma: no cover raise click.ClickException( "{} {} is already in a non-vendor item.".format( item_type.title(), public_id)) ctx.clean_paths.append(dst) copy_package_directory(Path(src), dst) try_to_load_agent_config(ctx) new_public_id = PublicId(author=ctx.agent_config.author, name=public_id.name, version=DEFAULT_VERSION) update_item_config(item_type, Path(dst), author=new_public_id.author, version=new_public_id.version) update_item_public_id_in_init(item_type, Path(dst), new_public_id) supported_items = getattr(ctx.agent_config, item_type_plural) for p_id in supported_items: if p_id.author == public_id.author and p_id.name == public_id.name: present_public_id = p_id break supported_items.add(new_public_id) supported_items.remove(present_public_id) update_item_config("agent", Path(ctx.cwd), **{item_type_plural: supported_items}) shutil.rmtree(src) fingerprint_item(ctx, item_type, new_public_id) click.echo("Successfully ejected {} {} to {} as {}.".format( item_type, public_id, dst, new_public_id))
def _generate_item(ctx: Context, item_type: str, specification_path: str): """Generate an item based on a specification and add it to the configuration file and agent.""" # Get existing items existing_id_list = getattr(ctx.agent_config, "{}s".format(item_type)) existing_item_list = [public_id.name for public_id in existing_id_list] item_type_plural = item_type + "s" # Load item specification yaml file try: protocol_spec = load_protocol_specification(specification_path) except Exception as e: raise click.ClickException(str(e)) protocol_directory_path = os.path.join( ctx.cwd, item_type_plural, protocol_spec.name ) # Check if we already have an item with the same name in the agent config logger.debug( "{} already supported by the agent: {}".format( item_type_plural, existing_item_list ) ) if protocol_spec.name in existing_item_list: raise click.ClickException( "A {} with name '{}' already exists. Aborting...".format( item_type, protocol_spec.name ) ) # Check if we already have a directory with the same name in the resource directory (e.g. protocols) of the agent's directory if os.path.exists(protocol_directory_path): raise click.ClickException( "A directory with name '{}' already exists. Aborting...".format( protocol_spec.name ) ) ctx.clean_paths.append(protocol_directory_path) try: agent_name = ctx.agent_config.agent_name click.echo( "Generating {} '{}' and adding it to the agent '{}'...".format( item_type, protocol_spec.name, agent_name ) ) output_path = os.path.join(ctx.cwd, item_type_plural) protocol_generator = ProtocolGenerator(specification_path, output_path) warning_message = protocol_generator.generate() if warning_message is not None: click.echo(warning_message) # Add the item to the configurations logger.debug( "Registering the {} into {}".format(item_type, DEFAULT_AEA_CONFIG_FILE) ) existing_id_list.add( PublicId(protocol_spec.author, protocol_spec.name, protocol_spec.version) ) ctx.agent_loader.dump( ctx.agent_config, open(os.path.join(ctx.cwd, DEFAULT_AEA_CONFIG_FILE), "w") ) except FileExistsError: raise click.ClickException( # pragma: no cover "A {} with this name already exists. Please choose a different name and try again.".format( item_type ) ) except ProtocolSpecificationParseError as e: raise click.ClickException( # pragma: no cover "The following error happened while parsing the protocol specification: " + str(e) ) except Exception as e: raise click.ClickException( "Protocol is NOT generated. The following error happened while generating the protocol:\n" + str(e) ) fingerprint_item(ctx, PROTOCOL, protocol_spec.public_id)
def scaffold_item(ctx: Context, item_type: str, item_name: str) -> None: """ Add an item scaffolding to the configuration file and agent. :param ctx: Context object. :param item_type: type of item. :param item_name: item name. :return: None :raises ClickException: if some error occures. """ validate_package_name(item_name) author_name = ctx.agent_config.author loader = getattr(ctx, f"{item_type}_loader") default_config_filename = globals( )[f"DEFAULT_{item_type.upper()}_CONFIG_FILE"] item_type_plural = item_type + "s" existing_ids = getattr(ctx.agent_config, f"{item_type}s") existing_ids_only_author_and_name = map(lambda x: (x.author, x.name), existing_ids) # check if we already have an item with the same public id if (author_name, item_name) in existing_ids_only_author_and_name: raise click.ClickException( f"A {item_type} with name '{item_name}' already exists. Aborting..." ) agent_name = ctx.agent_config.agent_name click.echo( f"Adding {item_type} scaffold '{item_name}' to the agent '{agent_name}'..." ) # create the item folder Path(item_type_plural).mkdir(exist_ok=True) dest = os.path.join(item_type_plural, item_name) if os.path.exists(dest): raise click.ClickException( f"A {item_type} with this name already exists. Please choose a different name and try again." ) ctx.clean_paths.append(str(dest)) try: # copy the item package into the agent project. src = Path(os.path.join(AEA_DIR, item_type_plural, "scaffold")) logger.debug(f"Copying {item_type} modules. src={src} dst={dest}") shutil.copytree(src, dest) # add the item to the configurations. logger.debug( f"Registering the {item_type} into {DEFAULT_AEA_CONFIG_FILE}") new_public_id = PublicId(author_name, item_name, DEFAULT_VERSION) existing_ids.add(new_public_id) with open_file(os.path.join(ctx.cwd, DEFAULT_AEA_CONFIG_FILE), "w") as fp: ctx.agent_loader.dump(ctx.agent_config, fp) # ensure the name in the yaml and the name of the folder are the same config_filepath = Path(ctx.cwd, item_type_plural, item_name, default_config_filename) with open_file(config_filepath) as fp: config = loader.load(fp) config.name = item_name config.author = author_name with open_file(config_filepath, "w") as fp: loader.dump(config, fp) # update 'PUBLIC_ID' variable with the right public id in connection.py! for file_name in ["__init__.py", "connection.py"]: file_path = Path(dest) / file_name if not file_path.exists(): continue py_file = Path(file_path) py_file.write_text( re.sub(SCAFFOLD_PUBLIC_ID, str(new_public_id), py_file.read_text())) # fingerprint item. fingerprint_item(ctx, item_type, new_public_id) if ctx.config.get("with_symlinks", False): click.echo( "Adding symlinks from vendor to non-vendor and packages to vendor folders." ) create_symlink_vendor_to_local(ctx, item_type, new_public_id) create_symlink_packages_to_vendor(ctx) except ValidationError: raise click.ClickException( f"Error when validating the {item_type} configuration file.") except Exception as e: raise click.ClickException(str(e))
def test_fingerprint_item_exception(self, *mocks): """Test for fingerprint_item exception raised.""" public_id = PublicIdMock() with self.assertRaises(ClickException): fingerprint_item(ContextMock(), "skill", public_id)
def test_fingerprint_item_package_not_found(self, *mocks): """Test for fingerprint_item package not found result.""" public_id = PublicIdMock() with self.assertRaises(ClickException) as cm: fingerprint_item(ContextMock(), "skill", public_id) self.assertIn("Package not found at path", cm.exception.message)