async def test_review_branch_not_yet_pushed(mock_input): """ Test case for a new review branch that does not yet track any remote branch (presumably, it hasn't yet been pushed) """ with temp_repo() as upstream: merge_base = upstream.active_branch.commit assert merge_base is not None with temp_repo_clone(upstream) as downstream: new_branch = downstream.create_head("feature-123") new_branch.checkout() assert downstream.active_branch.name == "feature-123" create_git_history( downstream, [(('my-file.txt', 'sample content'), 'second commit')]) assert downstream.heads['feature-123'] is not None downstream_default_branch = git_default_branch(downstream) assert downstream_default_branch == upstream.active_branch.name with fake_cliux(log_level=INFO) as (cli, get_lines): opts = ValidateOptions( ValidateCLIOptions(verbose=True, cwd=downstream.working_dir)) await do_validate(cli=cli, opts=opts) assert strip_ansi( "".join(get_lines()) ) == """git_guardrails has completed without taking any action.
async def test_new_upstream_commits_to_pull_down(mock_input_a): """ Test case for "origin/review-branch has new commits that I must pull down" (no new local commits that origin doesn't have yet) """ with temp_repo() as upstream: upstream_default_branch = upstream.active_branch upstream_feature_branch = upstream.create_head("feature-123") # upstream_feature_branch.checkout() with temp_repo_clone(upstream, ['feature-123']) as downstream: assert ", ".join(sorted_repo_branch_names( downstream)) == f"feature-123, {upstream_default_branch.name}" upstream_feature_branch.checkout() create_git_history(upstream, [ (('file_0.txt', 'content for file 0'), 'second commit'), (('file_1.txt', 'content for file 1'), 'third commit'), (('file_2.txt', 'content for file 2'), 'fourth commit'), ]) upstream_default_branch.checkout() assert upstream.active_branch.name in ['main', 'master'] downstream.heads['feature-123'].checkout() opts = ValidateOptions( ValidateCLIOptions(verbose=False, cwd=downstream.working_dir, auto_fetch=True)) assert opts.is_verbose() == False with fake_cliux(log_level=INFO) as (cli, get_lines): assert cli.log_level == INFO await do_validate(cli=cli, opts=opts) assert strip_ansi( "".join(get_lines()) ) == """determined that local branch feature-123 tracks upstream branch feature-123 on remote origin
async def test_branch_name_passthrough(): with temp_repo() as repo: repo.index.commit("first commit") repo.create_head("special_branch") repo.git.checkout("special_branch") o = ValidateOptions(ValidateCLIOptions(verbose=True, current_branch="fizz")) assert await o.get_current_branch_name(repo) == "fizz", "--current-branch supercedes git repo state"
async def test_branch_name_infer(): with temp_repo() as repo: repo.index.commit("first commit") repo.create_head("example_branch") repo.git.checkout("example_branch") o = ValidateOptions(ValidateCLIOptions()) assert await o.get_current_branch_name(repo) == "example_branch", "absence of --current-branch results in inference"
def test_create_temp_clone(): with temp_repo() as upstream: commit_all_modified_tracked_files(upstream, "initial commit") assert upstream.is_dirty( ) == False, 'before create_git_history, repo is "clean"' create_git_history(upstream, [ (('hello1.txt', 'hello world!'), 'second commit'), (('hello2.txt', 'hello world!'), 'third commit'), (('hello3.txt', 'hello world!'), 'fourth commit'), (('hello4.txt', 'hello world!'), 'fifth commit'), ]) assert upstream.is_dirty( ) == False, 'after create_git_history, repo is left "clean"' upstream_feature_branch = upstream.create_head('feature-456') upstream_feature_branch.checkout() assert upstream.active_branch.name == 'feature-456' assert upstream.is_dirty( ) == False, f"{upstream.index.diff(other=upstream_feature_branch.commit)}" create_git_history( upstream, [(('hello5.txt', 'hello world!'), 'feature commit')]) assert upstream.is_dirty() == False upstream.heads['master'].checkout() with temp_repo_clone(upstream, ['feature-456']) as downstream: assert downstream.bare == False assert list(sorted(map(lambda h: h.name, downstream.heads))) == sorted( ['master', 'feature-456'])
async def test_to_dict(): with temp_repo() as repo: repo.index.commit("first commit") o = ValidateOptions(ValidateCLIOptions(verbose=True, cwd="foo", current_branch="fizz")) d = await o.to_dict(repo) assert d["verbose"] == True assert d["cwd"] == "foo" assert d["current_branch"] == "fizz"
async def test_do_validate_no_remote(mock_input): """ Test case for repo w/o any git remotes """ with temp_repo() as upstream: with fake_cliux() as (cli, get_lines): opts = ValidateOptions( ValidateCLIOptions(verbose=True, cwd=upstream.working_dir)) await do_validate(cli=cli, opts=opts) assert strip_ansi("".join(get_lines( ))) == """git_guardrails has completed without taking any action.
def test_create_git_history(): with temp_repo() as repo: commit_all_modified_tracked_files(repo, "initial commit") create_git_history(repo, [ (('hello1.txt', 'hello world!'), 'second commit'), (('hello2.txt', 'hello world!'), 'third commit'), (('hello3.txt', 'hello world!'), 'fourth commit'), (('hello4.txt', 'hello world!'), 'fifth commit'), ]) log = repo.head.log() assert reflog_to_str(log) == """commit: Switching to master
async def test_push_from_default_branch(mock_input): """ Test case for "push while on the default branch instead of a review branch" """ with temp_repo() as upstream: with temp_repo_clone(upstream) as downstream: with fake_cliux(log_level=INFO) as (cli, get_lines): opts = ValidateOptions( ValidateCLIOptions(verbose=False, cwd=downstream.working_dir)) await do_validate(cli=cli, opts=opts) assert strip_ansi( "".join(get_lines()) ) == """git_guardrails has completed without taking any action.
async def test_no_connect_to_remote(mock_input): """ Test case for "can't connect to git remote" """ with pytest.raises(GitRemoteConnectivityException): with temp_repo() as upstream: with temp_repo_clone(upstream) as downstream: downstream_origin: Remote = downstream.remotes['origin'] assert downstream_origin is not None downstream_origin.set_url(new_url='https://example.com') with fake_cliux(log_level=INFO) as (cli, get_lines): opts = ValidateOptions( ValidateCLIOptions(verbose=False, cwd=downstream.working_dir)) await do_validate(cli=cli, opts=opts) assert strip_ansi("".join(get_lines())) == ""
async def test_review_branch_commit_count_hard_fail(): try: with temp_repo() as upstream: upstream_default_branch = upstream.active_branch upstream.create_head('mnorth-review-111') create_git_history(upstream, [ (("demo_0.txt", "content for demo_0"), "demo 0 commit"), (("demo_1.txt", "content for demo_1"), "demo 1 commit"), (("demo_2.txt", "content for demo_2"), "demo 2 commit"), (("demo_3.txt", "content for demo_3"), "demo 3 commit"), ]) upstream_default_branch.checkout() with temp_repo_clone(upstream, ['mnorth-review-111']) as downstream: # downstream_default_branch = downstream.active_branch downstream_review_branch = downstream.heads[ 'mnorth-review-111'] assert downstream_review_branch is not None downstream_review_branch.checkout() create_git_history(downstream, [ (("demo_4.txt", "content for demo_4"), "demo 4 commit"), (("demo_5.txt", "content for demo_5"), "demo 5 commit"), (("demo_6.txt", "content for demo_6"), "demo 6 commit"), (("demo_7.txt", "content for demo_7"), "demo 7 commit"), (("demo_8.txt", "content for demo_8"), "demo 8 commit"), (("demo_9.txt", "content for demo_9"), "demo 9 commit"), (("demo_10.txt", "content for demo_10"), "demo 10 commit"), (("demo_11.txt", "content for demo_11"), "demo 11 commit"), (("demo_12.txt", "content for demo_12"), "demo 12 commit"), (("demo_13.txt", "content for demo_13"), "demo 13 commit"), (("demo_14.txt", "content for demo_14"), "demo 14 commit"), (("demo_15.txt", "content for demo_15"), "demo 15 commit"), ]) with fake_cliux(log_level=INFO) as (cli, get_lines): opts = ValidateOptions( ValidateCLIOptions(verbose=True, commit_count_soft_fail_threshold=5, commit_count_hard_fail_threshold=10, cwd=downstream.working_dir)) await do_validate(cli=cli, opts=opts) assert False, 'Error should have already been thrown by this point' except LikelyUserErrorException as ex: assert ex is not None assert strip_ansi( str(ex)) == """DANGER: VERY LARGE NUMBER OF REVIEW BRANCH COMMITS
def setup_need_to_fetch_scenario() -> Iterator[Tuple[Repo, Repo]]: with temp_repo() as upstream: # Create some commit activity on origin/master commit_all_modified_tracked_files(upstream, "initial commit") create_git_history(upstream, [ (('old_file1.txt', 'hello from an existing commit!'), 'second commit'), (('old_file2.txt', 'hello from an existing commit!'), 'third commit'), (('old_file3.txt', 'hello from an existing commit!'), 'fourth commit'), (('old_file4.txt', 'hello from an existing commit!'), 'fifth commit'), ]) # Create a review branch and check it out upstream_default_branch = upstream.active_branch upstream_review999 = upstream.create_head('review-999') upstream_review999.checkout() # Create some commit history on origin/review-999 create_git_history(upstream, [ (('hello1.txt', 'hello world!'), 'second commit'), (('hello2.txt', 'hello world!'), 'third commit'), (('hello3.txt', 'hello world!'), 'fourth commit'), (('hello4.txt', 'hello world!'), 'fifth commit'), ]) # Switch back to origin/master upstream_default_branch.checkout() # Create a "downstream" clone of the repo. This would be the user's working copy with temp_repo_clone(upstream, ['review-999']) as downstream: # Make sure the downstream clone is initially on the default branch assert downstream.active_branch.name in ['main', 'master'] # Make sure the downstream clone has a local copy of the review branch downstream_review999 = downstream.heads['review-999'] assert downstream_review999 is not None # Create some new commits on origin/review-999 upstream_review999.checkout() create_git_history(upstream, [ (('hello5.txt', 'hello world! 21'), 'purple commit'), (('hello6.txt', 'hello world! 22'), 'brown commit'), (('hello7.txt', 'hello world! 23'), 'yellow commit'), (('hello8.txt', 'hello world! 24'), 'orange commit'), ]) upstream_default_branch.checkout() yield (upstream, downstream)
def test_git_default_branch_detection(): with temp_repo() as upstream: assert upstream is not None upstream.index.commit("first commit") assert upstream.is_dirty() == False assert upstream.active_branch.name in ["master", "main"] with temp_dir() as downstream_dir: downstream = Repo.clone_from(upstream.working_dir, downstream_dir) assert downstream is not None assert downstream.is_dirty() == False new_branch = downstream.create_head("feature/123") assert len(downstream.index.unmerged_blobs()) == 0 new_branch.checkout() with create_example_file_in_repo(repo=downstream, file_path="hello.txt", content="12345") as _: downstream.index.commit("second commit") assert len(downstream.remotes) == 1 assert "feature/123" in map(lambda h: h.name, downstream.heads) assert downstream.is_dirty() == False assert downstream.active_branch.name == "feature/123" assert git_default_branch(downstream) == upstream.active_branch.name
async def test_review_branch_commit_count_soft_fail(): with temp_repo() as upstream: upstream_default_branch = upstream.active_branch upstream.create_head('mnorth-review-111') create_git_history(upstream, [ (("demo_0.txt", "content for demo_0"), "demo 0 commit"), (("demo_1.txt", "content for demo_1"), "demo 1 commit"), (("demo_2.txt", "content for demo_2"), "demo 2 commit"), (("demo_3.txt", "content for demo_3"), "demo 3 commit"), ]) upstream_default_branch.checkout() with temp_repo_clone(upstream, ['mnorth-review-111']) as downstream: # downstream_default_branch = downstream.active_branch downstream_review_branch = downstream.heads['mnorth-review-111'] assert downstream_review_branch is not None downstream_review_branch.checkout() create_git_history(downstream, [ (("demo_4.txt", "content for demo_4"), "demo 4 commit"), (("demo_5.txt", "content for demo_5"), "demo 5 commit"), (("demo_6.txt", "content for demo_6"), "demo 6 commit"), (("demo_7.txt", "content for demo_7"), "demo 7 commit"), (("demo_8.txt", "content for demo_8"), "demo 8 commit"), (("demo_9.txt", "content for demo_9"), "demo 9 commit"), (("demo_10.txt", "content for demo_10"), "demo 10 commit"), (("demo_11.txt", "content for demo_11"), "demo 11 commit"), (("demo_12.txt", "content for demo_12"), "demo 12 commit"), (("demo_13.txt", "content for demo_13"), "demo 13 commit"), (("demo_14.txt", "content for demo_14"), "demo 14 commit"), (("demo_15.txt", "content for demo_15"), "demo 15 commit"), ]) with fake_cliux(log_level=INFO) as (cli, get_lines): opts = ValidateOptions( ValidateCLIOptions(verbose=True, commit_count_soft_fail_threshold=10, commit_count_auto_bypass_soft_fail=True, cwd=downstream.working_dir)) await do_validate(cli=cli, opts=opts) assert strip_ansi( "".join(get_lines()) ) == """determined that local branch mnorth-review-111 tracks upstream branch mnorth-review-111 on remote origin
def test_git_ls_remote(): with temp_repo() as upstream: assert upstream is not None upstream.index.commit("first commit") assert upstream.is_dirty() == False assert upstream.active_branch.name in ["master", "main"] with temp_dir() as downstream_dir: downstream = Repo.clone_from(upstream.working_dir, downstream_dir) assert downstream is not None assert downstream.is_dirty() == False new_branch = downstream.create_head("feature/123") assert len(downstream.index.unmerged_blobs()) == 0 downstream_default_branch = downstream.active_branch new_branch.checkout() with create_example_file_in_repo(repo=downstream, file_path="hello.txt", content="12345") as _: downstream.index.commit("second commit") assert len(downstream.remotes) == 1 assert "feature/123" in map(lambda h: h.name, downstream.heads) assert downstream.is_dirty() == False assert downstream.active_branch.name == "feature/123" downstream_default_branch_tracked = downstream_default_branch.tracking_branch() upstream_head_commit = git_ls_remote( repo=downstream, ref=downstream_default_branch_tracked, ref_types=["heads"]) upstream_head_commit = upstream.active_branch.commit.hexsha assert upstream_head_commit == upstream_head_commit assert git_does_commit_exist_locally(downstream, upstream_head_commit) == True with create_example_file_in_repo(repo=upstream, file_path="sample.txt", content="aaa") as _: upstream.index.commit("a new commit") updated_upstream_head_commit = git_ls_remote( repo=downstream, ref=downstream_default_branch_tracked, ref_types=["heads"]) updated_upstream_head_commit = upstream.active_branch.commit.hexsha assert updated_upstream_head_commit == upstream.active_branch.commit.hexsha assert updated_upstream_head_commit != upstream_head_commit assert git_does_commit_exist_locally(downstream, updated_upstream_head_commit) == False
def test_format_commit(): with git_test_utils.temp_repo() as repo: repo.index.commit("first commit") commit = repo.active_branch.commit assert strip_ansi(format_commit(commit)) == f"{commit.hexsha[0:8]} <{commit.author.email}> - first commit"