async def seek_entities(f: 'CdmManifestDefinition'): if f.entities is not None: spew.spew_line(f.folder_path) for entity in f.entities: ent = entity current_file = f while isinstance(ent, CdmReferencedEntityDeclarationDefinition): corpus_path = corpus.storage.create_absolute_corpus_path(ent.entity_path, current_file) ent = await corpus.fetch_object_async(corpus_path) current_file = ent corpus_path = corpus.storage.create_absolute_corpus_path(ent.entity_path, current_file) res_opt = ResolveOptions() res_opt.imports_load_strategy = ImportsLoadStrategy.LOAD new_ent = await corpus.fetch_object_async(corpus_path, res_opt=res_opt) res_opt.wrt_doc = new_ent.in_document res_opt.directives = directives res_ent = ResolvedEntity(res_opt, new_ent) res_ent.spew(res_opt, spew, ' ', True) if f.sub_manifests: for sub_manifest in f.sub_manifests: corpus_path = corpus.storage.create_absolute_corpus_path(sub_manifest.definition, f) await seek_entities(await corpus.fetch_object_async(corpus_path))
def _copy_resolve_options(res_opt: 'ResolveOptions') -> 'ResolveOptions': from cdm.utilities import ResolveOptions # pylint: disable=redefined-outer-name res_opt_copy = ResolveOptions() res_opt_copy.wrt_doc = res_opt.wrt_doc res_opt_copy._relationship_depth = res_opt._relationship_depth res_opt_copy._localize_references_for = res_opt._localize_references_for res_opt_copy._indexing_doc = res_opt._indexing_doc if res_opt.directives: res_opt_copy.directives = res_opt.directives.copy() return res_opt_copy
async def create_resolved_manifest_async( self, new_manifest_name: str, new_entity_document_name_format: str ) -> Optional['CdmManifestDefinition']: """Creates a resolved copy of the manifest. new_entity_document_name_format specifies a pattern to use when creating documents for resolved entities. The default is "resolved/{n}.cdm.json" to avoid a document name conflict with documents in the same folder as the manifest. Every instance of the string {n} is replaced with the entity name from the source manifest. Any sub-folders described by the pattern should exist in the corpus prior to calling this function. """ if self.entities is None: return None if new_entity_document_name_format is None: new_entity_document_name_format = '{f}resolved/{n}.cdm.json' elif new_entity_document_name_format == '': # for back compat new_entity_document_name_format = '{n}.cdm.json' elif '{n}' not in new_entity_document_name_format: # for back compat new_entity_document_name_format = new_entity_document_name_format + '/{n}.cdm.json' source_manifest_path = self.ctx.corpus.storage.create_absolute_corpus_path( self.at_corpus_path, self) source_manifest_folder_path = self.ctx.corpus.storage.create_absolute_corpus_path( self.folder.at_corpus_path, self) resolved_manifest_path_split = new_manifest_name.rfind('/') + 1 resolved_manifest_folder = None if resolved_manifest_path_split > 0: resolved_manifest_path = new_manifest_name[ 0:resolved_manifest_path_split] new_folder_path = self.ctx.corpus.storage.create_absolute_corpus_path( resolved_manifest_path, self) resolved_manifest_folder = await self.ctx.corpus.fetch_object_async( new_folder_path) # type: CdmFolderDefinition if resolved_manifest_folder is None: self.ctx.logger.error( 'New folder for manifest not found {}'.format( new_folder_path), 'create_resolved_manifest_async') return None new_manifest_name = new_manifest_name[ resolved_manifest_path_split:] else: resolved_manifest_folder = self.owner self.ctx.logger.debug( 'resolving manifest {}'.format(source_manifest_path), 'create_resolved_manifest_async') # using the references present in the resolved entities, get an entity # create an imports doc with all the necessary resolved entity references and then resolve it resolved_manifest = CdmManifestDefinition(self.ctx, new_manifest_name) # add the new document to the folder if resolved_manifest_folder.documents.append( resolved_manifest) is None: # when would this happen? return None # mapping from entity path to resolved entity path for translating relationhsip paths res_ent_map = {} # type: Dict[str, str] for entity in self.entities: ent_def = await self._get_entity_from_reference(entity, self) if not ent_def: self.ctx.logger.error('Unable to get entity from reference') return None # get the path from this manifest to the source entity. this will be the {f} replacement value source_entity_full_path = self.ctx.corpus.storage.create_absolute_corpus_path( ent_def.in_document.folder.at_corpus_path, self) f = '' if source_entity_full_path.startswith(source_manifest_folder_path): f = source_entity_full_path[len(source_manifest_folder_path):] new_document_full_path = new_entity_document_name_format.replace( '{n}', ent_def.entity_name).replace('{f}', f) new_document_full_path = self.ctx.corpus.storage.create_absolute_corpus_path( new_document_full_path, self) new_document_path_split = new_document_full_path.rfind('/') + 1 new_document_path = new_document_full_path[ 0:new_document_path_split] new_document_name = new_document_full_path[ new_document_path_split:] # make sure the new folder exists folder = await self.ctx.corpus.fetch_object_async( new_document_path) # type: CdmFolderDefinition if not folder: self.ctx.logger.error( 'New folder not found {}'.format(new_document_path)) return None # next create the resolved entity. res_opt = ResolveOptions() res_opt.wrt_doc = ent_def.in_document res_opt.directives = AttributeResolutionDirectiveSet( {'normalized', 'referenceOnly'}) self.ctx.logger.debug( ' resolving entity {} to document {}'.format( source_entity_full_path, new_document_full_path)) resolved_entity = await ent_def.create_resolved_entity_async( ent_def.entity_name, res_opt, folder, new_document_name) if not resolved_entity: # fail all resolution, if any one entity resolution fails return None result = entity.copy(res_opt) if result.object_type == CdmObjectType.LOCAL_ENTITY_DECLARATION_DEF: relative_entity_path = self.ctx.corpus.storage.create_relative_corpus_path( resolved_entity.at_corpus_path, resolved_manifest) result.entity_path = relative_entity_path or result.at_corpus_path resolved_manifest.entities.append(result) # absolute path is needed for generating relationships absolute_ent_path = self.ctx.corpus.storage.create_absolute_corpus_path( result.entity_path, resolved_manifest) res_ent_map[self.ctx.corpus.storage.create_absolute_corpus_path( ent_def.at_corpus_path, ent_def.in_document)] = absolute_ent_path self.ctx.logger.debug(' calculating relationships') # Calculate the entity graph for just this manifest. await self.ctx.corpus._calculate_entity_graph_async( resolved_manifest, res_ent_map) # Stick results into the relationships list for the manifest. await resolved_manifest.populate_manifest_relationships_async( CdmRelationshipDiscoveryStyle.EXCLUSIVE) # needed until Matt's changes with collections where I can propigate resolved_manifest._is_dirty = True return resolved_manifest