コード例 #1
0
    def push_derived(
        self,
        name: str,
        hoster: Optional[Hoster] = None,
        overwrite_existing: Optional[bool] = False,
        owner: Optional[str] = None,
        tags: Optional[Union[Dict[str, bytes], List[str]]] = None,
        stop_revision: Optional[bytes] = None,
    ) -> Tuple[Branch, str]:
        """Push a derived branch.

        Args:
          name: Branch name
          hoster: Optional hoster to use
          overwrite_existing: Whether to overwrite an existing branch
          tags: Tags list to push
          owner: Owner name
        Returns:
          tuple with remote_branch and public_branch_url
        """
        if hoster is None:
            hoster = get_hoster(self.main_branch)
        return push_derived_changes(
            self.local_tree.branch,
            self.main_branch,
            hoster,
            name,
            overwrite_existing=overwrite_existing,
            owner=owner,
            tags=tags,
            stop_revision=stop_revision,
        )
コード例 #2
0
 def push(
     self,
     hoster: Optional[Hoster] = None,
     dry_run: bool = False,
     tags: Optional[Union[Dict[str, bytes], List[str]]] = None,
     stop_revision: Optional[bytes] = None,
 ) -> None:
     if hoster is None:
         try:
             hoster = get_hoster(self.main_branch)
         except UnsupportedHoster:
             if isinstance(self.main_branch.control_transport,
                           LocalTransport):
                 hoster = None
             else:
                 raise
     return push_changes(
         self.local_tree.branch,
         self.main_branch,
         hoster=hoster,
         additional_colocated_branches=self.additional_colocated_branches,
         dry_run=dry_run,
         tags=tags,
         stop_revision=stop_revision,
     )
コード例 #3
0
ファイル: workspace.py プロジェクト: jelmer/silver-platter
 def push(
     self,
     hoster: Optional[Hoster] = None,
     dry_run: bool = False,
     tags: Optional[Union[Dict[str, bytes], List[str]]] = None,
     stop_revision: Optional[bytes] = None,
 ) -> None:
     if hoster is None:
         try:
             hoster = get_hoster(self.main_branch)
         except UnsupportedHoster:
             if not isinstance(self.main_branch.control_transport, LocalTransport):
                 logging.warning(
                     'Unable to find hoster for %s to determine push url, '
                     'trying anyway.', self.main_branch.user_url)
             hoster = None
     return push_changes(
         self.local_tree.branch,
         self.main_branch,
         hoster=hoster,
         additional_colocated_branches=self._inverse_additional_colocated_branches(),
         dry_run=dry_run,
         tags=tags,
         stop_revision=stop_revision,
     )
コード例 #4
0
def push_to_salsa(local_tree, orig_branch, user, name, dry_run=False):
    from breezy import urlutils
    from breezy.branch import Branch
    from breezy.errors import PermissionDenied
    from breezy.propose import UnsupportedHoster, get_hoster, HosterLoginRequired
    from breezy.plugins.gitlab.hoster import GitLab

    if dry_run:
        logging.info("Creating and pushing to salsa project %s/%s", user, name)
        return

    try:
        salsa = GitLab.probe_from_url("https://salsa.debian.org/")
    except HosterLoginRequired:
        logging.warning("No login for salsa known, not pushing branch.")
        return

    try:
        orig_hoster = get_hoster(orig_branch)
    except UnsupportedHoster:
        logging.debug("Original branch %r not hosted on salsa.")
        from_project = None
    else:
        if orig_hoster == salsa:
            from_project = urlutils.from_string(
                orig_branch.controldir.user_url).path
        else:
            from_project = None

    if from_project is not None:
        salsa.fork_project(from_project, owner=user)
    else:
        try:
            salsa.create_project("%s/%s" % (user, name))
        except PermissionDenied as e:
            logging.info('No permission to create new project under %s: %s',
                         user, e)
            return
    target_branch = Branch.open("git+ssh://[email protected]/%s/%s.git" %
                                (user, name))
    additional_colocated_branches = pick_additional_colocated_branches(
        local_tree.branch)
    return push_changes(
        local_tree.branch,
        target_branch,
        hoster=salsa,
        additional_colocated_branches=additional_colocated_branches,
        dry_run=dry_run,
    )
コード例 #5
0
 def propose(
     self,
     name: str,
     description: str,
     hoster: Optional[Hoster] = None,
     existing_proposal: Optional[MergeProposal] = None,
     overwrite_existing: Optional[bool] = None,
     labels: Optional[List[str]] = None,
     dry_run: bool = False,
     commit_message: Optional[str] = None,
     reviewers: Optional[List[str]] = None,
     tags: Optional[Union[Dict[str, bytes], List[str]]] = None,
     owner: Optional[str] = None,
     allow_collaboration: bool = False,
     stop_revision: Optional[bytes] = None,
 ) -> MergeProposal:
     if hoster is None:
         hoster = get_hoster(self.main_branch)
     return propose_changes(
         self.local_tree.branch,
         self.main_branch,
         hoster=hoster,
         name=name,
         mp_description=description,
         resume_branch=self.resume_branch,
         resume_proposal=existing_proposal,
         overwrite_existing=(overwrite_existing or False),
         labels=labels,
         dry_run=dry_run,
         commit_message=commit_message,
         reviewers=reviewers,
         owner=owner,
         additional_colocated_branches=self.additional_colocated_branches,
         tags=tags,
         allow_collaboration=allow_collaboration,
         stop_revision=stop_revision,
     )
コード例 #6
0
def publish_changes(
    local_branch: Branch,
    main_branch: Branch,
    resume_branch: Optional[Branch],
    mode: str,
    name: str,
    get_proposal_description: Callable[[str, Optional[MergeProposal]], str],
    get_proposal_commit_message: Callable[
        [Optional[MergeProposal]], Optional[str]
    ] = None,
    dry_run: bool = False,
    hoster: Optional[Hoster] = None,
    allow_create_proposal: bool = True,
    labels: Optional[List[str]] = None,
    overwrite_existing: Optional[bool] = True,
    existing_proposal: Optional[MergeProposal] = None,
    reviewers: Optional[List[str]] = None,
    tags: Optional[Union[List[str], Dict[str, bytes]]] = None,
    derived_owner: Optional[str] = None,
    allow_collaboration: bool = False,
    stop_revision: Optional[bytes] = None,
) -> PublishResult:
    """Publish a set of changes.

    Args:
      ws: Workspace to push from
      mode: Mode to use ('push', 'push-derived', 'propose')
      name: Branch name to push
      get_proposal_description: Function to retrieve proposal description
      get_proposal_commit_message: Function to retrieve proposal commit message
      dry_run: Whether to dry run
      hoster: Hoster, if known
      allow_create_proposal: Whether to allow creating proposals
      labels: Labels to set for any merge proposals
      overwrite_existing: Whether to overwrite existing (but unrelated) branch
      existing_proposal: Existing proposal to update
      reviewers: List of reviewers for merge proposal
      tags: Tags to push (None for default behaviour)
      derived_owner: Name of any derived branch
      allow_collaboration: Whether to allow target branch owners to modify
        source branch.
    """
    if mode not in SUPPORTED_MODES:
        raise ValueError("invalid mode %r" % mode)

    if stop_revision is None:
        stop_revision = local_branch.last_revision()

    if stop_revision == main_branch.last_revision():
        if existing_proposal is not None:
            logging.info("closing existing merge proposal - no new revisions")
            existing_proposal.close()
        return PublishResult(mode)

    if resume_branch and resume_branch.last_revision() == stop_revision:
        # No new revisions added on this iteration, but changes since main
        # branch. We may not have gotten round to updating/creating the
        # merge proposal last time.
        logging.info("No changes added; making sure merge proposal is up to date.")

    if hoster is None:
        hoster = get_hoster(main_branch)

    if mode == MODE_PUSH_DERIVED:
        (remote_branch, public_url) = push_derived_changes(
            local_branch,
            main_branch,
            hoster=hoster,
            name=name,
            overwrite_existing=overwrite_existing,
            tags=tags,
            owner=derived_owner,
            stop_revision=stop_revision,
        )
        return PublishResult(mode)

    if mode in (MODE_PUSH, MODE_ATTEMPT_PUSH):
        try:
            # breezy would do this check too, but we want to be *really* sure.
            with local_branch.lock_read():
                graph = local_branch.repository.get_graph()
                if not graph.is_ancestor(main_branch.last_revision(), stop_revision):
                    raise errors.DivergedBranches(main_branch, local_branch)
            push_changes(
                local_branch,
                main_branch,
                hoster=hoster,
                dry_run=dry_run,
                tags=tags,
                stop_revision=stop_revision,
            )
        except errors.PermissionDenied:
            if mode == MODE_ATTEMPT_PUSH:
                logging.info("push access denied, falling back to propose")
                mode = MODE_PROPOSE
            else:
                logging.info("permission denied during push")
                raise
        else:
            return PublishResult(mode=mode)

    assert mode == "propose"
    if not resume_branch and not allow_create_proposal:
        raise InsufficientChangesForNewProposal()

    mp_description = get_proposal_description(
        getattr(hoster, "merge_proposal_description_format", "plain"),
        existing_proposal if resume_branch else None,
    )
    if get_proposal_commit_message is not None:
        commit_message = get_proposal_commit_message(
            existing_proposal if resume_branch else None
        )
    (proposal, is_new) = propose_changes(
        local_branch,
        main_branch,
        hoster=hoster,
        name=name,
        mp_description=mp_description,
        resume_branch=resume_branch,
        resume_proposal=existing_proposal,
        overwrite_existing=overwrite_existing,
        labels=labels,
        dry_run=dry_run,
        commit_message=commit_message,
        reviewers=reviewers,
        tags=tags,
        owner=derived_owner,
        allow_collaboration=allow_collaboration,
        stop_revision=stop_revision,
    )
    return PublishResult(mode, proposal, is_new)