def test_set_project_dest_and_branch( tsrc_cli: CLI, git_server: GitServer, workspace_path: Path ) -> None: git_server.add_repo("foo") git_server.add_repo("bar", default_branch="devel") tsrc_cli.run("init", git_server.manifest_url) bar_path = workspace_path / "bar" run_git(bar_path, "checkout", "-b", "other") workspace = Workspace(workspace_path) manifest = workspace.get_manifest() env_setter = EnvSetter(workspace) workspace_vars = get_workspace_vars(workspace) assert workspace_vars["TSRC_MANIFEST_URL"] == git_server.manifest_url assert workspace_vars["TSRC_MANIFEST_BRANCH"] == "master" assert workspace_vars["TSRC_WORKSPACE_PATH"] == str(workspace_path) foo_repo = manifest.get_repo("foo") foo_env = env_setter.get_env_for_repo(foo_repo) # check that shared env is part of the result for foo assert foo_env["TSRC_MANIFEST_URL"] == git_server.manifest_url assert foo_env["TSRC_PROJECT_CLONE_URL"] == foo_repo.clone_url # check that bar and foo envs are different bar_repo = manifest.get_repo("bar") bar_env = env_setter.get_env_for_repo(bar_repo) assert bar_env["TSRC_PROJECT_DEST"] == "bar" assert bar_env["TSRC_PROJECT_MANIFEST_BRANCH"] == "devel" # check that git status is set assert bar_env["TSRC_PROJECT_STATUS_BRANCH"] == "other"
def add_remote(self, repo: Repo, remote: Remote) -> None: full_path = self.workspace_path / repo.dest # fmt: off self.info_3(repo.dest + ":", "Add remote", ui.reset, ui.bold, remote.name, ui.reset, ui.brown, f"({remote.url})") # fmt: on run_git(full_path, "remote", "add", remote.name, remote.url)
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_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") run_git(workspace_path, "clone", quux_url) message_recorder.reset() tsrc_cli.run("foreach", "--all-cloned", "ls") assert message_recorder.find(r"\bbar\b") assert message_recorder.find(r"\bbaz\b") assert message_recorder.find(r"\beggs\b") assert message_recorder.find(r"\bbacon\b") assert message_recorder.find(r"\bquux\b")
def update(self, url: str, *, branch: str) -> None: run_git(self.clone_path, "remote", "set-url", "origin", url) run_git(self.clone_path, "fetch") run_git(self.clone_path, "checkout", "-B", branch) run_git(self.clone_path, "branch", branch, "--set-upstream-to", f"origin/{branch}") ref = f"origin/{branch}" run_git(self.clone_path, "reset", "--hard", ref)
def run_git(self, working_path: Path, *args: str) -> None: """Same as tsrc.git.run_git, except the output of the git command is captured if the task is run in parallel with other tasks. """ if self.parallel: run_git(working_path, *args, show_output=False, show_cmd=False) else: run_git(working_path, *args)
def set_remote(self, repo: Repo, remote: Remote) -> None: full_path = self.workspace_path / repo.dest # fmt: off self.info_3(repo.dest + ":", "Update remote", ui.reset, ui.bold, remote.name, ui.reset, "to new url:", ui.brown, f"({remote.url})") # fmt: on run_git(full_path, "remote", "set-url", remote.name, remote.url)
def test_can_set_remote_head(tmp_path: Path, git_server: GitServer) -> None: git_server.add_repo("foo") git_server.manifest.change_branch("main") git_server.manifest.set_head("main") run_git(tmp_path, "clone", git_server.manifest_url, "manifest") assert get_current_branch(tmp_path / "manifest") == "main"
def test_add_repo_can_clone(workspace_path: Path, git_server: GitServer) -> None: """Check that repo added to the GitServer can be cloned, typically, they should be bare but not empty! """ foobar_url = git_server.add_repo("foo/bar") run_git(workspace_path, "clone", foobar_url) assert (workspace_path / "bar").exists()
def init(self, url: str, *, branch: Optional[str]) -> None: parent = self.clone_path.parent name = self.clone_path.name parent.mkdir(parents=True, exist_ok=True) cmd = ["clone", url] if branch: cmd += ["--branch", branch] cmd += [name] run_git(self.clone_path.parent, *cmd)
def test_no_remote_named_origin(tsrc_cli: CLI, git_server: GitServer, workspace_path: Path) -> None: git_server.add_repo("foo") tsrc_cli.run("init", git_server.manifest_url) foo_path = workspace_path / "foo" run_git(foo_path, "remote", "rename", "origin", "upstream") tsrc_cli.run("sync")
def test_create_submodule(workspace_path: Path, git_server: GitServer) -> None: top_url = git_server.add_repo("top") sub_url = git_server.add_repo("sub", add_to_manifest=False) git_server.add_submodule("top", url=sub_url, path=Path("sub")) run_git(workspace_path, "clone", top_url, "--recurse-submodules") top_path = workspace_path / "top" sub_readme = top_path / "sub" / "README" assert sub_readme.exists()
def test_default_branch_devel(workspace_path: Path, git_server: GitServer) -> None: foo_url = git_server.add_repo("foo", default_branch="devel") run_git(workspace_path, "clone", foo_url) foo_path = workspace_path / "foo" cloned_branch = get_current_branch(foo_path) assert cloned_branch == "devel" manifest = read_remote_manifest(workspace_path, git_server) foo_config = manifest.get_repo("foo") assert foo_config.branch == "devel"
def test_multiple_manifest_branches( workspace_path: Path, git_server: GitServer ) -> None: git_server.add_repo("foo") git_server.manifest.change_branch("devel") git_server.add_repo("bar") run_git(workspace_path, "clone", git_server.manifest_url) manifest_yml = workspace_path / "manifest/manifest.yml" manifest = load_manifest(manifest_yml) assert len(manifest.get_repos()) == 1 run_git(workspace_path / "manifest", "reset", "--hard", "origin/devel") manifest = load_manifest(manifest_yml) assert len(manifest.get_repos()) == 2
def test_status_on_tag( tsrc_cli: CLI, git_server: GitServer, workspace_path: Path, message_recorder: MessageRecorder, ) -> None: """Scenario: * Create a workspace with one repo * Create a tag on the repo * Run `tsrc status` * Check that the output contains the tag name """ 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, "tag", "v1.0") tsrc_cli.run("status") assert message_recorder.find(r"\* foo master on v1.0")
def test_update_submodule(workspace_path: Path, git_server: GitServer) -> None: top_url = git_server.add_repo("top") sub_url = git_server.add_repo("sub", add_to_manifest=False) git_server.add_submodule("top", url=sub_url, path=Path("sub")) run_git(workspace_path, "clone", top_url, "--recurse-submodules") git_server.push_file("sub", "new.txt") git_server.update_submodule("top", "sub") top_path = workspace_path / "top" run_git(top_path, "fetch") run_git(top_path, "reset", "--hard", "origin/master") run_git(top_path, "submodule", "update", "--init", "--recursive") new_sub = top_path / "sub" / "new.txt" assert new_sub.exists()
def test_status_happy( tsrc_cli: CLI, git_server: GitServer, workspace_path: Path, message_recorder: MessageRecorder, ) -> None: """Scenario: * Create a workspace with two clean repos in foo/bar and spam/eggs * Run `tsrc status` * Check that both paths are printed and properly aligned """ 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) run_git(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_push_to_other_branch(workspace_path: Path, git_server: GitServer) -> None: foo_url = git_server.add_repo("foo") git_server.push_file("foo", "devel.txt", contents="this is devel\n", branch="devel") run_git(workspace_path, "clone", foo_url, "--branch", "devel") foo_path = workspace_path / "foo" assert (foo_path / "devel.txt").read_text() == "this is devel\n"
def read_remote_manifest(workspace_path: Path, git_server: GitServer) -> Manifest: run_git(workspace_path, "clone", git_server.manifest_url) manifest_yml = workspace_path / "manifest/manifest.yml" manifest = load_manifest(manifest_yml) return manifest