def create_github_repo(dataset, repo_name): """Setup a github sibling / remote.""" try: # raise exception if github exports are not enabled if not DATALAD_GITHUB_EXPORTS_ENABLED: raise Exception( 'DATALAD_GITHUB_EXPORTS_ENABLED must be defined to create remote repos') # this adds github remote to config and also creates repo return create_sibling_github(repo_name, github_login=DATALAD_GITHUB_LOGIN, github_passwd=DATALAD_GITHUB_PASS, github_organization=DATALAD_GITHUB_ORG, dataset=dataset, access_protocol='ssh') except KeyError: raise Exception( 'DATALAD_GITHUB_LOGIN, DATALAD_GITHUB_PASS, and DATALAD_GITHUB_ORG must be defined to create remote repos')
def add( template_id, osf_user, osf_password, osf_overwrite, gh_user, gh_token, path, nprocs, ): """Add a new template.""" from .io import run_command from .utils import copy_template import shutil from datalad import api as dl gh_password = getenv("GITHUB_PASSWORD") if not gh_user or not gh_token: raise click.BadParameter("Insufficient secrets to login into GitHub") path = Path(path or f"tpl-{template_id}").absolute() cwd = Path.cwd() if not path.exists(): raise click.UsageError(f"<{path}> does not exist.") metadata = {} # Check metadata if (path / "template_description.json").exists(): metadata = json.loads((path / "template_description.json").read_text()) metadata["Identifier"] = template_id # Check license license_path = path / "LICENSE" if not license_path.exists(): license_path = path / "LICENCE" if not license_path.exists(): license_path = path / "COPYING" if not license_path.exists(): license_prompt = click.prompt( text="""\ A LICENSE file MUST be distributed with the template. The TemplateFlow Manager can \ set a license (either CC0 or CC-BY) for you.""", type=click.Choice(("CC0", "CC-BY", "Custom (abort)")), default="Custom (abort)", ) if license_prompt == "Custom (abort)": raise click.UsageError( "Cannot proceed without a valid license. Please write a LICENSE " "file before uploading.") license_path = Path( pkgr_fn("tfmanager", f"data/{license_prompt}.LICENSE")) metadata["License"] = license_prompt # Check RRID if not metadata.get("RRID"): rrid = click.prompt( text="Has a RRID (research resource ID) already been assigned?", type=str, default='') or None if rrid: metadata["RRID"] = rrid # Check short description if not metadata.get("Name", "").strip(): short_desc = click.prompt( text="""\ The "Name" metadata is not found within the <template_description.json> file. \ Please provide a short description for this resource.""", type=str, ) if not short_desc: raise click.UsageError( "Cannot proceed without a short description.") metadata["Name"] = short_desc # Check authors authors_prompt = [ a.strip() for a in metadata.get("Authors", []) if a.strip() ] if not authors_prompt: authors_prompt = [ n.strip() for n in click.prompt( text="""\ The "Authors" metadata is not found within the <template_description.json> file. \ Please provide a list of authors separated by semicolon (;) in <Lastname Initial(s)> format.""", type=str, ).split(";") if n ] if not authors_prompt: click.confirm("No authors were given, do you want to continue?", abort=True) metadata["Authors"] = authors_prompt # Check references refs_prompt = [ f"""\ {'https://doi.org/' if not a.strip().startswith('http') else ''}\ {a.replace("doi:", "").strip()}""" for a in metadata.get("ReferencesAndLinks", []) if a.strip() ] if not refs_prompt: refs_prompt = [ n.replace('"', "").strip() for n in click.prompt( text="""\ The "ReferencesAndLinks" metadata is not found within the <template_description.json> file. \ Please provide a list of links and publications within double-quotes \ (for example, "doi:10.1101/2021.02.10.430678") and separated by spaces (< >).""", type=str, ).split(" ") if n ] if not refs_prompt: click.confirm("No authors were given, do you want to continue?", abort=True) metadata["ReferencesAndLinks"] = refs_prompt with TemporaryDirectory() as tmpdir: repodir = Path(tmpdir) / "templateflow" # Clone root <user>/templateflow project - fork if necessary click.echo(f"Preparing Pull-Request (wd={tmpdir}).") clone = run_command( f"git clone https://github.com/{gh_user}/templateflow.git " "--branch tpl-intake --single-branch", cwd=tmpdir, capture_output=False, ) if clone.returncode != 0: run_command( "hub clone templateflow/templateflow", cwd=tmpdir, capture_output=False, env={ "GITHUB_USER": gh_user, "GITHUB_PASSWORD": gh_password }, ) run_command( "hub fork --remote-name origin", cwd=str(repodir), capture_output=False, env={ "GITHUB_USER": gh_user, "GITHUB_PASSWORD": gh_password }, ) else: run_command( "git remote add upstream https://github.com/templateflow/templateflow.git", cwd=str(repodir), capture_output=False, ) chdir(repodir) # Create datalad dataset dl.create( path=f"tpl-{template_id}", cfg_proc="text2git", initopts={"initial-branch": "main"}, description=metadata["Name"], ) # Populate template copy_template( path=path, dest=repodir / f"tpl-{template_id}", ) # Copy license shutil.copy(license_path, repodir / f"tpl-{template_id}" / "LICENSE") # (Over)write template_description.json (repodir / f"tpl-{template_id}" / "template_description.json").write_text(json.dumps(metadata, indent=2)) # Init/update CHANGELOG changelog = repodir / f"tpl-{template_id}" / "CHANGES" changes = [ f""" ## {datetime.date.today().ctime()} - TemplateFlow Manager Upload Populated contents after NIfTI sanitizing by the TF Manager. """ ] if changelog.exists(): changes += [changelog.read_text()] changelog.write_text("\n".join(changes)) # Init OSF sibling rrid_str = f" (RRID: {metadata['RRID']})" if metadata.get( "RRID") else "" dl.create_sibling_osf( title=f"TemplateFlow resource: <{template_id}>{rrid_str}", name="osf", dataset=f"./tpl-{template_id}", public=True, category="data", description=metadata["Name"], tags=["TemplateFlow dataset", template_id]) # Init GH sibling dl.create_sibling_github(reponame=f"tpl-{template_id}", dataset=str(repodir / f"tpl-{template_id}"), github_login=gh_user, publish_depends="osf-storage", existing="replace", access_protocol="ssh") # Save added contents dl.save(dataset=str(repodir / f"tpl-{template_id}"), message="ADD: TemplateFlow Manager initialized contents") # Push to siblings dl.push( dataset=str(repodir / f"tpl-{template_id}"), to="github", jobs=cpu_count(), ) # Back home chdir(cwd) run_command( "git fetch upstream tpl-intake", cwd=str(repodir), capture_output=False, ) run_command( f"git checkout -b pr/tpl-{template_id} upstream/tpl-intake", cwd=str(repodir), capture_output=False, ) (repodir / f"{path.name}.toml").write_text( toml.dumps({ "github": { "user": gh_user }, })) run_command( f"git add {path.name}.toml", cwd=str(repodir), capture_output=False, ) run_command( f"git commit -m 'add(tpl-{template_id}): create intake file'", cwd=str(repodir), capture_output=False, ) run_command( f"git push -u origin pr/tpl-{template_id}", cwd=str(repodir), capture_output=False, env={ "GITHUB_USER": gh_user, "GITHUB_TOKEN": gh_token }, ) (repodir.parent / "message.md").write_text(f"""\ ADD: ``tpl-{template_id}`` ## {metadata.get('Name', '<missing Name>')} Identifier: {metadata.get('Identifier', '<missing Identifier>')} Datalad: https://github.com/{gh_user}/tpl-{template_id} ### Authors {', '.join(metadata['Authors'])}. ### License {metadata.get('License', metadata.get('Licence', '<missing License>'))} ### Cohorts {' '.join(('The dataset contains', str(len(metadata.get('cohort', []))), 'cohorts.')) if metadata.get('cohort') else 'The dataset does not contain cohorts.'} ### References and links {', '.join(metadata.get('ReferencesAndLinks', [])) or 'N/A'} """) run_command( "hub pull-request -b templateflow:tpl-intake " f"-h {gh_user}:pr/tpl-{template_id} " f"-F {repodir.parent / 'message.md'}", cwd=str(repodir), capture_output=False, env={ "GITHUB_USER": gh_user, "GITHUB_TOKEN": gh_token }, )