Exemplo n.º 1
0
    def qimporthook(orig, ui, repo, *files, **opts):
        q = repo.mq

        # checks for an unused patch name. prompts if the patch already exists and
        # returns the corrected name.
        def checkpatchname(patch, current_filename=None):
            name = patch.name
            # For the first patch imported, the patch has already been temporarily saved
            # to disk by the time we reach here, with a filename that we cannot control
            # (eg 973703 for bz://973703). The patch is then renamed by us to the name of
            # the attachment in Bugzilla (unless patch_format has been overridden).
            # Unfortunately it's common for people to use the bug number as the filename of
            # the attachment, which would cause a name collision with this temporary file.
            # Patches other than the first will not have a current_filename.
            if name == current_filename:
                # Add a suffix to the patch filename to avoid a collision. This is preferable
                # to just skipping the check to see if the file exists, since if we leave the
                # filename as-is, subsequent qimports of the same bug will abort with an mq
                # "patch already exists" when it is unable to write its temporary file.
                ui.status("Changing patch filename to avoid conflict with temporary file.\n")
                name = "%s_" % name
            while os.path.exists(q.join(name)):
                msg = ("A file named '%s' already exists in your patch directory.\n"
                       "Rename %s '%s' (%d) (r)/overwrite (o)?" %
                       (name,
                        'patch' if isinstance(patch, bz.Patch) else 'attachment',
                        patch.desc,
                        int(patch.id)))
                if name in q.series and q.isapplied(name):
                    ui.write("A patch file named '%s' is already applied.\n")
                    choice = 'r'
                else:
                    choice = ui.prompt(msg, default="r")
                if choice == 'r':
                    name = ui.prompt("Enter the new patch name (old one was '%s'):" % name, default=name)
                else:
                    # overwrite
                    break
            if name in q.series and q.isapplied(name):
                ui.fatal("Patch with that name is already applied.")
            return name

        # hook for url.open which lets the user edit the returned patch name
        def previewopen(orig, ui, path):
            fp = orig(ui, path)

            class PreviewReader(object):
                def read(self):
                    return ui.edit(fp.read(), ui.username())

            return PreviewReader()

        # Install the preview hook if necessary. This will preview non-bz:// bugs
        # and that's OK.
        if opts['preview']:
            extensions.wrapfunction(url, "open", previewopen)

        # mercurial's url.search_re includes the // and that doesn't match what we
        # want which is bz:dddddd(/ddddd)?
        files = map(fixuppath, files)

        # Do the import as normal. The first patch of any bug is actually imported
        # and the rest are stored in the global delayed_imports. The imported
        # patches have dumb filenames because there's no way to tell mq to pick the
        # patch name *after* download.
        ret = orig(ui, repo, *files, **opts)
        if ret or bzhandler.last_imported_patch() is None:
            return ret

        # If the user passed a name, then mq used that so we don't need to rename
        if not opts['name']:
            # cache the lookup of the name. findcmd is not fast.
            qrename = cmdutil.findcmd("qrename", commands.table)[1][0]

            # Rename the already imported patch. If there are multiple patches, the
            # rest will be in bzhandler.delayed_imports, which we'll name correctly
            # in the first place.
            oldpatchname = q.fullseries[q.fullseriesend()]
            newpatchname = checkpatchname(bzhandler.last_imported_patch(), current_filename=oldpatchname)
            if newpatchname != oldpatchname:
                if newpatchname in q.series:
                    q.delete(repo, [newpatchname], {})
                qrename(ui, repo, oldpatchname, newpatchname)
                # mq always reports the original name, which is confusing so we'll
                # report the rename. But if ui.verbose is on, qrename will have already
                # reported it.
                if not ui.verbose:
                    ui.status("renamed %s -> %s\n" % (oldpatchname, newpatchname))

        # now process the delayed imports

        # these opts are invariant for all patches
        newopts = {}
        newopts.update(opts)
        newopts['force'] = True

        # loop through the Patches and import them by calculating their url. The
        # bz:// handler will have cached the lookup so we don't hit the network
        # here. Each one of these pushes an unapplied patch onto the beginning of
        # the queue, and unapplied patches are ignored when importing them, so do
        # these in reverse order.
        for patch in reversed(list(bzhandler.delayed_imports)):
            newopts['name'] = checkpatchname(patch)
            path = makebzurl(patch.bug.num, patch.id)

            ret = orig(ui, repo, path, **newopts)
            if ret:
                return ret
Exemplo n.º 2
0
  def qimporthook(orig, ui, repo, *files, **opts):
    q = repo.mq

    # checks for an unused patch name. prompts if the patch already exists and
    # returns the corrected name.
    def checkpatchname(patch):
      name = patch.name
      # Hg v1.4+: "ui.prompt is now a simple prompt and does not accept a list of choices. Use ui.promptchoice instead.".
      hasPromptchoice = hasattr(ui, 'promptchoice')
      while os.path.exists(q.join(name)):
        prompt = "A patch file named '%s' already exists in your patch directory. Rename %s '%s' (%d) (r)/overwrite (o)?" % \
                 (name,
                  'patch' if isinstance(patch, bz.Patch) else 'attachment',
                  patch.desc,
                  int(patch.id))
        if hasPromptchoice:
          choice = ui.promptchoice(prompt,
                                   ("&readonly", "&overwrite"),
                                   0)
          choice = ["r", "o"][choice]
        else:
          choice = ui.prompt(prompt,
                             ("&readonly", "&overwrite"),
                             "r")
        if choice == 'r':
          name = ui.prompt("Enter the new patch name (old one was '%s'):" % name)
        else: # overwrite
          break;
      if name in q.series and q.isapplied(name):
        ui.warn("Patch was already applied. Changes will not take effect until the patch is reapplied.")
      return name

    # hook for url.open which lets the user edit the returned 
    def previewopen(orig, ui, path):
      fp = orig(ui, path)

      class PreviewReader(object):
        def read(self):
          return ui.edit(fp.read(), ui.username())

      return PreviewReader()

    # Install the preview hook if necessary. This will preview non-bz:// bugs
    # and that's OK.
    if opts['preview']:
      extensions.wrapfunction(url, "open", previewopen)

    # mercurial's url.search_re includes the // and that doesn't match what we
    # want which is bz:dddddd(/ddddd)?
    files = map(fixuppath, files)

    # Do the import as normal. The first patch of any bug is actually imported
    # and the rest are stored in the global delayed_imports. The imported
    # patches have dumb filenames because there's no way to tell mq to pick the
    # patch name *after* download.
    ret = orig(ui, repo, *files, **opts)
    if ret or bzhandler.last_imported_patch() is None:
      return ret

    # If the user passed a name, then mq used that so we don't need to rename
    if not opts['name']:
      # cache the lookup of the name. findcmd is not fast.
      qrename = cmdutil.findcmd("qrename", commands.table)[1][0]

      # Rename the already imported patch. If there are multiple patches, the
      # rest will be in bzhandler.delayed_imports, which we'll name correctly
      # in the first place.
      try:
        # hg 1.9+
        oldpatchname = q.fullseries[q.fullseriesend()]
      except:
        oldpatchname = q.full_series[q.full_series_end()]
      newpatchname = checkpatchname(bzhandler.last_imported_patch())
      if newpatchname != oldpatchname:
        qrename(ui, repo, oldpatchname, newpatchname)
        # mq always reports the original name, which is confusing so we'll
        # report the rename. But if ui.verbose is on, qrename will have already
        # reported it.
        if not ui.verbose:
          ui.write("renamed %s -> %s\n" % (oldpatchname, newpatchname))

    # now process the delayed imports

    # these opts are invariant for all patches
    newopts = {}
    newopts.update(opts)
    newopts['force'] = True

    # loop through the Patches and import them by calculating their url. The
    # bz:// handler will have cached the lookup so we don't hit the network
    # here. Each one of these pushes an unapplied patch onto the beginning of
    # the queue, and unapplied patches are ignored when importing them, so do
    # these in reverse order.
    for patch in reversed(list(bzhandler.delayed_imports)):
      newopts['name'] = checkpatchname(patch)
      path = makebzurl(patch.bug.num, patch.id)

      ret = orig(ui, repo, path, **newopts)
      if ret:
        return ret
Exemplo n.º 3
0
    def qimporthook(orig, ui, repo, *files, **opts):
        q = repo.mq

        # checks for an unused patch name. prompts if the patch already exists and
        # returns the corrected name.
        def checkpatchname(patch, current_filename=None):
            name = patch.name
            # For the first patch imported, the patch has already been temporarily saved
            # to disk by the time we reach here, with a filename that we cannot control
            # (eg 973703 for bz://973703). The patch is then renamed by us to the name of
            # the attachment in Bugzilla (unless patch_format has been overridden).
            # Unfortunately it's common for people to use the bug number as the filename of
            # the attachment, which would cause a name collision with this temporary file.
            # Patches other than the first will not have a current_filename.
            if name == current_filename:
                # Add a suffix to the patch filename to avoid a collision. This is preferable
                # to just skipping the check to see if the file exists, since if we leave the
                # filename as-is, subsequent qimports of the same bug will abort with an mq
                # "patch already exists" when it is unable to write its temporary file.
                ui.status("Changing patch filename to avoid conflict with temporary file.\n")
                name = "%s_" % name
            while os.path.exists(q.join(name)):
                msg = (
                    "A file named '%s' already exists in your patch directory.\n"
                    "Rename %s '%s' (%d) (r)/overwrite (o)?"
                    % (name, "patch" if isinstance(patch, bz.Patch) else "attachment", patch.desc, int(patch.id))
                )
                if name in q.series and q.isapplied(name):
                    ui.write("A patch file named '%s' is already applied.\n")
                    choice = "r"
                else:
                    choice = ui.prompt(msg, default="r")
                if choice == "r":
                    name = ui.prompt("Enter the new patch name (old one was '%s'):" % name, default=name)
                else:
                    # overwrite
                    break
            if name in q.series and q.isapplied(name):
                ui.fatal("Patch with that name is already applied.")
            return name

        # hook for url.open which lets the user edit the returned patch name
        def previewopen(orig, ui, path):
            fp = orig(ui, path)

            class PreviewReader(object):
                def read(self):
                    return ui.edit(fp.read(), ui.username())

            return PreviewReader()

        # Install the preview hook if necessary. This will preview non-bz:// bugs
        # and that's OK.
        if opts["preview"]:
            extensions.wrapfunction(url, "open", previewopen)

        # mercurial's url.search_re includes the // and that doesn't match what we
        # want which is bz:dddddd(/ddddd)?
        files = map(fixuppath, files)

        # Do the import as normal. The first patch of any bug is actually imported
        # and the rest are stored in the global delayed_imports. The imported
        # patches have dumb filenames because there's no way to tell mq to pick the
        # patch name *after* download.
        ret = orig(ui, repo, *files, **opts)
        if ret or bzhandler.last_imported_patch() is None:
            return ret

        # If the user passed a name, then mq used that so we don't need to rename
        if not opts["name"]:
            # cache the lookup of the name. findcmd is not fast.
            qrename = cmdutil.findcmd("qrename", commands.table)[1][0]

            # Rename the already imported patch. If there are multiple patches, the
            # rest will be in bzhandler.delayed_imports, which we'll name correctly
            # in the first place.
            oldpatchname = q.fullseries[q.fullseriesend()]
            newpatchname = checkpatchname(bzhandler.last_imported_patch(), current_filename=oldpatchname)
            if newpatchname != oldpatchname:
                if newpatchname in q.series:
                    q.delete(repo, [newpatchname], {})
                qrename(ui, repo, oldpatchname, newpatchname)
                # mq always reports the original name, which is confusing so we'll
                # report the rename. But if ui.verbose is on, qrename will have already
                # reported it.
                if not ui.verbose:
                    ui.status("renamed %s -> %s\n" % (oldpatchname, newpatchname))

        # now process the delayed imports

        # these opts are invariant for all patches
        newopts = {}
        newopts.update(opts)
        newopts["force"] = True

        # loop through the Patches and import them by calculating their url. The
        # bz:// handler will have cached the lookup so we don't hit the network
        # here. Each one of these pushes an unapplied patch onto the beginning of
        # the queue, and unapplied patches are ignored when importing them, so do
        # these in reverse order.
        for patch in reversed(list(bzhandler.delayed_imports)):
            newopts["name"] = checkpatchname(patch)
            path = makebzurl(patch.bug.num, patch.id)

            ret = orig(ui, repo, path, **newopts)
            if ret:
                return ret