def test_make_file(self): p_metadata = ParentToolMetadata(name=TestMakeParentToolMetadata.test_dict['name'], softwareVersion=test_constants['test_software_version']) with TemporaryDirectory(prefix='xD_test1', suffix='') as tmpdir: parent_metadata_path = get_tool_metadata(TestMakeParentToolMetadata.test_dict['name'], test_constants['test_software_version']['versionName'], parent=True, base_dir=tmpdir) if not parent_metadata_path.exists(): parent_metadata_path.parent.mkdir(parents=True) p_metadata.mk_file(base_dir=tmpdir, replace_none=True) with parent_metadata_path.open('r') as file: test_file_dict = safe_load(file) self.assertEqual(test_file_dict['name'], TestMakeParentToolMetadata.test_dict['name'])
def test_add_parent_only(self): with TemporaryDirectory(prefix='dont_see me_') as tmp_dir: self.make_empty_tools_index(tmp_dir) tool_name = 'test__1' tool_version = '123' add_tool(tool_name, tool_version, root_repo_path=tmp_dir, refresh_index=False) # Index is not refreshed because there is nothing in the content repo. Will throw FileNotFound error when trying to traverse directories. # the tool added should be the only identifier in the index. parent_metadata_path = get_tool_metadata(tool_name, tool_version, parent=True, base_dir=tmp_dir) with self.assertRaises(InIndexError): # This should fail because trying to assign identifier that is already uses (by itself). parent_metadata = ParentToolMetadata.load_from_file(parent_metadata_path, _in_index=False, root_repo_path=tmp_dir) assert True parent_metadata = ParentToolMetadata.load_from_file(parent_metadata_path, root_repo_path=tmp_dir) # this should succeed with the _in_index flag. assert True return
def make_tool_common_dir_map(tool_name, tool_version, base_dir): common_metadata_path = get_tool_common_dir(tool_name, tool_version, base_dir=base_dir) / common_tool_metadata_name common_metadata = ParentToolMetadata.load_from_file(common_metadata_path) common_dir_map = {} common_dir_map[common_metadata.identifier] = {'path': str(common_metadata_path), 'metadataStatus': common_metadata.metadataStatus, 'name': common_metadata.name, 'versionName': common_metadata.softwareVersion.versionName, 'type': 'parent'} return common_dir_map
def test_make_subtool_metadata(self): p_metadata = ParentToolMetadata( name=TestMakeParentToolMetadata.test_dict['name'], softwareVersion=test_constants['test_software_version'], featureList=['subtool_name']) st_metadata = SubtoolMetadata( name=TestMakeSubtoolMetadata.test_dict['name'], _parentMetadata=p_metadata) self.assertTrue( st_metadata.name == TestMakeSubtoolMetadata.test_dict['name'])
def test_make_file(self): with TemporaryDirectory(prefix='xD_test1', suffix='') as tmpdir: p_metadata = ParentToolMetadata( name=TestMakeParentToolMetadata.test_dict['name'], softwareVersion=test_constants['test_software_version'], check_index=False, root_repo_path=tmpdir) self.make_empty_tools_index(tmpdir) parent_metadata_path = get_tool_metadata( TestMakeParentToolMetadata.test_dict['name'], test_constants['test_software_version']['versionName'], parent=True, base_dir=tmpdir) if not parent_metadata_path.exists(): parent_metadata_path.parent.mkdir(parents=True) p_metadata.mk_file( base_dir=tmpdir, replace_none=True, update_index=True ) # Don't try to update an index file. There isn't one. with parent_metadata_path.open('r') as file: test_file_dict = safe_load(file) self.assertEqual(test_file_dict['name'], TestMakeParentToolMetadata.test_dict['name'])
def make_tool_version_dir_map(tool_name, tool_version, base_dir=None, specify_exists=False): tool_version_map = {} tool_version_dir = get_tool_version_dir(tool_name, tool_version, base_dir=base_dir) parent_metadata_path = get_tool_metadata(tool_name, tool_version, parent=True, base_dir=base_dir) parent_metadata = ParentToolMetadata.load_from_file(parent_metadata_path, check_index=False) parent_rel_path = get_relative_path(parent_metadata_path, base_path=base_dir) tool_version_map[parent_metadata.identifier] = { 'metadataPath': str(parent_rel_path), 'metadataStatus': parent_metadata.metadataStatus, 'name': parent_metadata.name, 'versionName': parent_metadata.softwareVersion.versionName, 'type': 'parent' } for subtool_dir in tool_version_dir.iterdir(): if subtool_dir.name in ['.DS_Store', 'common']: continue assert subtool_dir.is_dir( ), subtool_dir.name + " is not a directory. You likely have an extra file." tool_name_length = len( tool_name ) # Use to get directory name string after 'tool_name'. In case there are underscores in tool_name. subtool_name = subtool_dir.name[tool_name_length + 1:] if subtool_name == '': subtool_name = None subdir_map = make_subtool_map(tool_name, tool_version, subtool_name, base_dir=base_dir, specify_exists=specify_exists) no_clobber_update(tool_version_map, subdir_map) return tool_version_map
def make_tool_version_dir_map(tool_name, tool_version, base_dir=None): tool_version_map = {} tool_version_dir = get_tool_version_dir(tool_name, tool_version, base_dir=base_dir) subdir_names = [subdir.name for subdir in tool_version_dir.iterdir()] parent_metadata_path = get_tool_metadata(tool_name, tool_version, parent=True, base_dir=base_dir) parent_metadata = ParentToolMetadata.load_from_file(parent_metadata_path) parent_rel_path = get_relative_path(parent_metadata_path, base_path=base_dir) tool_version_map[parent_metadata.identifier] = {'path': str(parent_rel_path), 'metadataStatus': parent_metadata.metadataStatus, 'name': parent_metadata.name, 'versionName': parent_metadata.softwareVersion.versionName, 'type': 'parent'} subdir_names.remove('common') for subdir_name in subdir_names: tool_name_length = len( tool_name) # Use to get directory name string after 'tool_name'. In case there are underscores in tool_name. subtool_name = subdir_name[tool_name_length + 1:] if subtool_name == '': subtool_name = None subdir_map = make_subtool_map(tool_name, tool_version, subtool_name, base_dir=base_dir) tool_version_map.update(subdir_map) return tool_version_map
def add_tool(tool_name, version_name, subtool_names=None, biotools_id=None, has_primary=False, root_repo_path=Path.cwd(), init_cwl=False, init_wdl=False, init_sm=False, init_nf=False, no_clobber=False, refresh_index=True): """ Make the correct directory structure for adding a new command line tool. Optionally, create initialized wf language and metadata files. Run from tools directory. :param tool_name(str): Name of the tool :param version_name(str): version of the tool :param subtool_names(list(str)): list of subtool names if the tool is broken into multiple subtools. :return: None """ version_name = str(version_name) # In case ArgumentParser is bypassed. if subtool_names: if isinstance(subtool_names, str): subtool_names = [subtool_names] if has_primary: # Need to append __main__ onto subtools. if subtool_names: subtool_names.append(main_tool_subtool_name) else: # __main__ is only subtool specified. subtool_names = [main_tool_subtool_name] if isinstance(init_cwl, str): init_cwl = {main_tool_subtool_name: init_cwl} if refresh_index: make_tools_index(base_dir=root_repo_path) common_dir = get_tool_common_dir(tool_name, version_name, base_dir=root_repo_path) if no_clobber and common_dir.exists(): logger.debug("Skipping tool directory setup") return common_dir.mkdir(parents=True, exist_ok=not no_clobber) if biotools_id: # tool_name will be ignored. parent_metadata = ParentToolMetadata.create_from_biotools( biotools_id, version_name, subtool_names, name=tool_name, root_repo_path=root_repo_path) # can't find it in biotools if parent_metadata is None: parent_metadata = ParentToolMetadata(name=tool_name, softwareVersion={ 'versionName': version_name, 'includedVersions': [] }, featureList=subtool_names, check_index=True, _in_index=False) else: parent_metadata = ParentToolMetadata(name=tool_name, softwareVersion={ 'versionName': version_name, 'includedVersions': [] }, featureList=subtool_names, root_repo_path=root_repo_path, check_index=True, _in_index=False) if parent_metadata.featureList: for subtool in parent_metadata.featureList: subtool_obj = parent_metadata.make_subtool_metadata( subtool_name=subtool, root_repo_path=root_repo_path, check_index=True) subtool_obj.mk_file() subtool_dir = get_tool_dir(tool_name, version_name, subtool, base_dir=root_repo_path) instances_dir = subtool_dir / 'instances' instances_dir.mkdir() git_keep_file = instances_dir / '.gitkeep' git_keep_file.touch() if isinstance(init_cwl, dict): init_cwl_ = init_cwl.get( subtool, False) # Not initialized if not specified. else: init_cwl_ = init_cwl initialize_tool_wf_file_tool(tool_name, version_name, subtool, init_cwl=init_cwl_, init_wdl=init_wdl, init_sm=init_sm, init_nf=init_nf, base_dir=root_repo_path) parent_metadata.mk_file(root_repo_path) return
def add_subtool(tool_name, tool_version, subtool_name, root_repo_path=Path.cwd(), update_featureList=False, init_cwl=False, init_wdl=False, init_sm=False, init_nf=False, no_clobber=False, refresh_index=True): """ Add subtool to already existing ToolLibrary (ParentTool file already exists) :param tool_name(str): :param version_name (str): :param subtool_name (str): :param root_repo_path (Path): The local directory under which this subtool should be added :param update_featureList (Bool): If True, subtool does not need to be in ParentTool featureList and ParentTool will be updated. Will throw error if False and subtool is not in ParentTool featureList. :param init_cwl: :return: """ if refresh_index: make_tools_index(base_dir=root_repo_path) subtool_kwargs = { 'extra': {} } # initialize to add any additional information about the subtool. parent_path = get_tool_metadata(tool_name, tool_version, parent=True, base_dir=root_repo_path) parent_meta = ParentToolMetadata.load_from_file( parent_path, root_repo_path=root_repo_path, _in_index=True ) # When adding a subtool, the ParentTool should already be present and in the index. subtool_dir = get_tool_dir(tool_name, tool_version, subtool_name, base_dir=root_repo_path) if no_clobber and subtool_dir.exists(): return if update_featureList: if parent_meta.featureList is None: parent_meta.featureList = [subtool_name] else: if not subtool_name in parent_meta.featureList: parent_meta.featureList.append(subtool_name) parent_meta.mk_file( base_dir=root_repo_path, update_index=False ) # Remake the file. Needs to be remade if updated. Identifier will already be in index. No place to update the identifier in this function. if not isinstance(init_cwl, bool): # initialized from a url. subtool_kwargs['extra'].update({ 'cwlDocument': { 'isBasedOn': init_cwl, 'dateCreated': str(date.today()) } }) if not isinstance(init_wdl, bool): # initialized from a url. subtool_kwargs['extra'].update({ 'wdlDocument': { 'isBasedOn': init_wdl, 'dateCreated': str(date.today()) } }) if not isinstance(init_sm, bool): # initialized from a url. subtool_kwargs['extra'].update({ 'snakemakeDocument': { 'isBasedOn': init_sm, 'dateCreated': str(date.today()) } }) if not isinstance(init_nf, bool): # initialized from a url. subtool_kwargs['extra'].update({ 'nextflowDocument': { 'isBasedOn': init_nf, 'dateCreated': str(date.today()) } }) subtool_meta = parent_meta.make_subtool_metadata( subtool_name, root_repo_path=root_repo_path, check_index=True, **subtool_kwargs) subtool_meta.mk_file() instances_dir = subtool_dir / 'instances' instances_dir.mkdir() git_keep_file = instances_dir / '.gitkeep' git_keep_file.touch() initialize_tool_wf_file_tool(tool_name, tool_version, subtool_name, init_cwl=init_cwl, init_wdl=init_wdl, init_sm=init_sm, init_nf=init_nf, base_dir=root_repo_path) return
def test_make_parent_metadata(self): p_metadata = ParentToolMetadata( name=TestMakeParentToolMetadata.test_dict['name'], softwareVersion=test_constants['test_software_version']) self.assertTrue( p_metadata.name == TestMakeParentToolMetadata.test_dict['name'])