def test_sync_with_errors( tsrc_cli: CLI, git_server: GitServer, workspace_path: Path, message_recorder: MessageRecorder, ) -> None: """ " Scenario: * Create a manifest with two repos (foo and bar) * Initialize a workspace from this manifest * Push a new file to the foo repo * Create a merge conflict in the foo repo * Run `tsrc sync` * Check that it fails and contains the proper error message """ git_server.add_repo("foo") git_server.add_repo("bar") manifest_url = git_server.manifest_url tsrc_cli.run("init", manifest_url) git_server.push_file("foo", "conflict.txt", contents="this is red") foo_src = workspace_path / "foo" (foo_src / "conflict.txt").write_text("this is green") tsrc_cli.run_and_fail("sync") assert message_recorder.find("Failed to synchronize workspace") assert message_recorder.find(r"\* foo")
def test_foreach_with_groups_from_config( tsrc_cli: CLI, git_server: GitServer, message_recorder: MessageRecorder ) -> None: """ * Create a manifest containing: * a group named `foo` with repos `bar` and `baz`, * a group named `spam` with repos `eggs` and `beacon` * a repo named `other`, not part of any group * Initialize a workspace from this manifest, using the `foo` and `spam` groups * Check that `tsrc foreach ---group "foo" --ls README` works and runs `ls` only on everything but `other` """ git_server.add_group("foo", ["bar", "baz"]) git_server.add_group("spam", ["eggs", "beacon"]) git_server.add_repo("other") manifest_url = git_server.manifest_url tsrc_cli.run("init", manifest_url, "--groups", "foo", "spam") message_recorder.reset() tsrc_cli.run("foreach", "ls") assert message_recorder.find("bar\n") assert message_recorder.find("baz\n") assert message_recorder.find("eggs\n") assert not message_recorder.find("other\n")
def test_use_given_group( tsrc_cli: CLI, git_server: GitServer, workspace_path: Path, message_recorder: MessageRecorder, ) -> None: """Scenario: * Create a manifest with two disjoint groups, group1 and group2 * Initialize a workspace from this manifest using the two groups * Run `tsrc status --group group1` * Check that the output contains repos from group1, but not from group2 """ git_server.add_group("group1", ["foo"]) git_server.add_group("group2", ["bar"]) manifest_url = git_server.manifest_url tsrc_cli.run("init", manifest_url, "--groups", "group1", "group2") message_recorder.reset() tsrc_cli.run("status", "--group", "group1") assert message_recorder.find(r"\* foo"), "foo status have been read" assert not message_recorder.find(r"\* bar"), "bar should have been skipped"
def test_foreach_with_all_cloned_repos_requested( tsrc_cli: CLI, git_server: GitServer, workspace_path: Path, message_recorder: MessageRecorder, ) -> None: """ * Create a manifest containing: * a group named `foo` with repos `bar` and `baz`, * a group named `spam` with repos `eggs` and `beacon` * a repo named `quux`, not part of any group * Initialize a workspace from this manifest, using the `foo` group * Force the clone of the `other` repo * Check that `tsrc foreach --all-cloned` visits all repos """ git_server.add_group("foo", ["bar", "baz"]) git_server.add_group("spam", ["eggs", "bacon"]) quux_url = git_server.add_repo("quux") manifest_url = git_server.manifest_url tsrc_cli.run("init", manifest_url, "--groups", "foo", "spam") tsrc.git.run(workspace_path, "clone", quux_url) message_recorder.reset() tsrc_cli.run("foreach", "--all-cloned", "ls") assert message_recorder.find("bar\n") assert message_recorder.find("baz\n") assert message_recorder.find("eggs\n") assert message_recorder.find("bacon\n") assert message_recorder.find("quux\n")
def test_happy(tsrc_cli: CLI, git_server: GitServer, message_recorder: MessageRecorder) -> None: """ Scenario: * Create a manifest with two repos, foo and bar * Initialize a workspace from this manifest * Create a tag named v0.1 on foo and bar * Run `tsrc log --from v0.1 """ git_server.add_repo("foo") git_server.add_repo("spam") git_server.push_file("foo", "bar.txt", message="boring bar") git_server.tag("foo", "v0.1") git_server.tag("spam", "v0.1") manifest_url = git_server.manifest_url tsrc_cli.run("init", manifest_url) git_server.push_file("foo", "foo.txt", message="new foo!") tsrc_cli.run("sync") message_recorder.reset() tsrc_cli.run("log", "--from", "v0.1") assert message_recorder.find("new foo!") message_recorder.reset() tsrc_cli.run("log", "--from", "v0.1", "--to", "v0.1") assert not message_recorder.find("new foo!")
def test_custom_group(tsrc_cli: CLI, git_server: GitServer, message_recorder: MessageRecorder) -> None: git_server.add_group("foo", ["bar", "baz"]) git_server.add_repo("other") tsrc_cli.run("init", git_server.manifest_url, "--group", "foo") message_recorder.reset() tsrc_cli.run("sync") assert message_recorder.find("bar") assert not message_recorder.find("other")
def test_foreach_with_errors(tsrc_cli: CLI, git_server: GitServer, message_recorder: MessageRecorder) -> None: git_server.add_repo("foo") git_server.add_repo("spam") git_server.push_file("foo", "foo/bar.txt", contents="this is bar") manifest_url = git_server.manifest_url tsrc_cli.run("init", manifest_url) cmd = get_cmd_for_foreach_test(shell=False) cmd.append("foo") tsrc_cli.run("foreach", *cmd, expect_fail=True) assert message_recorder.find("Command failed") assert message_recorder.find(r"\* spam")
def test_sync_with_errors(tsrc_cli: CLI, git_server: GitServer, workspace_path: Path, message_recorder: MessageRecorder) -> None: git_server.add_repo("foo/bar") git_server.add_repo("spam/eggs") manifest_url = git_server.manifest_url tsrc_cli.run("init", manifest_url) git_server.push_file("foo/bar", "bar.txt", contents="Bar is true") bar_src = workspace_path / "foo/bar" (bar_src / "bar.txt").write_text("Bar is false") tsrc_cli.run("sync", expect_fail=True) assert message_recorder.find("Failed to synchronize workspace") assert message_recorder.find(r"\* foo/bar")
def test_status_happy(tsrc_cli: CLI, git_server: GitServer, workspace_path: Path, message_recorder: MessageRecorder) -> None: git_server.add_repo("foo/bar") git_server.add_repo("spam/eggs") git_server.push_file("foo/bar", "CMakeLists.txt") git_server.push_file("spam/eggs", "CMakeLists.txt") manifest_url = git_server.manifest_url tsrc_cli.run("init", manifest_url) tsrc.git.run(workspace_path / "spam/eggs", "checkout", "-b", "fish") tsrc_cli.run("status") assert message_recorder.find(r"\* foo/bar master") assert message_recorder.find(r"\* spam/eggs fish")
def test_sync_not_on_master( tsrc_cli: CLI, git_server: GitServer, workspace_path: Path, message_recorder: MessageRecorder, ) -> None: """ " Scenario: * Create a manifest with two repos, foo and bar * Initialize a workspace from this manifest * Checkout a different branch on foo, tracking an existing remote * Run `tsrc sync` * Check that: * foo is updated * but the command fails because foo was not an the expected branch """ git_server.add_repo("foo") git_server.add_repo("bar") git_server.push_file("foo", "devel.txt", branch="devel") manifest_url = git_server.manifest_url tsrc_cli.run("init", manifest_url) foo_path = workspace_path / "foo" tsrc.git.run(foo_path, "checkout", "-B", "devel") tsrc.git.run(foo_path, "branch", "--set-upstream-to", "origin/devel") tsrc_cli.run_and_fail("sync") assert (foo_path / "devel.txt").exists(), "foo should have been updated" assert message_recorder.find("not on the correct branch")
def test_status_not_on_any_branch( tsrc_cli: CLI, git_server: GitServer, workspace_path: Path, message_recorder: MessageRecorder, ) -> None: """Scenario: * Create a workspace with one repo * Make sure the repo is not an any branch * Run `tsrc status` * Check that the output contains a sha1 """ git_server.add_repo("foo") # we need more that one commit # to be in 'detached HEAD': git_server.push_file("foo", "new.txt") git_server.add_repo("bar") tsrc_cli.run("init", git_server.manifest_url) # detach HEAD on foo repo foo_path = workspace_path / "foo" run_git(foo_path, "checkout", "HEAD~1") tsrc_cli.run("status") assert message_recorder.find(r"\* foo [a-f0-9]{7}")
def test_status_incorrect_branch( tsrc_cli: CLI, git_server: GitServer, workspace_path: Path, message_recorder: MessageRecorder, ) -> None: """Scenario: * Create a workspace with one repo * Create and checkout an 'other' branch * Run `tsrc status` * Check that the repo is shown as not being on the correct branch """ git_server.add_repo("foo") manifest_url = git_server.manifest_url tsrc_cli.run("init", manifest_url) foo_path = workspace_path / "foo" run_git(foo_path, "checkout", "-b", "other") run_git(foo_path, "push", "--set-upstream", "origin", "other:other") tsrc_cli.run("status") assert message_recorder.find(r"\* foo\s+other\s+\(expected: master\)")
def test_no_tracked_branch_non_interactive( test_repo: Path, message_recorder: MessageRecorder) -> None: tbump.git.run_git(test_repo, "checkout", "-b", "devel") with pytest.raises(SystemExit): tbump.main.main(["-C", str(test_repo), "1.2.42", "--non-interactive"]) assert message_recorder.find("Cannot push")
def test_no_tracked_branch_but_ref_exists( test_repo: Path, message_recorder: MessageRecorder) -> None: tbump.git.run_git(test_repo, "checkout", "-b", "devel") with pytest.raises(SystemExit): tbump.main.main(["-C", str(test_repo), "1.2.41-alpha-1"]) assert message_recorder.find("already exists")
def test_abort_if_tag_exists(test_repo: Path, message_recorder: MessageRecorder) -> None: tbump.git.run_git(test_repo, "tag", "v1.2.42") with pytest.raises(SystemExit): tbump.main.main(["-C", str(test_repo), "1.2.42", "--non-interactive"]) assert message_recorder.find("1.2.42 already exists")
def test_status_not_on_any_branch(tsrc_cli: CLI, git_server: GitServer, workspace_path: Path, message_recorder: MessageRecorder) -> None: git_server.add_repo("foo/bar") git_server.add_repo("spam/eggs") git_server.push_file("foo/bar", "CMakeLists.txt") git_server.push_file("spam/eggs", "CMakeLists.txt") tsrc_cli.run("init", git_server.manifest_url) # corrupt the git eggs_path = workspace_path / "spam/eggs" tsrc.git.run(eggs_path, "checkout", "HEAD~1") tsrc_cli.run("status") assert message_recorder.find(r"\* foo/bar \s+ master") assert message_recorder.find(r"\* spam/eggs [a-f0-9]{7}")
def test_tbump_toml_not_found(test_repo: Path, message_recorder: MessageRecorder) -> None: toml_path = test_repo / "tbump.toml" toml_path.unlink() with pytest.raises(SystemExit): tbump.main.main(["-C", str(test_repo), "1.2.42", "--non-interactive"]) assert message_recorder.find("No such file")
def test_abort_if_dirty(test_repo: Path, message_recorder: MessageRecorder) -> None: version_path = test_repo / "VERSION" with version_path.open("a") as f: f.write("unstaged changes\n") with pytest.raises(SystemExit): tbump.main.main(["-C", str(test_repo), "1.2.41-alpha-2", "--non-interactive"]) assert message_recorder.find("dirty")
def test_foreach_with_errors(tsrc_cli: CLI, git_server: GitServer, message_recorder: MessageRecorder) -> None: """ Scenario: * Create a repo 'foo' * Create a repo 'bar' containing 'stuff.txt' Check that tsr foreach -- ls stuff.txt fails, and prints the failing repo in the list of error """ git_server.add_repo("foo") git_server.add_repo("bar") git_server.push_file("bar", "stuff.txt", contents="some stuff") manifest_url = git_server.manifest_url tsrc_cli.run("init", manifest_url) tsrc_cli.run("foreach", "ls", "stuff.txt", expect_fail=True) assert message_recorder.find("Command failed") assert message_recorder.find(r"\* foo")
def test_pyproject_toml_not_found( test_repo: Path, message_recorder: MessageRecorder ) -> None: toml_path = test_repo / "pyproject.toml" toml_path.remove() with pytest.raises(SystemExit): tbump.main.main(["-C", test_repo, "1.2.42", "--non-interactive"]) assert message_recorder.find("No such file")
def test_foreach_with_groups_from_config( tsrc_cli: CLI, git_server: GitServer, message_recorder: MessageRecorder) -> None: git_server.add_group("foo", ["bar", "baz"]) git_server.add_group("spam", ["eggs", "beacon"]) git_server.add_repo("other") manifest_url = git_server.manifest_url tsrc_cli.run("init", manifest_url, "--groups", "foo", "spam") message_recorder.reset() tsrc_cli.run("foreach", "--groups-from-config", "ls") assert message_recorder.find("bar\n") assert message_recorder.find("baz\n") assert message_recorder.find("eggs\n") assert not message_recorder.find("other\n")
def test_abort_if_file_does_not_exist( test_repo: Path, message_recorder: MessageRecorder ) -> None: (test_repo / "package.json").remove() tbump.git.run_git(test_repo, "add", "--update") tbump.git.run_git(test_repo, "commit", "--message", "remove package.json") with pytest.raises(SystemExit): tbump.main.main(["-C", test_repo, "1.2.41-alpha-2", "--non-interactive"]) assert message_recorder.find("package.json does not exist")
def test_foreach_groups_happy(tsrc_cli: CLI, git_server: GitServer, message_recorder: MessageRecorder) -> None: git_server.add_group("foo", ["bar", "baz"]) git_server.add_group("spam", ["eggs", "beacon"]) git_server.add_repo("other") manifest_url = git_server.manifest_url tsrc_cli.run("init", manifest_url, "-g", "foo", "-g", "spam") cmd = get_cmd_for_foreach_test(shell=False) message_recorder.reset() tsrc_cli.run("foreach", "-g", "foo", *cmd) assert message_recorder.find("bar\n") assert message_recorder.find("baz\n") assert not message_recorder.find("eggs\n") assert not message_recorder.find("other\n")
def test_tbump_toml_bad_syntax(test_repo: Path, message_recorder: MessageRecorder) -> None: toml_path = test_repo / "tbump.toml" bad_toml = tomlkit.loads(toml_path.read_text()) del bad_toml["git"] toml_path.write_text(tomlkit.dumps(bad_toml)) with pytest.raises(SystemExit): tbump.main.main(["-C", str(test_repo), "1.2.42", "--non-interactive"]) assert message_recorder.find("Invalid config")
def test_copy_files_source_does_not_exist( tsrc_cli: CLI, git_server: GitServer, workspace_path: Path, message_recorder: MessageRecorder) -> None: manifest_url = git_server.manifest_url git_server.add_repo("master") git_server.manifest.set_repo_file_copies("master", [("top.cmake", "CMakeLists.txt")]) tsrc_cli.run("init", manifest_url, expect_fail=True) assert message_recorder.find("Failed to perform the following copies")
def test_bad_substitution(test_repo: Path, message_recorder: MessageRecorder) -> None: toml_path = test_repo / "pyproject.toml" new_toml = tomlkit.loads(toml_path.text()) new_toml["tool"]["tbump"]["file"][0]["version_template"] = "{release}" toml_path.write_text(tomlkit.dumps(new_toml)) tbump.git.run_git(test_repo, "add", ".") tbump.git.run_git(test_repo, "commit", "--message", "update repo") with pytest.raises(SystemExit): tbump.main.main(["-C", test_repo, "1.2.42"]) assert message_recorder.find("refusing to replace by version containing 'None'")
def test_shallow_with_fix_ref(tsrc_cli: CLI, git_server: GitServer, workspace_path: Path, message_recorder: MessageRecorder) -> None: git_server.add_repo("foo") initial_sha1 = git_server.get_sha1("foo") git_server.push_file("foo", "one.c") git_server.manifest.set_repo_sha1("foo", initial_sha1) manifest_url = git_server.manifest_url tsrc_cli.run("init", "--shallow", manifest_url, expect_fail=True) assert message_recorder.find("Cannot use --shallow with a fixed sha1")
def test_happy(tsrc_cli: CLI, git_server: GitServer, message_recorder: MessageRecorder) -> None: git_server.add_repo("foo") git_server.add_repo("spam") git_server.push_file("foo", "bar.txt", message="boring bar") git_server.tag("foo", "v0.1") git_server.tag("spam", "v0.1") manifest_url = git_server.manifest_url tsrc_cli.run("init", manifest_url) git_server.push_file("foo", "foo.txt", message="new foo!") tsrc_cli.run("sync") message_recorder.reset() tsrc_cli.run("log", "--from", "v0.1") assert message_recorder.find("new foo!") message_recorder.reset() tsrc_cli.run("log", "--from", "v0.1", "--to", "v0.1") assert not message_recorder.find("new foo!")
def test_changing_branch(tsrc_cli: CLI, git_server: GitServer, workspace_path: Path, message_recorder: MessageRecorder) -> None: git_server.add_repo("foo") manifest_url = git_server.manifest_url tsrc_cli.run("init", manifest_url) git_server.change_repo_branch("foo", "next") git_server.push_file("foo", "next.txt") git_server.manifest.set_repo_branch("foo", "next") tsrc_cli.run("sync", expect_fail=True) assert message_recorder.find("not on the correct branch")
def test_foreach_shell(tsrc_cli: CLI, git_server: GitServer, message_recorder: MessageRecorder) -> None: git_server.add_repo("foo") git_server.add_repo("spam") git_server.push_file("foo", "doc/index.html") git_server.push_file("spam", "doc/index.html") manifest_url = git_server.manifest_url tsrc_cli.run("init", manifest_url) cmd = get_cmd_for_foreach_test(shell=True) cmd.append("doc") tsrc_cli.run("foreach", "-c", " ".join(cmd)) assert message_recorder.find("`%s`" % " ".join(cmd))