diff --git a/abcclassroom/__main__.py b/abcclassroom/__main__.py index 9c3fdbf..7072ed6 100644 --- a/abcclassroom/__main__.py +++ b/abcclassroom/__main__.py @@ -39,6 +39,14 @@ def init(): create a valid file; 2. Check that ssh access to GitHub via git commands is working. """ + parser = argparse.ArgumentParser(description=init.__doc__) + parser.add_argument( + "--ssh_user", + default="git@github.com", + help="""Name of the Github user when connecting over ssh. Default to + git@github.com""", + ) + args = parser.parse_args() print("Step 1: Setting up GitHub API access") abcauth.check_or_generate_token() @@ -50,7 +58,7 @@ def init(): """ ) try: - abcgit.check_git_ssh() + abcgit.check_git_ssh(args.ssh_user) print( """Running git commands that access GitHub via SSH seems to be configured correctly""" @@ -89,6 +97,12 @@ def clone(): action="store_false", help="""Skip moving files from cloned repo to submitted.""", ) + parser.add_argument( + "--ssh_user", + default="git@github.com", + help="""Name of the Github user when connecting over ssh. Default to + git@github.com""", + ) args = parser.parse_args() clone_student_repos(args) @@ -157,6 +171,12 @@ def new_template(): merge = keep existing dir, overwrite existing files, add new files (Default = fail).""", ) + parser.add_argument( + "--ssh_user", + default="git@github.com", + help="""Name of the Github user when connecting over ssh. Default to + git@github.com""", + ) args = parser.parse_args() template.new_update_template(args) @@ -224,6 +244,12 @@ def update_template(): help="""Enter a commit message for git. If not set, uses default message 'Updating assignment').""", ) + parser.add_argument( + "--ssh_user", + default="git@github.com", + help="""Name of the Github user when connecting over ssh. Default to + git@github.com""", + ) args = parser.parse_args() # now set the additional args (so that it matches the keys in add_template # and we can use the same implementation methods) diff --git a/abcclassroom/clone.py b/abcclassroom/clone.py index 28ef80f..85ce5cf 100644 --- a/abcclassroom/clone.py +++ b/abcclassroom/clone.py @@ -12,7 +12,7 @@ from . import git as abcgit -def clone_or_update_repo(organization, repo, clone_dir, skip_existing): +def clone_or_update_repo(organization, repo, clone_dir, skip_existing, ssh_user="git@github.com"): """ Tries to clone the single repository 'repo' from the organization. If the local repository already exists, pulls instead of cloning (unless the @@ -46,7 +46,7 @@ def clone_or_update_repo(organization, repo, clone_dir, skip_existing): print(e) else: try: - abcgit.clone_repo(organization, repo, clone_dir) + abcgit.clone_repo(organization, repo, clone_dir, ssh_user=ssh_user) except RuntimeError as e: print("Error cloning repository {}".format(repo)) print(e) @@ -66,11 +66,12 @@ def clone_student_repos(args): assignment_name = args.assignment skip_existing = args.skip_existing no_submitted = args.no_submitted + ssh_user = args.ssh_user - clone_repos(assignment_name, skip_existing, no_submitted) + clone_repos(assignment_name, skip_existing, no_submitted, ssh_user) -def clone_repos(assignment_name, skip_existing=False, no_submitted=True): +def clone_repos(assignment_name, skip_existing=False, no_submitted=True, ssh_user="git@github.com"): """Iterates through the student roster, clones each repo for this assignment into the directory specified in the config, and then copies the notebook files into the 'course_materials/submitted' directory, based on @@ -140,6 +141,7 @@ def clone_repos(assignment_name, skip_existing=False, no_submitted=True): repo, Path(clone_dir, assignment_name), skip_existing, + ssh_user=ssh_user ) if materials_dir is not None and no_submitted: copy_assignment_files( diff --git a/abcclassroom/feedback.py b/abcclassroom/feedback.py index c23a6bd..6449322 100644 --- a/abcclassroom/feedback.py +++ b/abcclassroom/feedback.py @@ -14,7 +14,8 @@ from . import scrub_feedback as sf -def copy_feedback_files(assignment_name, push_to_github=False, scrub=False): +def copy_feedback_files(assignment_name, push_to_github=False, scrub=False, + ssh_user="git@github.com"): """Copies feedback reports to local student repositories, commits the changes, and (optionally) pushes to github. Assumes files are in the directory @@ -31,7 +32,9 @@ def copy_feedback_files(assignment_name, push_to_github=False, scrub=False): scrub: boolean If true, and we are moving an html file this will clean the html file before copying it over. - + ssh_user: string (default = "git@github.com") + Name of the Github user when connecting over ssh. + Returns ------- Moves feedback html files from the student feedback directory to the @@ -107,7 +110,7 @@ def copy_feedback_files(assignment_name, push_to_github=False, scrub=False): ) if push_to_github: try: - abcgit.push_to_github(destination_dir) + abcgit.push_to_github(destination_dir, ssh_user) except RuntimeError as e: print(e) print( diff --git a/abcclassroom/git.py b/abcclassroom/git.py index ded107b..46f8ca1 100644 --- a/abcclassroom/git.py +++ b/abcclassroom/git.py @@ -9,13 +9,18 @@ import subprocess -def check_git_ssh(): +def check_git_ssh(ssh_user="git@github.com"): """Tests that ssh access to GitHub is set up correctly on the users computer. Throws a RuntimeError if setup is not working. + + Parameters + ---------- + ssh_user: string (default = "git@github.com") + Name of the Github user when connecting over ssh. """ - cmd = ["ssh", "-T", "git@github.com"] + cmd = ["ssh", "-T", ssh_user] try: subprocess.run( cmd, @@ -89,7 +94,7 @@ def _call_git(*args, directory=None): return ret -def clone_repo(organization, repo, dest_dir): +def clone_repo(organization, repo, dest_dir, ssh_user="git@github.com"): """Clone `repository` from `org` into a sub-directory in `directory`. Raises RuntimeError if ssh keys not set up correctly, or if git clone @@ -105,6 +110,8 @@ def clone_repo(organization, repo, dest_dir): Path to the destination directory TODO: is this a full path, path object or string - what format is dest_dir in + ssh_user: string (default = "git@github.com") + Name of the Github user when connecting over ssh. Returns ------- Cloned github repository in the destination directory specified. @@ -112,16 +119,16 @@ def clone_repo(organization, repo, dest_dir): try: # first, check that local git set up with ssh keys for github - check_git_ssh() - url = "git@github.com:{}/{}.git".format(organization, repo) + check_git_ssh(ssh_user=ssh_user) + url = "{}:{}/{}.git".format(ssh_user, organization, repo) print("cloning:", url) _call_git("-C", dest_dir, "clone", url) except RuntimeError as e: raise e -def add_remote(directory, organization, remote_repo): - remote_url = "git@github.com:{}/{}.git".format(organization, remote_repo) +def add_remote(directory, organization, remote_repo, ssh_user): + remote_url = "{}:{}/{}.git".format(ssh_user, organization, remote_repo) _call_git("remote", "add", "origin", remote_url, directory=directory) @@ -212,7 +219,7 @@ def _master_branch_to_main(dir): _call_git("branch", "-m", "master", "main", directory=dir) -def push_to_github(directory, branch="main"): +def push_to_github(directory, branch="main", ssh_user="git@github.com"): """Push `branch` of the repository in `directory` back to GitHub Assumes git remotes are already setup. @@ -223,6 +230,8 @@ def push_to_github(directory, branch="main"): A path to the local directory where the git repo of interest is saved. branch : str A string representing the branch that you wish to pull. Default = main + ssh_user: string (default = "git@github.com") + Name of the Github user when connecting over ssh. Returns ------- @@ -230,7 +239,7 @@ def push_to_github(directory, branch="main"): """ try: # first, check that local git set up with ssh keys for github - check_git_ssh() + check_git_ssh(ssh_user=ssh_user) _call_git( "push", "--set-upstream", "origin", branch, directory=directory ) @@ -238,7 +247,7 @@ def push_to_github(directory, branch="main"): raise e -def pull_from_github(directory, branch="main"): +def pull_from_github(directory, branch="main", ssh_user="git@github.com"): """Pull `branch` of local repo in `directory` from GitHub. Assumes git remotes are already setup. @@ -249,6 +258,8 @@ def pull_from_github(directory, branch="main"): A path to the local directory where the git repo of interest is saved. branch : str A string representing the branch that you wish to pull. Default = main + ssh_user: string (default = "git@github.com") + Name of the Github user when connecting over ssh. Returns ------- @@ -257,7 +268,7 @@ def pull_from_github(directory, branch="main"): """ try: # first, check that local git set up with ssh keys for github - check_git_ssh() + check_git_ssh(ssh_user=ssh_user) _call_git("pull", "origin", branch, directory=directory) except RuntimeError as e: raise e diff --git a/abcclassroom/template.py b/abcclassroom/template.py index 35978aa..1b7f11a 100644 --- a/abcclassroom/template.py +++ b/abcclassroom/template.py @@ -36,6 +36,7 @@ def new_update_template(args): push_to_github=args.github, commit_message=args.commit_message, assignment_name=args.assignment, + ssh_user=args.ssh_user ) except FileNotFoundError as fnfe: # if the assignment does not exist in course_materials/release @@ -50,6 +51,7 @@ def create_template( mode="fail", push_to_github=False, commit_message="Initial commit", + ssh_user="git@github.com" ): """ Classroom package function that creates or updates an assignment template @@ -79,6 +81,8 @@ def create_template( "Updating assignment" assignment_name : string name of the assignment + ssh_user: string (default = "git@github.com") + Name of the Github user when connecting over ssh. """ print("Loading configuration from config.yml") @@ -138,12 +142,12 @@ def create_template( token = auth.get_github_auth()["access_token"] create_or_update_remote( - template_repo_path, organization, repo_name, token + template_repo_path, organization, repo_name, token, ssh_user ) def create_or_update_remote( - template_repo_path, organization, repo_name, token + template_repo_path, organization, repo_name, token, ssh_user ): """ Push template repo to GitHub. If remote does not yet exist, creates it @@ -172,14 +176,14 @@ def create_or_update_remote( abcgithub.create_repo(organization, repo_name, token) try: - abcgit.add_remote(template_repo_path, organization, repo_name) + abcgit.add_remote(template_repo_path, organization, repo_name, ssh_user) except RuntimeError: print("Remote already added to local repository.") pass print("Pushing any changes to remote repository on GitHub.") try: - abcgit.push_to_github(template_repo_path, "main") + abcgit.push_to_github(template_repo_path, "main", ssh_user) except RuntimeError as e: print( """Push to github failed. This is usually because there are