merge with upstream
authorThomas Arendsen Hein <thomas@intevation.de>
Fri, 28 Jul 2006 09:00:59 +0200
changeset 2715 79c31b6b9c83
parent 2713 85070b784896 (diff)
parent 2714 146fef06e188 (current diff)
child 2717 14ebe97542a7
merge with upstream
tests/test-mq-qrefresh-replace-log-message
--- a/hgext/mq.py
+++ b/hgext/mq.py
@@ -187,8 +187,7 @@ class queue:
             return (err, n)
 
         if n is None:
-            self.ui.warn("apply failed for patch %s\n" % patch)
-            sys.exit(1)
+            raise util.Abort(_("apply failed for patch %s") % patch)
 
         self.ui.warn("patch didn't work out, merging %s\n" % patch)
 
@@ -199,17 +198,14 @@ class queue:
         c = repo.changelog.read(rev)
         ret = repo.update(rev, allow=True, wlock=wlock)
         if ret:
-            self.ui.warn("update returned %d\n" % ret)
-            sys.exit(1)
+            raise util.Abort(_("update returned %d") % ret)
         n = repo.commit(None, c[4], c[1], force=1, wlock=wlock)
         if n == None:
-            self.ui.warn("repo commit failed\n")
-            sys.exit(1)
+            raise util.Abort(_("repo commit failed"))
         try:
             message, comments, user, date, patchfound = mergeq.readheaders(patch)
         except:
-            self.ui.warn("Unable to read %s\n" % patch)
-            sys.exit(1)
+            raise util.Abort(_("unable to read %s") % patch)
 
         patchf = self.opener(patch, "w")
         if comments:
@@ -280,8 +276,6 @@ class queue:
         # TODO unify with commands.py
         if not patchdir:
             patchdir = self.path
-        pwd = os.getcwd()
-        os.chdir(repo.root)
         err = 0
         if not wlock:
             wlock = repo.wlock()
@@ -308,7 +302,8 @@ class queue:
 
             try:
                 pp = util.find_in_path('gpatch', os.environ.get('PATH', ''), 'patch')
-                f = os.popen("%s -p1 --no-backup-if-mismatch < '%s'" % (pp, pf))
+                f = os.popen("%s -d '%s' -p1 --no-backup-if-mismatch < '%s'" %
+                             (pp, repo.root, pf))
             except:
                 self.ui.warn("patch failed, unable to continue (try -v)\n")
                 err = 1
@@ -356,8 +351,7 @@ class queue:
                             wlock=wlock)
 
             if n == None:
-                self.ui.warn("repo commit failed\n")
-                sys.exit(1)
+                raise util.Abort(_("repo commit failed"))
 
             if update_status:
                 self.applied.append(revlog.hex(n) + ":" + patch)
@@ -376,18 +370,15 @@ class queue:
                 err = 1
                 break
         tr.close()
-        os.chdir(pwd)
         return (err, n)
 
     def delete(self, repo, patch):
         patch = self.lookup(patch, strict=True)
         info = self.isapplied(patch)
         if info:
-            self.ui.warn("cannot delete applied patch %s\n" % patch)
-            sys.exit(1)
+            raise util.Abort(_("cannot delete applied patch %s") % patch)
         if patch not in self.series:
-            self.ui.warn("patch %s not in series file\n" % patch)
-            sys.exit(1)
+            raise util.Abort(_("patch %s not in series file") % patch)
         i = self.find_series(patch)
         del self.full_series[i]
         self.read_series(self.full_series)
@@ -399,23 +390,22 @@ class queue:
             top = revlog.bin(top)
             pp = repo.dirstate.parents()
             if top not in pp:
-                self.ui.warn("queue top not at dirstate parents. top %s dirstate %s %s\n" %( revlog.short(top), revlog.short(pp[0]), revlog.short(pp[1])))
-                sys.exit(1)
+                raise util.Abort(_("queue top not at same revision as working directory"))
             return top
         return None
     def check_localchanges(self, repo):
         (c, a, r, d, u) = repo.changes(None, None)
         if c or a or d or r:
-            self.ui.write("Local changes found, refresh first\n")
-            sys.exit(1)
+            raise util.Abort(_("local changes found, refresh first"))
     def new(self, repo, patch, msg=None, force=None):
+        if os.path.exists(os.path.join(self.path, patch)):
+            raise util.Abort(_('patch "%s" already exists') % patch)
         commitfiles = []
         (c, a, r, d, u) = repo.changes(None, None)
         if c or a or d or r:
             if not force:
-                raise util.Abort(_("Local changes found, refresh first"))
-            else:
-                commitfiles = c + a + r
+                raise util.Abort(_("local changes found, refresh first"))
+            commitfiles = c + a + r
         self.check_toppatch(repo)
         wlock = repo.wlock()
         insert = self.full_series_end()
@@ -426,8 +416,7 @@ class queue:
             n = repo.commit(commitfiles,
                             "New patch: %s" % patch, force=True, wlock=wlock)
         if n == None:
-            self.ui.warn("repo commit failed\n")
-            sys.exit(1)
+            raise util.Abort(_("repo commit failed"))
         self.full_series[insert:insert] = [patch]
         self.applied.append(revlog.hex(n) + ":" + patch)
         self.read_series(self.full_series)
@@ -532,7 +521,7 @@ class queue:
         if update:
             (c, a, r, d, u) = repo.changes(None, None)
             if c or a or d or r:
-                raise util.Abort(_("Local changes found"))
+                raise util.Abort(_("local changes found"))
             urev = self.qparents(repo, rev)
             repo.update(urev, allow=False, force=True, wlock=wlock)
             repo.dirstate.write()
@@ -672,8 +661,7 @@ class queue:
                         else:
                             if i + off < len(self.series):
                                 return self.series[i + off]
-        self.ui.warn("patch %s not in series\n" % patch)
-        sys.exit(1)
+        raise util.Abort(_("patch %s not in series") % patch)
 
     def push(self, repo, patch=None, force=False, list=False,
              mergeq=None, wlock=None):
@@ -681,10 +669,10 @@ class queue:
             wlock = repo.wlock()
         patch = self.lookup(patch)
         if patch and self.isapplied(patch):
-            self.ui.warn("patch %s is already applied\n" % patch)
+            self.ui.warn(_("patch %s is already applied\n") % patch)
             sys.exit(1)
         if self.series_end() == len(self.series):
-            self.ui.warn("File series fully applied\n")
+            self.ui.warn(_("patch series fully applied\n"))
             sys.exit(1)
         if not force:
             self.check_localchanges(repo)
@@ -733,10 +721,9 @@ class queue:
                 patch = self.lookup(patch)
             info = self.isapplied(patch)
             if not info:
-                self.ui.warn("patch %s is not applied\n" % patch)
-                sys.exit(1)
+                raise util.Abort(_("patch %s is not applied") % patch)
         if len(self.applied) == 0:
-            self.ui.warn("No patches applied\n")
+            self.ui.warn(_("no patches applied\n"))
             sys.exit(1)
 
         if not update:
@@ -910,15 +897,14 @@ class queue:
 
     def init(self, repo, create=False):
         if os.path.isdir(self.path):
-            raise util.Abort("patch queue directory already exists")
+            raise util.Abort(_("patch queue directory already exists"))
         os.mkdir(self.path)
         if create:
             return self.qrepo(create=True)
 
     def unapplied(self, repo, patch=None):
         if patch and patch not in self.series:
-            self.ui.warn("%s not in the series file\n" % patch)
-            sys.exit(1)
+            raise util.Abort(_("patch %s is not in series file") % patch)
         if not patch:
             start = self.series_end()
         else:
@@ -1070,8 +1056,7 @@ class queue:
 
     def qapplied(self, repo, patch=None):
         if patch and patch not in self.series:
-            self.ui.warn("%s not in the series file\n" % patch)
-            sys.exit(1)
+            raise util.Abort(_("patch %s is not in series file") % patch)
         if not patch:
             end = len(self.applied)
         else:
@@ -1117,8 +1102,8 @@ class queue:
 
     def qimport(self, repo, files, patch=None, existing=None, force=None):
         if len(files) > 1 and patch:
-            self.ui.warn("-n option not valid when importing multiple files\n")
-            sys.exit(1)
+            raise util.Abort(_('option "-n" not valid when importing multiple '
+                               'files'))
         i = 0
         added = []
         for filename in files:
@@ -1126,24 +1111,21 @@ class queue:
                 if not patch:
                     patch = filename
                 if not os.path.isfile(os.path.join(self.path, patch)):
-                    self.ui.warn("patch %s does not exist\n" % patch)
-                    sys.exit(1)
+                    raise util.Abort(_("patch %s does not exist") % patch)
             else:
                 try:
                     text = file(filename).read()
                 except IOError:
-                    self.ui.warn("Unable to read %s\n" % patch)
-                    sys.exit(1)
+                    raise util.Abort(_("unable to read %s") % patch)
                 if not patch:
                     patch = os.path.split(filename)[1]
-                if not force and os.path.isfile(os.path.join(self.path, patch)):
-                    self.ui.warn("patch %s already exists\n" % patch)
-                    sys.exit(1)
+                if not force and os.path.exists(os.path.join(self.path, patch)):
+                    raise util.Abort(_('patch "%s" already exists') % patch)
                 patchf = self.opener(patch, "w")
                 patchf.write(text)
             if patch in self.series:
-                self.ui.warn("patch %s is already in the series file\n" % patch)
-                sys.exit(1)
+                raise util.Abort(_('patch %s is already in the series file')
+                                 % patch)
             index = self.full_series_end() + i
             self.full_series[index:index] = [patch]
             self.read_series(self.full_series)
@@ -1326,13 +1308,11 @@ def save(ui, repo, **opts):
             newpath = os.path.join(q.basepath, opts['name'])
             if os.path.exists(newpath):
                 if not os.path.isdir(newpath):
-                    ui.warn("destination %s exists and is not a directory\n" %
-                            newpath)
-                    sys.exit(1)
+                    raise util.Abort(_('destination %s exists and is not '
+                                       'a directory') % newpath)
                 if not opts['force']:
-                    ui.warn("destination %s exists, use -f to force\n" %
-                            newpath)
-                    sys.exit(1)
+                    raise util.Abort(_('destination %s exists, '
+                                       'use -f to force') % newpath)
         else:
             newpath = savename(path)
         ui.warn("copy %s to %s\n" % (path, newpath))
--- a/hgext/patchbomb.py
+++ b/hgext/patchbomb.py
@@ -45,6 +45,7 @@ demandload(globals(), '''email.MIMEMulti
                          mercurial:commands,hg,ui
                          os errno popen2 socket sys tempfile time''')
 from mercurial.i18n import gettext as _
+from mercurial.node import *
 
 try:
     # readline gives raw_input editing capabilities, but is not
@@ -130,8 +131,26 @@ def patchbomb(ui, repo, *revs, **opts):
             while patch and not patch[0].strip(): patch.pop(0)
         if opts['diffstat']:
             body += cdiffstat('\n'.join(desc), patch) + '\n\n'
-        body += '\n'.join(patch)
-        msg = email.MIMEText.MIMEText(body)
+        if opts['attach']:
+            msg = email.MIMEMultipart.MIMEMultipart()
+            if body: msg.attach(email.MIMEText.MIMEText(body, 'plain'))
+            p = email.MIMEText.MIMEText('\n'.join(patch), 'x-patch')
+            node = bin(node)
+            # if node is mq patch, it will have patch file name as tag
+            patchname = [t for t in repo.nodetags(node)
+                         if t.endswith('.patch') or t.endswith('.diff')]
+            if patchname:
+                patchname = patchname[0]
+            elif total > 1:
+                patchname = commands.make_filename(repo, '%b-%n.patch',
+                                                   node, idx, total)
+            else:
+                patchname = commands.make_filename(repo, '%b.patch', node)
+            p['Content-Disposition'] = 'inline; filename=' + patchname
+            msg.attach(p)
+        else:
+            body += '\n'.join(patch)
+            msg = email.MIMEText.MIMEText(body)
         if total == 1:
             subj = '[PATCH] ' + desc[0].strip()
         else:
@@ -274,7 +293,8 @@ def patchbomb(ui, repo, *revs, **opts):
 cmdtable = {
     'email':
     (patchbomb,
-     [('', 'bcc', [], 'email addresses of blind copy recipients'),
+     [('a', 'attach', None, 'send patches as inline attachments'),
+      ('', 'bcc', [], 'email addresses of blind copy recipients'),
       ('c', 'cc', [], 'email addresses of copy recipients'),
       ('d', 'diffstat', None, 'add diffstat output to messages'),
       ('f', 'from', '', 'email address of sender'),
--- a/tests/run-tests.py
+++ b/tests/run-tests.py
@@ -201,6 +201,11 @@ def run(cmd):
     return ret, splitnewlines(output)
 
 def run_one(test):
+    '''tristate output:
+    None -> skipped
+    True -> passed
+    False -> failed'''
+
     vlog("# Test", test)
     if not verbose:
         sys.stdout.write('.')
@@ -217,15 +222,28 @@ def run_one(test):
     os.mkdir(tmpd)
     os.chdir(tmpd)
 
-    if test.endswith(".py"):
-        cmd = '%s "%s"' % (sys.executable, os.path.join(TESTDIR, test))
-    else:
-        cmd = '"%s"' % (os.path.join(TESTDIR, test))
+    lctest = test.lower()
 
-    # To reliably get the error code from batch files on WinXP,
-    # the "cmd /c call" prefix is needed. Grrr
-    if os.name == 'nt' and test.endswith(".bat"):
+    if lctest.endswith('.py'):
+        cmd = '%s "%s"' % (sys.executable, os.path.join(TESTDIR, test))
+    elif lctest.endswith('.bat'):
+        # do not run batch scripts on non-windows
+        if os.name != 'nt':
+            print '\nSkipping %s: batch script' % test
+            return None
+        # To reliably get the error code from batch files on WinXP,
+        # the "cmd /c call" prefix is needed. Grrr
         cmd = 'cmd /c call "%s"' % (os.path.join(TESTDIR, test))
+    else:
+        # do not run shell scripts on windows
+        if os.name == 'nt':
+            print '\nSkipping %s: shell script' % test
+            return None
+        # do not try to run non-executable programs
+        if not os.access(os.path.join(TESTDIR, test), os.X_OK):
+            print '\nSkipping %s: not executable' % test
+            return None
+        cmd = '"%s"' % (os.path.join(TESTDIR, test))
 
     if options.timeout > 0:
         signal.alarm(options.timeout)
@@ -330,6 +348,7 @@ try:
 
         tests = 0
         failed = 0
+        skipped = 0
 
         if len(args) == 0:
             args = os.listdir(".")
@@ -337,11 +356,15 @@ try:
             if (test.startswith("test-") and '~' not in test and
                 ('.' not in test or test.endswith('.py') or 
                  test.endswith('.bat'))):
-                if not run_one(test):
+                ret = run_one(test)
+                if ret is None:
+                    skipped += 1
+                elif not ret:
                     failed += 1
                 tests += 1
 
-        print "\n# Ran %d tests, %d failed." % (tests, failed)
+        print "\n# Ran %d tests, %d skipped, %d failed." % (tests, skipped,
+                                                            failed)
         if coverage:
             output_coverage()
     except KeyboardInterrupt:
new file mode 100755
--- /dev/null
+++ b/tests/test-mq-qnew-twice
@@ -0,0 +1,15 @@
+#!/bin/sh
+
+HGRCPATH=$HGTMP/.hgrc; export HGRCPATH
+echo "[extensions]" >> $HGTMP/.hgrc
+echo "mq=" >> $HGTMP/.hgrc
+
+hg init a
+cd a
+hg qnew first.patch
+hg qnew first.patch
+
+touch ../first.patch
+hg qimport ../first.patch
+
+exit 0
new file mode 100644
--- /dev/null
+++ b/tests/test-mq-qnew-twice.out
@@ -0,0 +1,2 @@
+abort: patch "first.patch" already exists
+abort: patch "first.patch" already exists
--- a/tests/test-mq-qrefresh-replace-log-message
+++ b/tests/test-mq-qrefresh-replace-log-message
@@ -1,9 +1,9 @@
 #!/bin/sh
 
 # Environement setup for MQ
-export HGRCPATH=./hgrc
-echo "[extensions]" >> ./hgrc
-echo "mq=" >> ./hgrc
+HGRCPATH=$HGTMP/.hgrc; export HGRCPATH
+echo "[extensions]" >> $HGTMP/.hgrc
+echo "mq=" >> $HGTMP/.hgrc
 
 #Repo init
 hg init