def verify(): try: pathlib.Path(".gsc_state").read_text() except FileNotFoundError: raise verifier.VerifyError( "You haven't set up the exercise.\nRun `gsc setup`.") if not utils.clean_status(): raise verifier.VerifyError( "Your git status is not clean. Run `git status` to see the problem." ) # We should have 1 commit commit_messages = utils.commit_messages() num_commits = len(commit_messages) if num_commits != 1: raise verifier.VerifyError( f"There {utils.pluralise_commits(num_commits)} on your local branch.\n" "There should be exactly 1: the inital commit.\n" "Run `gsc reset` to try again.") # The code should be the same as in the initial commit codefile = pathlib.Path(FILE_NAME) code = codefile.read_text() if (""" def subtract(x, y): return x - y""" not in code): raise verifier.VerifyError( "The code is not the same as it was originally.\n" "You've done something strange. Email us for help if you're not sure what.\n" "Run `gsc reset` and try again.") cli.success("Done.")
def verify(): if not utils.clean_status(): raise verifier.VerifyError( "Your git status is not clean. Run `git status` to see the problem." ) if not utils.on_branch("master"): raise verifier.VerifyError( "You should be on the master branch for this exercise.\n" "Change branch with `git checkout master` and try again.") # We should be one commit ahead of remote master res = subprocess.run( [ "git", "rev-list", "--left-right", "--count", "master...origin/master" ], stdout=PIPE, stderr=PIPE, ) res = res.stdout.decode("utf-8").strip().split("\t") if ["1", "0"] != res: raise verifier.VerifyError( f"You need to make 1 commit but you've made {res[0]}.") # We should ideally have this exact commit message but no bother if not msg = utils.most_recent_commit_message() utils.check_commit_message(msg) if msg != "Switch `subtract` to use correct operator": cli.warn( "Looks like you didn't choose the suggested commit message.\n" 'When you get to the "Useful Commit Messages" section, be sure to come back here ' "and check that your message is good.") cli.success("Looks good.")
def verify(): res = subprocess.run(["git", "remote", "-v"], stdout=PIPE, stderr=PIPE) res = res.stdout.decode("utf-8").strip() if "[email protected]:" not in res: raise verifier.VerifyError("Repo not cloned using SSH.") cli.success("Looks good.")
def verify(): if not utils.clean_status(): raise verifier.VerifyError( "Your git status is not clean. Run `git status` to see the problem." ) commit_messages = utils.commit_messages() # We should have 3 commits num_commits = len(commit_messages) if num_commits != 3: raise verifier.VerifyError( f"There {utils.pluralise_commits(num_commits)} on your local branch.\n" "There should be exactly 3: the 2 original commits and 1 revert commit.\n" "Run `gsc reset` to try again.") # The code should be the same as in the initial commit codefile = pathlib.Path(FILE_NAME) code = codefile.read_text() if (""" def subtract(x, y): return x + y""" not in code): raise verifier.VerifyError( "You chose the wrong version of the code when fixing the conflict.\n" "This implementation is broken!\n" 'Take another look at "Fix the Merge Conflict".\n' "Run `gsc reset` and try again.") # The revert commit title should start with the word "Revert". title = utils.most_recent_commit_message() if not title.startswith("Revert"): raise verifier.VerifyError( 'The revert commit title should start with the word "Revert".\n' "Git does this automatically when you revert a commit - don't change it!" ) # The reverted commit hash should be in the revert commit description. desc = utils.most_recent_commit_description() if REVERT_HASH not in desc: raise verifier.VerifyError( "The commit hash is not in the commit message description.\n" "Git puts it there automatically when you revert a commit - don't delete it!" ) cli.success("Done.")
def verify(): # TODO: this should be sorted out properly. # We can run git log on the correct branch. # We can check out the file from the correct branch as long as we back it up and restore it # after. # Then we won't need to change branch. # If we're still in the middle of the merge conflict we won't be able to change branch if utils.mid_rebase(): raise verifier.VerifyError( "You haven't finished rebasing yet. Run `git status` to see what to do next." ) state = json.loads(pathlib.Path(".gsc_state").read_text()) # We should have the branch res = subprocess.run(["git", "checkout", BRANCH_NAME], stdout=PIPE, stderr=PIPE) if res.returncode != 0: raise verifier.VerifyError( f'The "{BRANCH_NAME}" branch has been deleted!\n' "Run `gsc reset` to start again.") commit_hashes = utils.git_log_hashes() commit_messages = utils.git_log_oneline() codefile = pathlib.Path(FILE_NAME) code = codefile.read_text() payload = { "git status --porcelain": utils.git_status(), "git branch": utils.git_branch(), "branch_name": BRANCH_NAME, "state": state, "git log --format=%H": commit_hashes, "git log --oneline": commit_messages, "master_commit_message": MASTER_COMMIT_MSG, "branch_commit_message": BRANCH_COMMIT_MSG, "code": code, } client.verify("merge_conflict", payload)
def verify(): if not utils.clean_status(): raise verifier.VerifyError( "Your git status is not clean. Run `git status` to see the problem." ) if not utils.on_branch("master"): raise verifier.VerifyError( "You should be on the master branch for this exercise.\n" "Change branch with `git checkout master` and try again.") state = json.loads(pathlib.Path(".gsc_state").read_text()) commit_hashes = utils.commit_hashes() # We should have the remote commit if state["remote_hash"] not in commit_hashes: raise verifier.VerifyError( f'The "{REMOTE_COMMIT_MSG}" commit is missing!\n' "It's on the remote repo. You need to bring in into your local somehow..." ) commit_messages = utils.commit_messages() # We should have the local commit if LOCAL_COMMIT_MSG not in commit_messages: raise verifier.VerifyError( f'The "{LOCAL_COMMIT_MSG}" commit is missing!\n' "Run `gsc reset` and try again.") # We should not have a merge commit if any(["Merge branch" in msg for msg in commit_messages]): raise verifier.VerifyError( "You created a merge commit when you pulled in the remote commit.\n" 'Take another look at "How do we fix a sync error?"\n' "Run `gsc reset` and try again.") # We should be up to date with the remote utils.assert_up_to_date_with_remote("master") cli.success("Done.")
def verify(): if not utils.clean_status(): raise verifier.VerifyError( "Your git status is not clean. Run `git status` to see the problem." ) if not utils.on_branch("master"): raise verifier.VerifyError( "You should be on the master branch for this exercise.\n" "Change branch with `git checkout master` and try again." ) cwd = os.getcwd() if cwd.endswith(PULL_SUFFIX): repo_name = cwd[: -len(PULL_SUFFIX)] pull_repo_name = cwd else: repo_name = cwd pull_repo_name = cwd + PULL_SUFFIX # Check that both repos contain the commit we want. os.chdir(repo_name) msgs = utils.commit_messages() if COMMIT_MSG not in msgs: raise verifier.VerifyError( "Setup commit not found. Did you run `gsc setup push_and_pull`?" ) os.chdir(pull_repo_name) msgs = utils.commit_messages() if COMMIT_MSG not in msgs: raise verifier.VerifyError( "The commit has not been pulled into your local repo.\n" f"The repo is located at {pull_repo_name}\n" "See the My First Pull section of the lesson." ) cli.success("Done.")
def assert_up_to_date_with_remote(branch: str) -> None: res = subprocess.run( ["git", "rev-list", "--left-right", "--count", f"{branch}...origin/{branch}"], stdout=PIPE, stderr=PIPE, ) commits = res.stdout.decode("utf-8").strip().split("\t") if ["0", "0"] != commits: raise verifier.VerifyError( f"There {pluralise_commits(commits[0])} on your local repo which aren't on your remote.\n" f"There {pluralise_commits(commits[1])} on your remote repo which aren't on your local.\n" "Your local and remote repos should have the same commits.\n" "Run `gsc reset` to try again if you aren't sure what's gone wrong." )
def verify(): # TODO: this should be sorted out properly. # See merge_conflict.py if utils.mid_rebase(): raise verifier.VerifyError( "You haven't finished rebasing yet. Run `git status` to see what to do next." ) state = json.loads(pathlib.Path(".gsc_state").read_text()) # We should have the branch res = subprocess.run(["git", "checkout", BRANCH_NAME], stdout=PIPE, stderr=PIPE) if res.returncode != 0: raise verifier.VerifyError( f'The "{BRANCH_NAME}" branch has been deleted!\n' "Run `gsc reset` to start again." ) commit_hashes = utils.git_log_hashes() commit_messages = utils.git_log_oneline() codefile = pathlib.Path(FILE_NAME) code = codefile.read_text() payload = { "git status --porcelain": utils.git_status(), "git branch": utils.git_branch(), "git rev-list --left-right --count": utils.rev_list_count_remote(BRANCH_NAME), "branch_name": BRANCH_NAME, "state": state, "git log --format=%H": commit_hashes, "git log --oneline": commit_messages, "master_commit_message": MASTER_COMMIT_MSG, "branch_commit_message": BRANCH_COMMIT_MSG, "code": code, } client.verify("use_the_force", payload)
def verify(): if not utils.clean_status(): raise verifier.VerifyError( "Your git status is not clean. Run `git status` to see the problem." ) state = json.loads(pathlib.Path(".gsc_state").read_text()) # We should have the branch res = subprocess.run(["git", "checkout", BRANCH_NAME], stdout=PIPE, stderr=PIPE) if res.returncode != 0: raise verifier.VerifyError( f'The "{BRANCH_NAME}" branch has been deleted!\n' "Run `gsc reset` to start again.") commit_hashes = utils.commit_hashes() # We should have the master commit if state["master_hash"] not in commit_hashes: raise verifier.VerifyError( f'The "{MASTER_COMMIT_MSG}" commit is missing!\n' f"It's on the master branch. You need to bring in into the `{BRANCH_NAME}` branch somehow..." ) commit_messages = utils.commit_messages() # We should have the branch commit if BRANCH_COMMIT_MSG not in commit_messages: raise verifier.VerifyError( f'The "{BRANCH_COMMIT_MSG}" commit is missing!\n' "Run `gsc reset` and try again.") # We should not have a merge commit if any(["Merge branch" in msg for msg in commit_messages]): raise verifier.VerifyError( "You created a merge commit when you pulled in the remote commit.\n" 'Take another look at "Exercise Setup".\n' "Run `gsc reset` and try again.") # We should have chosen the correct version of the code in the conflict codefile = pathlib.Path(FILE_NAME) code = codefile.read_text() if (""" def divide(x, y): return x / y""" not in code): raise verifier.VerifyError( "You chose the wrong version of the code when fixing the conflict.\n" "This implementation is broken!\n" 'Take another look at "Fix the Merge Conflict".\n' "Run `gsc reset` and try again.") # We should be up to date with the remote. utils.assert_up_to_date_with_remote(BRANCH_NAME) cli.success("Done.")
def verify(id: str, payload: t.Dict[str, str]) -> str: cookies = auth.cookies() res = requests.post(API_URL + "/verify/" + id, json=payload, cookies=cookies) if res.status_code == 200: reply = json.loads(res.text) if reply["status"] == "ok": handle_warnings(reply) cli.success("Looks good.") return "Exercise complete" elif reply["status"] == "failed_verification": raise verifier.VerifyError(reply["msg"]) elif reply["status"] == "error": raise APIError(reply["msg"]) else: raise APIError("Unexpected API response. Try updating gsc.") raise api_error(res.status_code)
def verify(): try: state = json.loads(pathlib.Path(".gsc_state").read_text()) except FileNotFoundError: raise verifier.VerifyError( "You haven't set up the exercise.\nRun `gsc setup`.") commit_messages = utils.git_log_oneline() # The code should be the same as in the initial commit codefile = pathlib.Path(FILE_NAME) code = codefile.read_text() payload = { "git status --porcelain": utils.git_status(), "git branch": utils.git_branch(), "git log --oneline": commit_messages, "state": state, "code": code, } client.verify("reset_file", payload)
def verify(): # We should have an origin remote with a fork url res = subprocess.run(["git", "remote", "-v"], stdout=PIPE, stderr=PIPE) if res.returncode != 0: raise verifier.VerifyError("Failed to list remote repos") remotes = {} res = res.stdout.decode("utf-8").strip().split("\n") for r in res: [name, url] = r.split("\t") [url, _] = url.split(" ") remotes[name] = url if remotes["origin"] in [ UPSTREAM_URL, UPSTREAM_URL_GIT, UPSTREAM_SSH_URL, UPSTREAM_SSH_URL_GIT, ]: raise verifier.VerifyError( "You've cloned the upstream repo. You need to fork the repo first and then clone your fork." ) num_remotes = len(remotes) if num_remotes == 1: raise verifier.VerifyError( "This repo only has one remote. You need to add the upstream repo as a second remote." ) elif num_remotes > 2: raise verifier.VerifyError( f"This repo has {num_remotes} remotes. There should be exactly 2.\n" "Delete your local repo, clone your fork, and try adding the upstream remote again." ) # We should have an upstream remote with the original url upstream = "upstream" if upstream not in remotes: remote_names = list(remotes.keys()) remote_names.remove("origin") [upstream] = remote_names if remotes[upstream] in [ UPSTREAM_URL, UPSTREAM_URL_GIT, UPSTREAM_SSH_URL, UPSTREAM_SSH_URL_GIT, ]: cli.warn( f'I couldn\'t find the upstream remote, but I did find a remote called "{name}" with the correct url.\n' 'You should consider calling your upstream remotes "upstream" instead.' ) else: raise verifier.VerifyError( "I couldn't find the upstream remote.\n" f'I found a remote called "{name}" with the wrong url.\n' f"{UPSTREAM_URL} is the correct url.\n" f"{remotes[name]} is what you have.") if remotes[upstream] in [UPSTREAM_SSH_URL, UPSTREAM_SSH_URL_GIT]: cli.warn( "You've used SSH for the upstream URL.\n" "There's no point using SSH for the upstream.\n" "You don't have write access and the repo is public, so HTTPS will do everything we need." ) elif remotes[upstream] not in [UPSTREAM_URL, UPSTREAM_URL_GIT]: raise verifier.VerifyError("The upstream url is not correct.\n" f"{UPSTREAM_URL} is the correct url.\n" f"{remotes[name]} is what you have.") cli.success("Done.")