Пример #1
0
def test_CloneRepo_valid_repo(tempdir: pathlib.Path, shallow: bool):
  github = api.GetDefaultGithubConnectionOrDie()
  repo = github.get_repo("ChrisCummins/empty_repository_for_testing")
  clone_path = tempdir / "repo"

  # Note forced https because test runner may not have access to SSH
  # keys in ~/.ssh.
  assert (
    api.CloneRepo(repo, tempdir / "repo", shallow=shallow, force_https=True)
    == clone_path
  )
  assert (clone_path / "HelloWorld.java").is_file()
Пример #2
0
def Export(
  workspace_root: pathlib.Path,
  github_repo: str,
  targets: List[str],
  excluded_targets: List[str] = None,
  extra_files: List[str] = None,
  move_file_mapping: Dict[str, str] = None,
) -> None:
  """Custom entry-point to export source-tree.

  This should be called from a bare python script, before flags parsing.

  Args:
    workspace_root: The root path of the bazel workspace.
    github_repo: The name of the GitHub repo to export to.
    targets: A list of bazel targets to export. These targets, and their
      dependencies, will be exported. These arguments are passed unmodified to
      bazel query, so `/...` and `:all` labels are expanded, e.g.
      `//some/package/to/export/...`. All targets should be absolute, and
      prefixed with '//'.
    excluded_targets: A list of targets to exlude.
    extra_files: A list of additional files to export.
    move_file_mapping: A dictionary of <src,dst> relative paths listing files
      which should be moved from their respective source location to the
      destination.
  """
  excluded_targets = excluded_targets or []
  extra_files = extra_files or []
  move_file_mapping = move_file_mapping or {}

  source_workspace = phd_workspace.PhdWorkspace(workspace_root)

  with tempfile.TemporaryDirectory(prefix=f"phd_export_{github_repo}_") as d:
    destination = pathlib.Path(d)
    connection = api.GetDefaultGithubConnectionOrDie(
      extra_access_token_paths=[
        "~/.github/access_tokens/export_source_tree.txt"
      ]
    )
    repo = GetOrCreateRepoOrDie(connection, github_repo)
    api.CloneRepo(repo, destination)
    destination_repo = git.Repo(destination)

    src_files = source_workspace.GetAllSourceTreeFiles(
      targets, excluded_targets, extra_files, move_file_mapping
    )
    if FLAGS.export_source_tree_print_files:
      print("\n".join(str(x) for x in src_files))
      sys.exit(0)

    exported_commit_count = source_workspace.ExportToRepo(
      repo=destination_repo,
      targets=targets,
      src_files=src_files,
      extra_files=extra_files,
      file_move_mapping=move_file_mapping,
    )
    if not exported_commit_count:
      return
    app.Log(1, "Pushing changes to remote")

    # Force push since we may have rewritten history.
    destination_repo.git.push("origin", force=True)
Пример #3
0
def test_CloneRepo_invalid_repo_not_found(tempdir: pathlib.Path, shallow: bool):
  github = api.GetDefaultGithubConnectionOrDie()
  repo = github.get_repo("ChrisCummins/not_a_real_repo")

  with test.Raises(FileNotFoundError):
    api.CloneRepo(repo, tempdir, shallow=shallow)
Пример #4
0
def main():
    if not FLAGS.user:
        raise app.UsageError("--user not set")

    try:
        g = api.GetDefaultGithubConnectionOrDie(extra_access_token_paths=[
            "~/.github/access_tokens/gh_archiver.txt"
        ])

        # AuthenticatedUser provides access to private repos
        user: Union[NamedUser, AuthenticatedUser] = g.get_user(FLAGS.user)

        repos = list(get_repos(user))

        FLAGS.outdir.mkdir(exist_ok=True, parents=True)

        if FLAGS.delete:
            # Delete any directories which are not Github repos.
            repo_names = [r.name for r in repos]

            for path in FLAGS.outdir.iterdir():
                if not path.is_dir():
                    continue
                local_repo_name = os.path.basename(path)

                if local_repo_name not in repo_names:
                    print(f"removing {local_repo_name}")
                    if path.is_dir():
                        shutil.rmtree(path)
                    else:
                        os.remove(path)

        errors = False
        for repo in repos:
            local_path = FLAGS.outdir / repo.name

            # remove any file of the same name
            if local_path.exists() and not local_path.is_dir():
                os.remove(local_path)

            # Local clone
            if local_path.is_dir():
                print(f"updating {repo.name}")
            else:
                print(f"cloning {repo.name}:{repo.default_branch}")
                try:
                    api.CloneRepo(repo, local_path)
                except git_clone.RepoCloneFailed as e:
                    errors = True
                    print(f"ERROR: {local_path} {type(e).__name__}",
                          file=sys.stderr)

            try:
                local_repo = Repo(local_path)
                for remote in local_repo.remotes:
                    remote.fetch()
                for submodule in local_repo.submodules:
                    submodule.update(init=True)
            except Exception as e:
                errors = True
                print(f"ERROR: {local_path} {type(e).__name__}",
                      file=sys.stderr)

        return sys.exit(1 if errors else 0)
    except KeyboardInterrupt:
        print()
        sys.exit(1)