Patchwork [3,of,3] import: move tryone closure in cmdutil

login
register
mail settings
Submitter Pierre-Yves David
Date April 17, 2013, 8:57 a.m.
Message ID <f06a2231a66b162fecb5.1366189068@crater1.logilab.fr>
Download mbox | patch
Permalink /patch/1380/
State Superseded, archived
Commit ce3f3082ec45f26fc1a4d25c20f7d59a5700b5f7
Delegated to: Augie Fackler
Headers show

Comments

Pierre-Yves David - April 17, 2013, 8:57 a.m.
# HG changeset patch
# User Pierre-Yves David <pierre-yves.david@logilab.fr>
# Date 1366188688 -7200
#      Wed Apr 17 10:51:28 2013 +0200
# Node ID f06a2231a66b162fecb5a3a9a44db2d991dd79f7
# Parent  66fdcdc7cb399d62bb7bcc4115df3a79c89196e8
import: move tryone closure in cmdutil

We extract the `tryone` function into the `cmdutil` module. A lot fo the command
context have to be passed to the utility function, but having and explicit
declaration will allow extension to wrap it. This will allows use to make
changeset evolution related experiment in dedicated extension.
Augie Fackler - April 17, 2013, 1:56 p.m.
On Wed, Apr 17, 2013 at 10:57:48AM +0200, pierre-yves.david@logilab.fr wrote:
> # HG changeset patch
> # User Pierre-Yves David <pierre-yves.david@logilab.fr>
> # Date 1366188688 -7200
> #      Wed Apr 17 10:51:28 2013 +0200
> # Node ID f06a2231a66b162fecb5a3a9a44db2d991dd79f7
> # Parent  66fdcdc7cb399d62bb7bcc4115df3a79c89196e8
> import: move tryone closure in cmdutil
>

Queued first two of these (with English tweaks), need to meditate on this one more.

>
> We extract the `tryone` function into the `cmdutil` module. A lot fo the command
> context have to be passed to the utility function, but having and explicit
> declaration will allow extension to wrap it. This will allows use to make
> changeset evolution related experiment in dedicated extension.
>
> diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py
> --- a/mercurial/cmdutil.py
> +++ b/mercurial/cmdutil.py
> @@ -534,10 +534,125 @@ def service(opts, parentfn=None, initfn=
>              os.close(logfilefd)
>
>      if runfn:
>          return runfn()
>
> +def tryimportone(ui, repo, hunk, parents, opts, msgs, updatefunc):
> +    """Utility function used by commands.import to import a single patch
> +
> +    This function is explicitly defined here to help the evolve extension to
> +    wrap this part of the import logic.
> +    """
> +    editor = commiteditor
> +    if opts.get('edit'):
> +        editor = commitforceeditor
> +    update = not opts.get('bypass')
> +    strip = opts["strip"]
> +    sim = float(opts.get('similarity') or 0)
> +
> +    tmpname, message, user, date, branch, nodeid, p1, p2 = \
> +        patch.extract(ui, hunk)
> +
> +    if not tmpname:
> +        return (None, None)
> +    msg = _('applied to working directory')
> +
> +    try:
> +        cmdline_message = logmessage(ui, opts)
> +        if cmdline_message:
> +            # pickup the cmdline msg
> +            message = cmdline_message
> +        elif message:
> +            # pickup the patch msg
> +            message = message.strip()
> +        else:
> +            # launch the editor
> +            message = None
> +        ui.debug('message:\n%s\n' % message)
> +
> +        if len(parents) == 1:
> +            parents.append(repo[nullid])
> +        if opts.get('exact'):
> +            if not nodeid or not p1:
> +                raise util.Abort(_('not a Mercurial patch'))
> +            p1 = repo[p1]
> +            p2 = repo[p2 or nullid]
> +        elif p2:
> +            try:
> +                p1 = repo[p1]
> +                p2 = repo[p2]
> +                # Without any options, consider p2 only if the
> +                # patch is being applied on top of the recorded
> +                # first parent.
> +                if p1 != parents[0]:
> +                    p1 = parents[0]
> +                    p2 = repo[nullid]
> +            except error.RepoError:
> +                p1, p2 = parents
> +        else:
> +            p1, p2 = parents
> +
> +        n = None
> +        if update:
> +            if p1 != parents[0]:
> +                updatefunc(repo, p1.node())
> +            if p2 != parents[1]:
> +                repo.setparents(p1.node(), p2.node())
> +
> +            if opts.get('exact') or opts.get('import_branch'):
> +                repo.dirstate.setbranch(branch or 'default')
> +
> +            files = set()
> +            patch.patch(ui, repo, tmpname, strip=strip, files=files,
> +                        eolmode=None, similarity=sim / 100.0)
> +            files = list(files)
> +            if opts.get('no_commit'):
> +                if message:
> +                    msgs.append(message)
> +            else:
> +                if opts.get('exact') or p2:
> +                    # If you got here, you either use --force and know what
> +                    # you are doing or used --exact or a merge patch while
> +                    # being updated to its first parent.
> +                    m = None
> +                else:
> +                    m = scmutil.matchfiles(repo, files or [])
> +                n = repo.commit(message, opts.get('user') or user,
> +                                opts.get('date') or date, match=m,
> +                                editor=editor)
> +        else:
> +            if opts.get('exact') or opts.get('import_branch'):
> +                branch = branch or 'default'
> +            else:
> +                branch = p1.branch()
> +            store = patch.filestore()
> +            try:
> +                files = set()
> +                try:
> +                    patch.patchrepo(ui, repo, p1, store, tmpname, strip,
> +                                    files, eolmode=None)
> +                except patch.PatchError, e:
> +                    raise util.Abort(str(e))
> +                memctx = patch.makememctx(repo, (p1.node(), p2.node()),
> +                                          message,
> +                                          opts.get('user') or user,
> +                                          opts.get('date') or date,
> +                                          branch, files, store,
> +                                          editor=commiteditor)
> +                repo.savecommitmessage(memctx.description())
> +                n = memctx.commit()
> +            finally:
> +                store.close()
> +        if opts.get('exact') and hex(n) != nodeid:
> +            raise util.Abort(_('patch is damaged or loses information'))
> +        if n:
> +            # i18n: refers to a short changeset id
> +            msg = _('created %s') % short(n)
> +        return (msg, n)
> +    finally:
> +        os.unlink(tmpname)
> +
>  def export(repo, revs, template='hg-%h.patch', fp=None, switch_parent=False,
>             opts=None):
>      '''export changesets as hg patches.'''
>
>      total = len(revs)
> diff --git a/mercurial/commands.py b/mercurial/commands.py
> --- a/mercurial/commands.py
> +++ b/mercurial/commands.py
> @@ -3577,14 +3577,10 @@ def import_(ui, repo, patch1=None, *patc
>
>      date = opts.get('date')
>      if date:
>          opts['date'] = util.parsedate(date)
>
> -    editor = cmdutil.commiteditor
> -    if opts.get('edit'):
> -        editor = cmdutil.commitforceeditor
> -
>      update = not opts.get('bypass')
>      if not update and opts.get('no_commit'):
>          raise util.Abort(_('cannot use --no-commit with --bypass'))
>      try:
>          sim = float(opts.get('similarity') or 0)
> @@ -3597,117 +3593,13 @@ def import_(ui, repo, patch1=None, *patc
>
>      if (opts.get('exact') or not opts.get('force')) and update:
>          cmdutil.bailifchanged(repo)
>
>      base = opts["base"]
> -    strip = opts["strip"]
>      wlock = lock = tr = None
>      msgs = []
>
> -    def tryone(ui, hunk, parents):
> -        tmpname, message, user, date, branch, nodeid, p1, p2 = \
> -            patch.extract(ui, hunk)
> -
> -        if not tmpname:
> -            return (None, None)
> -        msg = _('applied to working directory')
> -
> -        try:
> -            cmdline_message = cmdutil.logmessage(ui, opts)
> -            if cmdline_message:
> -                # pickup the cmdline msg
> -                message = cmdline_message
> -            elif message:
> -                # pickup the patch msg
> -                message = message.strip()
> -            else:
> -                # launch the editor
> -                message = None
> -            ui.debug('message:\n%s\n' % message)
> -
> -            if len(parents) == 1:
> -                parents.append(repo[nullid])
> -            if opts.get('exact'):
> -                if not nodeid or not p1:
> -                    raise util.Abort(_('not a Mercurial patch'))
> -                p1 = repo[p1]
> -                p2 = repo[p2 or nullid]
> -            elif p2:
> -                try:
> -                    p1 = repo[p1]
> -                    p2 = repo[p2]
> -                    # Without any options, consider p2 only if the
> -                    # patch is being applied on top of the recorded
> -                    # first parent.
> -                    if p1 != parents[0]:
> -                        p1 = parents[0]
> -                        p2 = repo[nullid]
> -                except error.RepoError:
> -                    p1, p2 = parents
> -            else:
> -                p1, p2 = parents
> -
> -            n = None
> -            if update:
> -                if p1 != parents[0]:
> -                    hg.clean(repo, p1.node())
> -                if p2 != parents[1]:
> -                    repo.setparents(p1.node(), p2.node())
> -
> -                if opts.get('exact') or opts.get('import_branch'):
> -                    repo.dirstate.setbranch(branch or 'default')
> -
> -                files = set()
> -                patch.patch(ui, repo, tmpname, strip=strip, files=files,
> -                            eolmode=None, similarity=sim / 100.0)
> -                files = list(files)
> -                if opts.get('no_commit'):
> -                    if message:
> -                        msgs.append(message)
> -                else:
> -                    if opts.get('exact') or p2:
> -                        # If you got here, you either use --force and know what
> -                        # you are doing or used --exact or a merge patch while
> -                        # being updated to its first parent.
> -                        m = None
> -                    else:
> -                        m = scmutil.matchfiles(repo, files or [])
> -                    n = repo.commit(message, opts.get('user') or user,
> -                                    opts.get('date') or date, match=m,
> -                                    editor=editor)
> -            else:
> -                if opts.get('exact') or opts.get('import_branch'):
> -                    branch = branch or 'default'
> -                else:
> -                    branch = p1.branch()
> -                store = patch.filestore()
> -                try:
> -                    files = set()
> -                    try:
> -                        patch.patchrepo(ui, repo, p1, store, tmpname, strip,
> -                                        files, eolmode=None)
> -                    except patch.PatchError, e:
> -                        raise util.Abort(str(e))
> -                    memctx = patch.makememctx(repo, (p1.node(), p2.node()),
> -                                              message,
> -                                              opts.get('user') or user,
> -                                              opts.get('date') or date,
> -                                              branch, files, store,
> -                                              editor=cmdutil.commiteditor)
> -                    repo.savecommitmessage(memctx.description())
> -                    n = memctx.commit()
> -                finally:
> -                    store.close()
> -            if opts.get('exact') and hex(n) != nodeid:
> -                raise util.Abort(_('patch is damaged or loses information'))
> -            if n:
> -                # i18n: refers to a short changeset id
> -                msg = _('created %s') % short(n)
> -            return (msg, n)
> -        finally:
> -            os.unlink(tmpname)
> -
>      try:
>          try:
>              wlock = repo.wlock()
>              if not opts.get('no_commit'):
>                  lock = repo.lock()
> @@ -3723,11 +3615,12 @@ def import_(ui, repo, patch1=None, *patc
>                      ui.status(_('applying %s\n') % patchurl)
>                      patchfile = hg.openpath(ui, patchurl)
>
>                  haspatch = False
>                  for hunk in patch.split(patchfile):
> -                    (msg, node) = tryone(ui, hunk, parents)
> +                    (msg, node) = cmdutil.tryimportone(ui, repo, hunk, parents,
> +                                                       opts, msgs, hg.clean)
>                      if msg:
>                          haspatch = True
>                          ui.note(msg + '\n')
>                      if update or opts.get('exact'):
>                          parents = repo.parents()
> _______________________________________________
> Mercurial-devel mailing list
> Mercurial-devel@selenic.com
> http://selenic.com/mailman/listinfo/mercurial-devel
Augie Fackler - June 24, 2013, 7:56 p.m.
On Wed, Apr 17, 2013 at 09:56:33AM -0400, Augie Fackler wrote:
> On Wed, Apr 17, 2013 at 10:57:48AM +0200, pierre-yves.david@logilab.fr wrote:
> > # HG changeset patch
> > # User Pierre-Yves David <pierre-yves.david@logilab.fr>
> > # Date 1366188688 -7200
> > #      Wed Apr 17 10:51:28 2013 +0200
> > # Node ID f06a2231a66b162fecb5a3a9a44db2d991dd79f7
> > # Parent  66fdcdc7cb399d62bb7bcc4115df3a79c89196e8
> > import: move tryone closure in cmdutil
> >
>
> Queued first two of these (with English tweaks), need to meditate on this one more.

I'm going to just drop this for now, and figure you'll come back to
this in a bit when you resume work on evolve.

Patch

diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py
--- a/mercurial/cmdutil.py
+++ b/mercurial/cmdutil.py
@@ -534,10 +534,125 @@  def service(opts, parentfn=None, initfn=
             os.close(logfilefd)
 
     if runfn:
         return runfn()
 
+def tryimportone(ui, repo, hunk, parents, opts, msgs, updatefunc):
+    """Utility function used by commands.import to import a single patch
+
+    This function is explicitly defined here to help the evolve extension to
+    wrap this part of the import logic.
+    """
+    editor = commiteditor
+    if opts.get('edit'):
+        editor = commitforceeditor
+    update = not opts.get('bypass')
+    strip = opts["strip"]
+    sim = float(opts.get('similarity') or 0)
+
+    tmpname, message, user, date, branch, nodeid, p1, p2 = \
+        patch.extract(ui, hunk)
+
+    if not tmpname:
+        return (None, None)
+    msg = _('applied to working directory')
+
+    try:
+        cmdline_message = logmessage(ui, opts)
+        if cmdline_message:
+            # pickup the cmdline msg
+            message = cmdline_message
+        elif message:
+            # pickup the patch msg
+            message = message.strip()
+        else:
+            # launch the editor
+            message = None
+        ui.debug('message:\n%s\n' % message)
+
+        if len(parents) == 1:
+            parents.append(repo[nullid])
+        if opts.get('exact'):
+            if not nodeid or not p1:
+                raise util.Abort(_('not a Mercurial patch'))
+            p1 = repo[p1]
+            p2 = repo[p2 or nullid]
+        elif p2:
+            try:
+                p1 = repo[p1]
+                p2 = repo[p2]
+                # Without any options, consider p2 only if the
+                # patch is being applied on top of the recorded
+                # first parent.
+                if p1 != parents[0]:
+                    p1 = parents[0]
+                    p2 = repo[nullid]
+            except error.RepoError:
+                p1, p2 = parents
+        else:
+            p1, p2 = parents
+
+        n = None
+        if update:
+            if p1 != parents[0]:
+                updatefunc(repo, p1.node())
+            if p2 != parents[1]:
+                repo.setparents(p1.node(), p2.node())
+
+            if opts.get('exact') or opts.get('import_branch'):
+                repo.dirstate.setbranch(branch or 'default')
+
+            files = set()
+            patch.patch(ui, repo, tmpname, strip=strip, files=files,
+                        eolmode=None, similarity=sim / 100.0)
+            files = list(files)
+            if opts.get('no_commit'):
+                if message:
+                    msgs.append(message)
+            else:
+                if opts.get('exact') or p2:
+                    # If you got here, you either use --force and know what
+                    # you are doing or used --exact or a merge patch while
+                    # being updated to its first parent.
+                    m = None
+                else:
+                    m = scmutil.matchfiles(repo, files or [])
+                n = repo.commit(message, opts.get('user') or user,
+                                opts.get('date') or date, match=m,
+                                editor=editor)
+        else:
+            if opts.get('exact') or opts.get('import_branch'):
+                branch = branch or 'default'
+            else:
+                branch = p1.branch()
+            store = patch.filestore()
+            try:
+                files = set()
+                try:
+                    patch.patchrepo(ui, repo, p1, store, tmpname, strip,
+                                    files, eolmode=None)
+                except patch.PatchError, e:
+                    raise util.Abort(str(e))
+                memctx = patch.makememctx(repo, (p1.node(), p2.node()),
+                                          message,
+                                          opts.get('user') or user,
+                                          opts.get('date') or date,
+                                          branch, files, store,
+                                          editor=commiteditor)
+                repo.savecommitmessage(memctx.description())
+                n = memctx.commit()
+            finally:
+                store.close()
+        if opts.get('exact') and hex(n) != nodeid:
+            raise util.Abort(_('patch is damaged or loses information'))
+        if n:
+            # i18n: refers to a short changeset id
+            msg = _('created %s') % short(n)
+        return (msg, n)
+    finally:
+        os.unlink(tmpname)
+
 def export(repo, revs, template='hg-%h.patch', fp=None, switch_parent=False,
            opts=None):
     '''export changesets as hg patches.'''
 
     total = len(revs)
diff --git a/mercurial/commands.py b/mercurial/commands.py
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -3577,14 +3577,10 @@  def import_(ui, repo, patch1=None, *patc
 
     date = opts.get('date')
     if date:
         opts['date'] = util.parsedate(date)
 
-    editor = cmdutil.commiteditor
-    if opts.get('edit'):
-        editor = cmdutil.commitforceeditor
-
     update = not opts.get('bypass')
     if not update and opts.get('no_commit'):
         raise util.Abort(_('cannot use --no-commit with --bypass'))
     try:
         sim = float(opts.get('similarity') or 0)
@@ -3597,117 +3593,13 @@  def import_(ui, repo, patch1=None, *patc
 
     if (opts.get('exact') or not opts.get('force')) and update:
         cmdutil.bailifchanged(repo)
 
     base = opts["base"]
-    strip = opts["strip"]
     wlock = lock = tr = None
     msgs = []
 
-    def tryone(ui, hunk, parents):
-        tmpname, message, user, date, branch, nodeid, p1, p2 = \
-            patch.extract(ui, hunk)
-
-        if not tmpname:
-            return (None, None)
-        msg = _('applied to working directory')
-
-        try:
-            cmdline_message = cmdutil.logmessage(ui, opts)
-            if cmdline_message:
-                # pickup the cmdline msg
-                message = cmdline_message
-            elif message:
-                # pickup the patch msg
-                message = message.strip()
-            else:
-                # launch the editor
-                message = None
-            ui.debug('message:\n%s\n' % message)
-
-            if len(parents) == 1:
-                parents.append(repo[nullid])
-            if opts.get('exact'):
-                if not nodeid or not p1:
-                    raise util.Abort(_('not a Mercurial patch'))
-                p1 = repo[p1]
-                p2 = repo[p2 or nullid]
-            elif p2:
-                try:
-                    p1 = repo[p1]
-                    p2 = repo[p2]
-                    # Without any options, consider p2 only if the
-                    # patch is being applied on top of the recorded
-                    # first parent.
-                    if p1 != parents[0]:
-                        p1 = parents[0]
-                        p2 = repo[nullid]
-                except error.RepoError:
-                    p1, p2 = parents
-            else:
-                p1, p2 = parents
-
-            n = None
-            if update:
-                if p1 != parents[0]:
-                    hg.clean(repo, p1.node())
-                if p2 != parents[1]:
-                    repo.setparents(p1.node(), p2.node())
-
-                if opts.get('exact') or opts.get('import_branch'):
-                    repo.dirstate.setbranch(branch or 'default')
-
-                files = set()
-                patch.patch(ui, repo, tmpname, strip=strip, files=files,
-                            eolmode=None, similarity=sim / 100.0)
-                files = list(files)
-                if opts.get('no_commit'):
-                    if message:
-                        msgs.append(message)
-                else:
-                    if opts.get('exact') or p2:
-                        # If you got here, you either use --force and know what
-                        # you are doing or used --exact or a merge patch while
-                        # being updated to its first parent.
-                        m = None
-                    else:
-                        m = scmutil.matchfiles(repo, files or [])
-                    n = repo.commit(message, opts.get('user') or user,
-                                    opts.get('date') or date, match=m,
-                                    editor=editor)
-            else:
-                if opts.get('exact') or opts.get('import_branch'):
-                    branch = branch or 'default'
-                else:
-                    branch = p1.branch()
-                store = patch.filestore()
-                try:
-                    files = set()
-                    try:
-                        patch.patchrepo(ui, repo, p1, store, tmpname, strip,
-                                        files, eolmode=None)
-                    except patch.PatchError, e:
-                        raise util.Abort(str(e))
-                    memctx = patch.makememctx(repo, (p1.node(), p2.node()),
-                                              message,
-                                              opts.get('user') or user,
-                                              opts.get('date') or date,
-                                              branch, files, store,
-                                              editor=cmdutil.commiteditor)
-                    repo.savecommitmessage(memctx.description())
-                    n = memctx.commit()
-                finally:
-                    store.close()
-            if opts.get('exact') and hex(n) != nodeid:
-                raise util.Abort(_('patch is damaged or loses information'))
-            if n:
-                # i18n: refers to a short changeset id
-                msg = _('created %s') % short(n)
-            return (msg, n)
-        finally:
-            os.unlink(tmpname)
-
     try:
         try:
             wlock = repo.wlock()
             if not opts.get('no_commit'):
                 lock = repo.lock()
@@ -3723,11 +3615,12 @@  def import_(ui, repo, patch1=None, *patc
                     ui.status(_('applying %s\n') % patchurl)
                     patchfile = hg.openpath(ui, patchurl)
 
                 haspatch = False
                 for hunk in patch.split(patchfile):
-                    (msg, node) = tryone(ui, hunk, parents)
+                    (msg, node) = cmdutil.tryimportone(ui, repo, hunk, parents,
+                                                       opts, msgs, hg.clean)
                     if msg:
                         haspatch = True
                         ui.note(msg + '\n')
                     if update or opts.get('exact'):
                         parents = repo.parents()