##// END OF EJS Templates
record: allow splitting of hunks by manually editing patches...
record: allow splitting of hunks by manually editing patches It is possible that unrelated changes in a file are on sequential lines. The current record extension does not allow these to be committed independently. An example use case for this is in software development for deeply embedded real-time systems. In these environments, it is not always possible to use a debugger (due to time-constraints) and hence inline UART-based printing is often used. When fixing a bug in a module, it is often convenient to add a large number of 'printf's (linked to the UART via a custom fputc) to the module in order to work out what is going wrong. printf is a very slow function (and also variadic so somewhat frowned upon by the MISRA standard) and hence it is highly undesirable to commit these lines to the repository. If only a partial fix is implemented, however, it is desirable to commit the fix without deleting all of the printf lines. This is also simplifies removal of the printf lines as once the final fix is committed, 'hg revert' does the rest. It is likely that the printf lines will be very near the actual fix, so being able to split the hunk is very useful in this case. There were two alternatives I considered for the user interface. One was to manually edit the patch, the other to allow a hunk to be split into individual lines for consideration. The latter option would require a significant refactor of the record module and is less flexible. While the former is potentially more complicated to use, this is a feature that is likely to only be used in certain exceptional cases (such as the use case proposed above) and hence I felt that the complexity would not be a considerable issue. I've also written a follow-up patch that refactors the 'prompt' code to base everything on the choices variable. This tidies up and clarifies the code a bit (removes constructs like 'if ret == 7' and removes the 'e' option from the file scope options as it's not relevant there. It's not really a necessity, so I've excluded it from this submission for now, but I can send it separately if there's a desire and it's on bitbucket (see below) in the meantime. Possible future improvements include: * Tidying up the 'prompt' code to base everything on the choices variable. This would allow entries to be removed from the prompt as currently 'e' is offered even for entire file patches, which is currently unsupported. * Allowing the entire file (or even multi-file) patch to be edited manually: this would require quite a large refactor without much benefit, so I decided to exclude it from the initial submission. * Allow the option to retry if a patch fails to apply (this is what Git does). This would require quite a bit of refactoring given the current 'hg record' implementation, so it's debatable whether it's worth it. Output is similar to existing record user interface except that an additional option ('e') exists to allow manual editing of the patch. This opens the user's configured editor with the patch. A comment is added to the bottom of the patch explaining what to do (based on Git's one). A large proportion of the changeset is test-case changes to update the options reported by record (Ynesfdaq? instead of Ynsfdaq?). Functional changes are in record.py and there are some new test cases in test-record.t.

File last commit:

r16320:e11ab387 stable
r16324:46b991a1 default
Show More
hghave
329 lines | 9.0 KiB | text/plain | TextLexer
Patrick Mezard
Add hghave utility and run-tests.py support....
r4881 #!/usr/bin/env python
"""Test the running system for features availability. Exit with zero
Patrick Mezard
hghave: feature absence can be checked by prefixing with 'no-'
r5084 if all features are there, non-zero otherwise. If a feature name is
prefixed with "no-", the absence of feature is tested.
Patrick Mezard
Add hghave utility and run-tests.py support....
r4881 """
import optparse
import os
Patrick Mezard
hghave: wrap command output matching
r5252 import re
Patrick Mezard
Add hghave utility and run-tests.py support....
r4881 import sys
Patrick Mezard
hghave: detect executable permission availability.
r5072 import tempfile
Patrick Mezard
Add hghave utility and run-tests.py support....
r4881
Patrick Mezard
hghave: prefix temporary files with "hg-hghave-"
r5090 tempprefix = 'hg-hghave-'
Patrick Mezard
hghave: detect cvs and cvsps availability...
r5302 def matchoutput(cmd, regexp, ignorestatus=False):
Patrick Mezard
hghave: wrap command output matching
r5252 """Return True if cmd executes successfully and its output
is matched by the supplied regular expression.
"""
r = re.compile(regexp)
fh = os.popen(cmd)
s = fh.read()
Patrick Mezard
hghave: handle Windows raising on popen() failure
r8213 try:
ret = fh.close()
except IOError:
# Happen in Windows test environment
ret = 1
Patrick Mezard
hghave: detect cvs and cvsps availability...
r5302 return (ignorestatus or ret is None) and r.search(s)
Patrick Mezard
hghave: wrap command output matching
r5252
Aleix Conchillo Flaque
convert: added gnu arch (baz) tests
r6078 def has_baz():
return matchoutput('baz --version 2>&1', r'baz Bazaar version')
Marek Kubica
convert: add bzr source
r7053 def has_bzr():
Dirkjan Ochtman
tests: check for bzr support by importing bzrlib...
r7061 try:
import bzrlib
Simon Heimberg
test suite: saver check if bzr is installed...
r7773 return bzrlib.__doc__ != None
Dirkjan Ochtman
tests: check for bzr support by importing bzrlib...
r7061 except ImportError:
return False
Marek Kubica
convert: add bzr source
r7053
Patrick Mezard
convert/bzr: handle files replaced by directories (issue1623)
r8126 def has_bzr114():
try:
import bzrlib
return (bzrlib.__doc__ != None
Mads Kiilerich
tests/hghave: bzr114 checks for bzr >= 1.14...
r9244 and bzrlib.version_info[:2] >= (1, 14))
Patrick Mezard
convert/bzr: handle files replaced by directories (issue1623)
r8126 except ImportError:
return False
Patrick Mezard
hghave: detect cvs and cvsps availability...
r5302 def has_cvs():
Dirkjan Ochtman
tests: don't run test-convert-cvs if there's no cvs server
r6626 re = r'Concurrent Versions System.*?server'
Mads Kiilerich
tests: skip cvs tests with msys on windows...
r15568 return matchoutput('cvs --version 2>&1', re) and not has_msys()
Patrick Mezard
hghave: detect cvs and cvsps availability...
r5302
Patrick Mezard
hghave: detect darcs client
r5410 def has_darcs():
Bryan O'Sullivan
Fix failing darcs test
r9326 return matchoutput('darcs --version', r'2\.[2-9]', True)
Patrick Mezard
hghave: detect darcs client
r5410
Patrick Mezard
Add a test for monotone conversion
r6372 def has_mtn():
Thomas Arendsen Hein
Skip older monotone versions for tests....
r6384 return matchoutput('mtn --version', r'monotone', True) and not matchoutput(
Thomas Arendsen Hein
tests: fix updated monotone version requirement...
r14550 'mtn --version', r'monotone 0\.', True)
Patrick Mezard
Add a test for monotone conversion
r6372
Patrick Mezard
hghave: reorder check functions and entries
r5409 def has_eol_in_paths():
try:
fd, path = tempfile.mkstemp(prefix=tempprefix, suffix='\n\r')
os.close(fd)
os.remove(path)
return True
except:
return False
Patrick Mezard
hghave: detect executable permission availability.
r5072 def has_executablebit():
Patrick Mezard
hghave: prefix temporary files with "hg-hghave-"
r5090 fd, path = tempfile.mkstemp(prefix=tempprefix)
Patrick Mezard
hghave: detect executable permission availability.
r5072 os.close(fd)
try:
s = os.lstat(path).st_mode
os.chmod(path, s | 0100)
return (os.lstat(path).st_mode & 0100 != 0)
finally:
os.remove(path)
Patrick Mezard
Add test for case folding issues
r6806 def has_icasefs():
# Stolen from mercurial.util
Simon Heimberg
hghave: check for case insensitive filesystem in current dir...
r9395 fd, path = tempfile.mkstemp(prefix=tempprefix, dir='.')
Patrick Mezard
Add test for case folding issues
r6806 os.close(fd)
try:
s1 = os.stat(path)
d, b = os.path.split(path)
p2 = os.path.join(d, b.upper())
if path == p2:
p2 = os.path.join(d, b.lower())
try:
s2 = os.stat(p2)
return s2 == s1
except:
return False
finally:
Benoit Boissinot
merge with -stable
r6998 os.remove(path)
Benoit Boissinot
inotify: deactivate inotify status on failure...
r6996 def has_inotify():
try:
import hgext.inotify.linux.watcher
return True
except ImportError:
return False
Patrick Mezard
hghave: reorder check functions and entries
r5409 def has_fifo():
return hasattr(os, "mkfifo")
Patrick Mezard
hghave: detect support for EOL in paths.
r5074
Idan Kamara
posix, windows: introduce cachestat...
r14927 def has_cacheable_fs():
from mercurial import util
fd, path = tempfile.mkstemp(prefix=tempprefix)
os.close(fd)
try:
return util.cachestat(path).cacheable()
finally:
os.remove(path)
Patrick Mezard
Test --time, --profile and --lsprof
r5099 def has_lsprof():
try:
import _lsprof
return True
except ImportError:
return False
Martin Geisler
test-i18n: make test conditional on msgfmt availability
r13442 def has_gettext():
return matchoutput('msgfmt --version', 'GNU gettext-tools')
Patrick Mezard
hghave: detect git availability
r5218 def has_git():
Patrick Mezard
hghave: wrap command output matching
r5252 return matchoutput('git --version 2>&1', r'^git version')
Patrick Mezard
hghave: detect git availability
r5218
Martin Geisler
doc: add generic frontend to rst2man and rst2html...
r10971 def has_docutils():
try:
from docutils.core import publish_cmdline
return True
except ImportError:
return False
Martin Geisler
test-gendoc: test documentation generation
r9446
Patrick Mezard
subrepo: handle svn tracked/unknown directory collisions...
r14050 def getsvnversion():
m = matchoutput('svn --version 2>&1', r'^svn,\s+version\s+(\d+)\.(\d+)')
if not m:
return (0, 0)
return (int(m.group(1)), int(m.group(2)))
def has_svn15():
return getsvnversion() >= (1, 5)
Thomas Arendsen Hein
tests: check for svn >= 1.3 and >= 1.5 in tests that require those versions
r15346 def has_svn13():
return getsvnversion() >= (1, 3)
Patrick Mezard
hghave: detect subversion client and admin tools availability
r5253 def has_svn():
Patrick Mezard
convert: reenable SVN support after license issue solved
r9819 return matchoutput('svn --version 2>&1', r'^svn, version') and \
matchoutput('svnadmin --version 2>&1', r'^svnadmin, version')
Patrick Mezard
hghave: detect subversion client and admin tools availability
r5253
Patrick Mezard
hghave: detect subversion bindings availability
r5254 def has_svn_bindings():
try:
import svn.core
Dirkjan Ochtman
tests: run svn tests only with svn bindings >1.3
r7315 version = svn.core.SVN_VER_MAJOR, svn.core.SVN_VER_MINOR
if version < (1, 4):
return False
Patrick Mezard
hghave: detect subversion bindings availability
r5254 return True
except ImportError:
return False
Frank Kingswood
convert: Perforce source for conversion to Mercurial
r7823 def has_p4():
return matchoutput('p4 -V', r'Rev\. P4/') and matchoutput('p4d -V', r'Rev\. P4D/')
Patrick Mezard
hghave: reorder check functions and entries
r5409 def has_symlink():
Mads Kiilerich
tests: use 'hghave symlink' for tests using symlinks
r15441 return hasattr(os, "symlink") # FIXME: should also check file system and os
Patrick Mezard
hghave: reorder check functions and entries
r5409
Aleix Conchillo Flaque
convert: added GNU Arch (tla) tests and related fixes
r6079 def has_tla():
return matchoutput('tla --version 2>&1', r'The GNU Arch Revision')
Brendan Cully
gpg: add test
r8809 def has_gpg():
return matchoutput('gpg --version 2>&1', r'GnuPG')
Alexis S. L. Carvalho
hghave: detect unix-style permissions...
r6063 def has_unix_permissions():
d = tempfile.mkdtemp(prefix=tempprefix, dir=".")
try:
fname = os.path.join(d, 'foo')
for umask in (077, 007, 022):
os.umask(umask)
f = open(fname, 'w')
f.close()
mode = os.stat(fname).st_mode
os.unlink(fname)
if mode & 0777 != ~umask & 0666:
return False
return True
finally:
os.rmdir(d)
timeless
tests: add pyflakes checking for unused imports
r14140 def has_pyflakes():
return matchoutput('echo "import re" 2>&1 | pyflakes',
r"<stdin>:1: 're' imported but unused",
True)
Dirkjan Ochtman
tests: add highlight extension tests
r6355 def has_pygments():
try:
import pygments
return True
except ImportError:
return False
Mads Kiilerich
tests: Skip tests if they will fail because of outer repo...
r7429 def has_outer_repo():
return matchoutput('hg root 2>&1', r'')
Mads Kiilerich
serve: fix https mode and add test...
r12740 def has_ssl():
try:
import ssl
Mads Kiilerich
tests: update ssl requirement for test-https.t...
r13418 import OpenSSL
OpenSSL.SSL.Context
Mads Kiilerich
serve: fix https mode and add test...
r12740 return True
except ImportError:
return False
Mads Kiilerich
tests: use 'hghave no-windows' to avoid testing reserved file names on windows
r15444 def has_windows():
return os.name == 'nt'
Mads Kiilerich
tests: use 'hghave system-sh' to guard tests that requires sh in system()
r15445 def has_system_sh():
return os.name != 'nt'
Mads Kiilerich
tests: use 'hghave serve' to guard tests that requires serve daemon management
r15446 def has_serve():
return os.name != 'nt' # gross approximation
Mads Kiilerich
tests: skip color test on platforms without tic
r15539 def has_tic():
return matchoutput('test -x "`which tic`"', '')
Mads Kiilerich
tests: introduce 'hghave msys' to skip tests that would fail because of msys
r15567 def has_msys():
return os.getenv('MSYSTEM')
Patrick Mezard
Add hghave utility and run-tests.py support....
r4881 checks = {
Aleix Conchillo Flaque
convert: added gnu arch (baz) tests
r6078 "baz": (has_baz, "GNU Arch baz client"),
Marek Kubica
convert: add bzr source
r7053 "bzr": (has_bzr, "Canonical's Bazaar client"),
Patrick Mezard
convert/bzr: handle files replaced by directories (issue1623)
r8126 "bzr114": (has_bzr114, "Canonical's Bazaar client >= 1.14"),
Idan Kamara
posix, windows: introduce cachestat...
r14927 "cacheable": (has_cacheable_fs, "cacheable filesystem"),
Dirkjan Ochtman
tests: don't run test-convert-cvs if there's no cvs server
r6626 "cvs": (has_cvs, "cvs client/server"),
Patrick Mezard
hghave: detect darcs client
r5410 "darcs": (has_darcs, "darcs client"),
Mads Kiilerich
serve: fix https mode and add test...
r12740 "docutils": (has_docutils, "Docutils text processing library"),
Patrick Mezard
Test --time, --profile and --lsprof
r5099 "eol-in-paths": (has_eol_in_paths, "end-of-lines in paths"),
"execbit": (has_executablebit, "executable bit"),
Patrick Mezard
hghave: reorder check functions and entries
r5409 "fifo": (has_fifo, "named pipes"),
Martin Geisler
test-i18n: make test conditional on msgfmt availability
r13442 "gettext": (has_gettext, "GNU Gettext (msgfmt)"),
Patrick Mezard
hghave: detect git availability
r5218 "git": (has_git, "git command line client"),
Brendan Cully
gpg: add test
r8809 "gpg": (has_gpg, "gpg client"),
Patrick Mezard
Add test for case folding issues
r6806 "icasefs": (has_icasefs, "case insensitive file system"),
Benoit Boissinot
inotify: deactivate inotify status on failure...
r6996 "inotify": (has_inotify, "inotify extension support"),
Patrick Mezard
Test --time, --profile and --lsprof
r5099 "lsprof": (has_lsprof, "python lsprof module"),
Sune Foldager
tests: update monotone version requirement
r14432 "mtn": (has_mtn, "monotone client (>= 1.0)"),
Mads Kiilerich
tests: Skip tests if they will fail because of outer repo...
r7429 "outer-repo": (has_outer_repo, "outer repo"),
Frank Kingswood
convert: Perforce source for conversion to Mercurial
r7823 "p4": (has_p4, "Perforce server and client"),
timeless
tests: add pyflakes checking for unused imports
r14140 "pyflakes": (has_pyflakes, "Pyflakes python linter"),
Benoit Boissinot
inotify: deactivate inotify status on failure...
r6996 "pygments": (has_pygments, "Pygments source highlighting library"),
Mads Kiilerich
tests: use 'hghave serve' to guard tests that requires serve daemon management
r15446 "serve": (has_serve, "platform and python can manage 'hg serve -d'"),
timeless
tests: improve hghave error reporting for missing Py OpenSSL
r13543 "ssl": (has_ssl, "python >= 2.6 ssl module and python OpenSSL"),
Patrick Mezard
hghave: detect subversion client and admin tools availability
r5253 "svn": (has_svn, "subversion client and admin tools"),
Thomas Arendsen Hein
tests: check for svn >= 1.3 and >= 1.5 in tests that require those versions
r15346 "svn13": (has_svn13, "subversion client and admin tools >= 1.3"),
Patrick Mezard
subrepo: handle svn tracked/unknown directory collisions...
r14050 "svn15": (has_svn15, "subversion client and admin tools >= 1.5"),
Patrick Mezard
hghave: detect subversion bindings availability
r5254 "svn-bindings": (has_svn_bindings, "subversion python bindings"),
Patrick Mezard
Test --time, --profile and --lsprof
r5099 "symlink": (has_symlink, "symbolic links"),
Mads Kiilerich
tests: use 'hghave system-sh' to guard tests that requires sh in system()
r15445 "system-sh": (has_system_sh, "system() uses sh"),
Mads Kiilerich
tests: skip color test on platforms without tic
r15539 "tic": (has_tic, "terminfo compiler"),
Aleix Conchillo Flaque
convert: added GNU Arch (tla) tests and related fixes
r6079 "tla": (has_tla, "GNU Arch tla client"),
Alexis S. L. Carvalho
hghave: detect unix-style permissions...
r6063 "unix-permissions": (has_unix_permissions, "unix-style permissions"),
Mads Kiilerich
tests: use 'hghave no-windows' to avoid testing reserved file names on windows
r15444 "windows": (has_windows, "Windows"),
Mads Kiilerich
tests: introduce 'hghave msys' to skip tests that would fail because of msys
r15567 "msys": (has_msys, "Windows with MSYS"),
Patrick Mezard
Add hghave utility and run-tests.py support....
r4881 }
def list_features():
for name, feature in checks.iteritems():
desc = feature[1]
print name + ':', desc
Nicolas Dumazet
hghave: checking that all targets are Exception-free
r8059 def test_features():
failed = 0
for name, feature in checks.iteritems():
check, _ = feature
try:
check()
except Exception, e:
print "feature %s failed: %s" % (name, e)
failed += 1
return failed
Patrick Mezard
Add hghave utility and run-tests.py support....
r4881 parser = optparse.OptionParser("%prog [options] [features]")
Nicolas Dumazet
hghave: checking that all targets are Exception-free
r8059 parser.add_option("--test-features", action="store_true",
help="test available features")
Patrick Mezard
Add hghave utility and run-tests.py support....
r4881 parser.add_option("--list-features", action="store_true",
help="list available features")
parser.add_option("-q", "--quiet", action="store_true",
help="check features silently")
if __name__ == '__main__':
options, args = parser.parse_args()
if options.list_features:
list_features()
sys.exit(0)
Thomas Arendsen Hein
Remove trailing spaces
r5081
Nicolas Dumazet
hghave: checking that all targets are Exception-free
r8059 if options.test_features:
sys.exit(test_features())
Patrick Mezard
Add hghave utility and run-tests.py support....
r4881 quiet = options.quiet
failures = 0
def error(msg):
global failures
if not quiet:
sys.stderr.write(msg + '\n')
failures += 1
Thomas Arendsen Hein
Remove trailing spaces
r5081
Patrick Mezard
Add hghave utility and run-tests.py support....
r4881 for feature in args:
Patrick Mezard
hghave: feature absence can be checked by prefixing with 'no-'
r5084 negate = feature.startswith('no-')
if negate:
feature = feature[3:]
Thomas Arendsen Hein
Hide absolute path from test-no-symlinks output....
r5091
Patrick Mezard
Add hghave utility and run-tests.py support....
r4881 if feature not in checks:
Thomas Arendsen Hein
Use skipped: instead of hghave: for skipping tests, use this in test-merge-types
r5685 error('skipped: unknown feature: ' + feature)
Patrick Mezard
Add hghave utility and run-tests.py support....
r4881 continue
Thomas Arendsen Hein
Remove trailing spaces
r5081
check, desc = checks[feature]
Nicolas Dumazet
run-tests: detect when hghave fails to check for a feature and fail test...
r8060 try:
available = check()
except Exception, e:
error('hghave check failed: ' + feature)
continue
if not negate and not available:
Thomas Arendsen Hein
Use skipped: instead of hghave: for skipping tests, use this in test-merge-types
r5685 error('skipped: missing feature: ' + desc)
Nicolas Dumazet
run-tests: detect when hghave fails to check for a feature and fail test...
r8060 elif negate and available:
Thomas Arendsen Hein
Use skipped: instead of hghave: for skipping tests, use this in test-merge-types
r5685 error('skipped: system supports %s' % desc)
Patrick Mezard
Add hghave utility and run-tests.py support....
r4881
if failures != 0:
sys.exit(1)