def init( self, parsers=None, repo=None, params=None, force=False, skip_users=None, from_resources=None, ): """Init one or more contributor parsers. Specifically, this is the action that runs the parser.init() to generate some initial file. """ parsers = parsers or [] # Generate a shared repository object repo = GitHubRepository(repo, skip_users) # Get resource lookup ids (emails, orcids, logins, most won't be used for init) resources = self.get_resource_lookups(from_resources, params) for parser in parsers: client = get_named_parser(name=parser, repo=repo, params=params) client.cache = self.cache client.init(force=force, from_resources=resources) self.cache.update(client.cache) # Save the cache self.save_cache()
def get_resource_lookups(self, from_resources=None, params=None): """Based on a name (e.g., GitHub or special case tributors) return as many lookups of unique ids (email, login, orcid) that the resource provides """ from_resources = from_resources or ["github"] lookups = {"login": set(), "orcid": set(), "email": set(), "name": set()} for name in from_resources: # Special case, tributors is just the entire cache if name == "tributors": lookups["login"].update(self.cache) lookups["name"].update( {x["name"]: x for _, x in self.cache.items() if "name" in x} ) lookups["orcid"].update( {x["orcid"]: x for _, x in self.cache.items() if "orcid" in x} ) lookups["email"].update( {x["email"]: x for _, x in self.cache.items() if "email" in x} ) else: parser = get_named_parser(name=name, params=params) lookups["name"].update(parser.name_lookup) lookups["login"].update(parser.login_lookup) lookups["email"].update(parser.email_lookup) lookups["orcid"].update(parser.orcid_lookup) return lookups
def update( self, parsers=None, repo=None, params=None, thresh=1, skip_users=None, from_resources=None, ): """Update one or more contributor parsers. Specifically, this is the action that runs the parser.update() after obtaining contributions from GitHub or a cache. """ parsers = parsers or [] # Generate a shared repository object repo = GitHubRepository(repo, skip_users=skip_users) bot.debug(f"Found repository {repo}") # Get resource lookup ids (emails, orcids, logins) resources = self.get_resource_lookups(from_resources, params) # Update each metadata file via its parser for parser in parsers: client = get_named_parser(name=parser, repo=repo, params=params) client.cache = self.cache client.update(thresh=thresh, from_resources=resources) self.cache.update(client.cache) # Save the cache self.save_cache()
def update_resource(self, resources=None, params=None, skip_users=None): """Given one or more resource types (an external file or source of metadata) update the .tributors cache lookup """ resources = resources or [] for name in resources: resource = get_named_parser(name=name, params=params) resource.cache = self.cache resource.update_lookup() # Save the cache self.save_cache()
def test_parser_allcontrib(tmp_path): """test each executor type with the filesystem """ from tributors.main.parsers import get_named_parser # Prepare from resources from_resources = {"login": set(["vsoch", "manbat", "yarikoptic"])} # Create a dummy output file allcontrib = os.path.join(str(tmp_path), ".all-contributorsrc") params = {"--allcontrib-file": allcontrib} repo = "singularityhub/sregistry" # Output file should not exist before inint assert not os.path.exists(allcontrib) parser = get_named_parser("allcontrib", repo=repo, params=params) result = parser.init() # Trying to write existing file raises system exit with pytest.raises(SystemExit): result = parser.init() assert os.path.exists(allcontrib) # Ensure the result matches the template template = { "projectName": "sregistry", "projectOwner": "singularityhub", "repoType": "github", "repoHost": "https://github.com", "files": ["README.md"], "imageSize": 100, "commit": True, "commitConvention": "none", "contributors": [], "contributorsPerLine": 7, } assert template == result # Test adding contributors, default from GitHub result = parser.update(from_resources=from_resources, save=False) assert len(result["contributors"]) == 3 for login in [x["login"] for x in result["contributors"]]: assert login in from_resources["login"] # Test adding by email or orcid should not change output byemail = parser.update(from_resources={"email": set(["*****@*****.**"])}, save=False) byorcid = parser.update( from_resources={"orcid": set(["0000-0000-0000-0000"])}, save=False) assert byemail == byorcid == result
def init(self, parsers=None, repo=None, params=None, force=False): """Init one or more contributor parsers. Specifically, this is the action that runs the parser.init() to generate some initial file. """ parsers = parsers or [] for parser in parsers: client = get_named_parser(parser, repo) client.init(params=params, repo=repo, force=force, contributors=self.contributors) # Update contributors caches self.contributors.update(client.contributors) self.cache.update(client.cache) # Save the cache self.save_cache()
def update(self, parsers=None, repo=None, params=None, thresh=1): """Update one or more contributor parsers. Specifically, this is the action that runs the parser.update() after obtaining contributions from GitHub or a cache. """ parsers = parsers or [] self.orcid_token = get_orcid_token() for parser in parsers: client = get_named_parser(parser, repo) client.orcid_token = self.orcid_token client.cache = self.cache client.update(params=params, repo=repo, contributors=self.contributors, thresh=thresh) # Update contributors caches self.contributors.update(client.contributors) self.cache.update(client.cache) # Save the cache self.save_cache()
def test_parser_zenodo(tmp_path): """test each executor type with the filesystem """ from tributors.main.parsers import get_named_parser # Prepare from resources from_resources = {"login": set(["vsoch", "manbat", "yarikoptic"])} # Create a dummy output file zenodo = os.path.join(str(tmp_path), ".zenodo.json") params = {"--zenodo-file": zenodo} repo = "singularityhub/sregistry" # Output file should not exist before init assert not os.path.exists(zenodo) parser = get_named_parser("zenodo", repo=repo, params=params) result = parser.init(save=False) assert len(result["creators"]) == 0 # With from resources, should add to creators result = parser.init(from_resources=from_resources) assert len(result["creators"]) == 3 # Trying to write existing file raises system exit with pytest.raises(SystemExit): result = parser.init() assert os.path.exists(zenodo) # Ensure the result matches the template template = { "creators": [{ "name": "yarikoptic" }, { "name": "manbat" }, { "name": "vsoch" }], "upload_type": "software", "keywords": [ "singularity", "management", "containers", "registry", "singularity-containers", "singularityhub", ], } assert set(template["keywords"]) == set(result["keywords"]) assert template["upload_type"] == result["upload_type"] assert len(result["creators"]) == 3 for login in [x["name"] for x in result["creators"]]: assert login in from_resources["login"] # Test adding contributors, default from GitHub parser = get_named_parser("zenodo", repo=repo, params=params) from_github = parser.update(from_resources=from_resources, save=False) assert from_github == result # Test adding by email or orcid should not change output parser = get_named_parser("zenodo", repo=repo, params=params) byemail = parser.update(from_resources={"email": set(["*****@*****.**"])}, save=False) assert byemail == result # Support adding by orcid, if not known parser = get_named_parser("zenodo", repo=repo, params=params) byorcid = parser.update( from_resources={"orcid": set(["0000-0000-0000-0000"])}, save=False) assert len(byorcid["creators"]) == 4