Пример #1
0
 def sync_repo_to_ref(repo_path: Path, ref: str) -> None:
     ui.info_2("Resetting to", ref)
     status = tsrc.git.get_status(repo_path)
     if status.dirty:
         raise tsrc.Error(f"{repo_path} is dirty, skipping")
     try:
         tsrc.git.run(repo_path, "reset", "--hard", ref)
     except tsrc.Error:
         raise tsrc.Error("updating ref failed")
Пример #2
0
 def sync_repo_to_ref(repo_path, ref):
     ui.info_2("Resetting to", ref)
     status = tsrc.git.get_status(repo_path)
     if status != "clean":
         raise tsrc.Error("%s, skipping" % status)
     try:
         tsrc.git.run_git(repo_path, "reset", "--hard", ref)
     except tsrc.Error:
         raise tsrc.Error("updating ref failed")
Пример #3
0
 def get_gitlab_url(self):
     manifest = self.load_manifest()
     gitlab_config = manifest.gitlab
     if not gitlab_config:
         raise tsrc.Error("No gitlab configuration found in manifest")
     res = gitlab_config.get("url")
     if not res:
         raise tsrc.Error("Missing 'url' in gitlab configuration")
     return res
Пример #4
0
def main(args: argparse.Namespace) -> None:
    path_as_str = args.workspace_path or os.getcwd()
    workspace_path = Path(path_as_str)
    cfg_path = workspace_path / ".tsrc" / "config.yml"

    if cfg_path.exists():
        raise tsrc.Error("Workspace already configured with file " + cfg_path)

    ui.info_1("Configuring workspace in", ui.bold, workspace_path)

    workspace_config = WorkspaceConfig(
        manifest_url=args.url,
        manifest_branch=args.branch,
        clone_all_repos=args.clone_all_repos,
        repo_groups=args.groups,
        shallow_clones=args.shallow,
    )

    workspace_config.save_to_file(cfg_path)

    workspace = Workspace(workspace_path)
    workspace.update_manifest()
    workspace.clone_missing()
    workspace.set_remotes()
    workspace.copy_files()
    ui.info_2("Workspace initialized")
    ui.info_2("Configuration written in", ui.bold, workspace.cfg_path)
Пример #5
0
def run(args: argparse.Namespace) -> None:
    workspace_path = args.workspace_path or Path.cwd()

    cfg_path = workspace_path / ".tsrc" / "config.yml"

    if cfg_path.exists():
        raise tsrc.Error(
            f"Workspace already configured. `{cfg_path}` already exists")

    ui.info_1("Configuring workspace in", ui.bold, workspace_path)

    workspace_config = WorkspaceConfig(
        manifest_url=args.manifest_url,
        manifest_branch=args.manifest_branch,
        clone_all_repos=args.clone_all_repos,
        repo_groups=args.groups or [],
        shallow_clones=args.shallow_clones,
        singular_remote=args.singular_remote,
    )

    workspace_config.save_to_file(cfg_path)

    workspace = Workspace(workspace_path)
    workspace.update_manifest()
    manifest = workspace.get_manifest()
    workspace.repos = repos_from_config(manifest, workspace_config)
    workspace.clone_missing()
    workspace.set_remotes()
    workspace.perform_filesystem_operations()
    ui.info_2("Workspace initialized")
    ui.info_2("Configuration written in", ui.bold, workspace.cfg_path)
Пример #6
0
Файл: log.py Проект: xzr/tsrc
def run(args: argparse.Namespace) -> None:
    workspace = get_workspace_with_repos(args)
    all_ok = True
    for repo in workspace.repos:
        full_path = workspace.root_path / repo.dest
        if not full_path.exists():
            ui.info(ui.bold,
                    repo.dest,
                    ": ",
                    ui.red,
                    "error: missing repo",
                    sep="")
            all_ok = False
            continue

        colors = ["green", "reset", "yellow", "reset", "bold blue", "reset"]
        log_format = "%m {}%h{} - {}%d{} %s {}<%an>{}"
        log_format = log_format.format(*("%C({})".format(x) for x in colors))
        cmd = [
            "log",
            "--color=always",
            f"--pretty=format:{log_format}",
            f"{args.from_ref}...{args.to_ref}",
        ]
        rc, out = tsrc.git.run_captured(full_path, *cmd, check=False)
        if rc != 0:
            all_ok = False
        if out:
            ui.info(ui.bold, repo.dest)
            ui.info(ui.bold, "-" * len(repo.dest))
            ui.info(out)
    if not all_ok:
        raise tsrc.Error()
Пример #7
0
 def process(self, index: int, count: int,
             item: tsrc.FileSystemOperation) -> None:
     ui.info_count(index, count, item)
     try:
         item.perform(self.workspace_path)
     except OSError as e:
         raise tsrc.Error(str(e))
Пример #8
0
    def clone_repo(self, repo: tsrc.Repo) -> None:
        """ Clone a missing repo.

        Note: must use the correct remote(s) and branch when cloning,
        *and* must reset the repo to the correct state if `tag` or
        `sha1` were set in the manifest configuration.
        """
        repo_path = self.workspace_path / repo.dest
        parent, name = repo_path.splitpath()
        parent.makedirs_p()
        remote = self._choose_remote(repo)
        remote_name = remote.name
        remote_url = remote.url
        clone_args = ["clone", "--origin", remote_name, remote_url]
        ref = None
        if repo.tag:
            ref = repo.tag
        elif repo.branch:
            ref = repo.branch
        if ref:
            clone_args.extend(["--branch", ref])
        if self.shallow:
            clone_args.extend(["--depth", "1"])
        clone_args.append(name)
        try:
            tsrc.git.run(parent, *clone_args)
        except tsrc.Error:
            raise tsrc.Error("Cloning failed")
Пример #9
0
 def load_manifest(self):
     manifest_yml_path = self.manifest_clone_path.joinpath("manifest.yml")
     if not manifest_yml_path.exists():
         message = "No manifest found in {}. Did you run `tsrc init` ?"
         raise tsrc.Error(message.format(manifest_yml_path))
     manifest = tsrc.manifest.Manifest()
     manifest.load(manifest_yml_path.text())
     return manifest
Пример #10
0
 def configure(self, url=None, branch="master", tag=None, groups=None):
     if not self.cfg_path.exists() and not url:
         raise tsrc.Error(
             "manifest URL is required when creating a new workspace")
     if self.cfg_path.exists() and not url:
         url = self.load_config()["url"]
     self._ensure_git_state(url, branch=branch, tag=tag)
     self.save_config(url=url, branch=branch, tag=tag, groups=groups)
Пример #11
0
 def process(self, repo):
     ui.info(repo.src)
     repo_path = self.workspace.joinpath(repo.src)
     parent, name = repo_path.splitpath()
     parent.makedirs_p()
     try:
         tsrc.git.run_git(parent, "clone", repo.url, "--branch",
                          repo.branch, name)
     except tsrc.Error:
         raise tsrc.Error("Cloning failed")
     ref = repo.fixed_ref
     if ref:
         ui.info_2("Resetting", repo.src, "to", ref)
         try:
             tsrc.git.run_git(repo_path, "reset", "--hard", ref)
         except tsrc.Error:
             raise tsrc.Error("Resetting to", ref, "failed")
Пример #12
0
 def check_shallow_with_sha1(self, repo: tsrc.Repo) -> None:
     if not repo.sha1:
         return
     if self.shallow:
         message = textwrap.dedent(
             f"Cannot use --shallow with a fixed sha1 ({repo.sha1})\n"
             "Consider using a tag instead")
         raise tsrc.Error(message)
Пример #13
0
    def check_branch(self, repo, repo_path):
        current_branch = None
        try:
            current_branch = tsrc.git.get_current_branch(repo_path)
        except tsrc.Error:
            raise tsrc.Error("Not on any branch")

        if current_branch and current_branch != repo.branch:
            self.bad_branches.append((repo.src, current_branch, repo.branch))
Пример #14
0
    def _pick_remotes(self, repo: tsrc.Repo) -> List[tsrc.Remote]:
        if self.remote_name:
            for remote in repo.remotes:
                if remote.name == self.remote_name:
                    return [remote]
            message = f"Remote {self.remote_name} not found for repository {repo.dest}"
            raise tsrc.Error(message)

        return repo.remotes
Пример #15
0
 def reset_repo(self, repo: tsrc.Repo) -> None:
     repo_path = self.workspace_path / repo.src
     ref = repo.sha1
     if ref:
         ui.info_2("Resetting", repo.src, "to", ref)
         try:
             tsrc.git.run(repo_path, "reset", "--hard", ref)
         except tsrc.Error:
             raise tsrc.Error("Resetting to", ref, "failed")
Пример #16
0
 def fetch(self, repo: tsrc.Repo) -> None:
     repo_path = self.workspace_path / repo.src
     for remote in repo.remotes:
         try:
             ui.info_2("Fetching", remote.name)
             tsrc.git.run(repo_path, "fetch", "--tags", "--prune",
                          remote.name)
         except tsrc.Error:
             raise tsrc.Error("fetch from %s failed" % remote.name)
Пример #17
0
 def load(self) -> None:
     config = self.load_config()
     if not config.file_path:
         yml_path = self.clone_path / "manifest.yml"
     else:
         yml_path = config.file_path
     if not yml_path.exists():
         message = "No manifest found in {}. Did you run `tsrc init` ?"
         raise tsrc.Error(message.format(yml_path))
     self.manifest = tsrc.manifest.load(yml_path)
Пример #18
0
 def update(self) -> None:
     ui.info_2("Updating manifest")
     if not self.clone_path.exists():
         message = "Could not find manifest in {}. "
         message += "Did you run `tsrc init` ?"
         raise tsrc.Error(message.format(self.clone_path))
     cmd = ("fetch", "--prune", "origin")
     tsrc.git.run(self.clone_path, *cmd)
     cmd = ("reset", "--hard", "@{upstream}")
     tsrc.git.run(self.clone_path, *cmd)
Пример #19
0
    def _choose_remote(self, repo: tsrc.Repo) -> tsrc.Remote:
        if self.remote_name:
            for remote in repo.remotes:
                if remote.name == self.remote_name:
                    return remote
            message = (
                f"Remote '{self.remote_name}' not found for repository '{repo.dest}'"
            )
            raise tsrc.Error(message)

        return repo.remotes[0]
Пример #20
0
 def fetch(self, repo: tsrc.Repo) -> None:
     repo_path = self.workspace_path / repo.dest
     for remote in self._pick_remotes(repo):
         try:
             ui.info_2("Fetching", remote.name)
             cmd = ["fetch", "--tags", "--prune", remote.name]
             if self.force:
                 cmd.append("--force")
             tsrc.git.run(repo_path, *cmd)
         except tsrc.Error:
             raise tsrc.Error(f"fetch from '{remote.name}' failed")
Пример #21
0
 def update_manifest(self):
     ui.info_2("Updating manifest")
     if not self.manifest_clone_path.exists():
         message = "Could not find manifest in {}. "
         message += "Did you run `tsrc init` ?"
         raise tsrc.Error(message.format(self.manifest_clone_path))
     cmd = ("fetch", "--prune", "origin")
     tsrc.git.run_git(self.manifest_clone_path, *cmd)
     cmd = ("reset", "--hard", "@{u}")
     tsrc.git.run_git(self.manifest_clone_path, *cmd)
     return self.load_manifest()
Пример #22
0
    def check_branch(self, repo: tsrc.Repo, repo_path: Path) -> None:
        current_branch = None
        try:
            current_branch = tsrc.git.get_current_branch(repo_path)
        except tsrc.Error:
            raise tsrc.Error("Not on any branch")

        # FIXME: is repo.branch allowed to be None ?
        if current_branch and current_branch != repo.branch:
            self.bad_branches.append(  # type: ignore
                (repo.src, current_branch, repo.branch))
Пример #23
0
    def check_branch(self, repo: tsrc.Repo, repo_path: Path) -> None:
        current_branch = None
        try:
            current_branch = tsrc.git.get_current_branch(repo_path)
        except tsrc.Error:
            raise tsrc.Error("Not on any branch")

        if current_branch and current_branch != repo.branch:
            self.bad_branches.append(
                RepoAtIncorrectBranchDescription(
                    dest=repo.dest, actual=current_branch, expected=repo.branch
                )
            )
Пример #24
0
 def find_merge_request(self) -> Optional[ProjectMergeRequest]:
     assert self.remote_branch
     assert self.project
     res = self.project.mergerequests.list(
         state="opened",
         source_branch=self.remote_branch,
         all=True
     )
     if len(res) >= 2:
         raise tsrc.Error("Found more than one opened merge request with the same branch")
     if not res:
         return None
     return res[0]
Пример #25
0
 def process(self, item):
     src, dest = item
     ui.info(src, "->", dest)
     try:
         src_path = self.workspace.joinpath(src)
         dest_path = self.workspace.joinpath(dest)
         if dest_path.exists():
             # Re-set the write permissions on the file:
             dest_path.chmod(stat.S_IWRITE)
         src_path.copy(dest_path)
         # Make sure perms are read only for everyone
         dest_path.chmod(0o10444)
     except Exception as e:
         raise tsrc.Error(str(e))
Пример #26
0
def find_workspace_path() -> Path:
    """ Look for a workspace root somewhere in the upper directories
    hierarchy

    """
    head = os.getcwd()
    tail = "a truthy string"
    while tail:
        tsrc_path = os.path.join(head, ".tsrc")
        if os.path.isdir(tsrc_path):
            return Path(head)

        else:
            head, tail = os.path.split(head)
    raise tsrc.Error("Could not find current workspace")
Пример #27
0
 def process(self, repo):
     full_path = self.workspace.joinpath(repo.src)
     try:
         _, old_url = tsrc.git.run_git(full_path,
                                       "remote",
                                       "get-url",
                                       "origin",
                                       raises=False)
         if old_url != repo.url:
             ui.info_2(repo.src, old_url, "->", repo.url)
             tsrc.git.run_git(full_path, "remote", "set-url", "origin",
                              repo.url)
     except Exception:
         raise tsrc.Error(repo.src, ":",
                          "Failed to set remote url to %s" % repo.url)
Пример #28
0
def find_workspace_path() -> Path:
    """
    Find the workspace path when not specified on the command line.
    """
    # Walk up the file system hierarchy until a `.tsrc` directory is found
    head = os.getcwd()
    tail = "a truthy string"
    while tail:
        tsrc_path = os.path.join(head, ".tsrc")
        if os.path.isdir(tsrc_path):
            return Path(head)

        else:
            head, tail = os.path.split(head)
    raise tsrc.Error("Could not find current workspace")
Пример #29
0
 def process(self, index: int, count: int, item: tsrc.Copy) -> None:
     known_sources = {x.src for x in self.repos}
     if item.repo not in known_sources:
         return
     ui.info_count(index, count, item.src, "->", item.dest)
     try:
         src_path = self.workspace_path / item.repo / item.src
         dest_path = self.workspace_path / item.dest
         if dest_path.exists():
             # Re-set the write permissions on the file:
             dest_path.chmod(stat.S_IWRITE)
         src_path.copy(dest_path)
         # Make sure perms are read only for everyone
         dest_path.chmod(0o10444)
     except Exception as e:
         raise tsrc.Error(str(e))
Пример #30
0
def find_workspace_path():
    """ Look for a workspace root somewhere in the upper directories
    hierarchy

    """
    head = os.getcwd()
    tail = True
    while tail:
        tsrc_path = os.path.join(head, ".tsrc")
        if os.path.isdir(tsrc_path):
            return path.Path(head)
        tbuild_yml_path = os.path.join(head, "tbuild.yml")
        if os.path.exists(tbuild_yml_path):
            return path.Path(head)

        else:
            head, tail = os.path.split(head)
    raise tsrc.Error("Could not find current workspace")