# HG changeset patch # User Matt Harbison # Date 2018-07-16 04:32:33 # Node ID c382c19ce9bd5c335beae197e82e7cda2a213eb2 # Parent 02b5b5c1bba858d037c6d4c91305db61a479826c windows: expand '~/' and '~\' to %USERPROFILE% when translating to cmd.exe It's convenient to be able to reference hooks in a portable location on any platform. diff --git a/mercurial/help/config.txt b/mercurial/help/config.txt --- a/mercurial/help/config.txt +++ b/mercurial/help/config.txt @@ -892,9 +892,11 @@ be ``$HG_HOOKTYPE=incoming`` and ``$HG_H .. container:: windows Some basic Unix syntax can be enabled for portability, including ``$VAR`` - and ``${VAR}`` style variables. To use a literal ``$``, it must be - escaped with a back slash or inside of a strong quote. Strong quotes - will be replaced by double quotes after processing. + and ``${VAR}`` style variables. A ``~`` followed by ``\`` or ``/`` will + be expanded to ``%USERPROFILE%`` to simulate a subset of tilde expansion + on Unix. To use a literal ``$`` or ``~``, it must be escaped with a back + slash or inside of a strong quote. Strong quotes will be replaced by + double quotes after processing. This feature is enabled by adding a prefix of ``tonative.`` to the hook name on a new line, and setting it to ``True``. For example:: diff --git a/mercurial/windows.py b/mercurial/windows.py --- a/mercurial/windows.py +++ b/mercurial/windows.py @@ -276,8 +276,11 @@ def shelltocmdexe(path, env): >>> # No double substitution >>> shelltocmdexe(b"$var1 %var1%", {b'var1': b'%var2%', b'var2': b'boom'}) '%var1% %var1%' + >>> # Tilde expansion + >>> shelltocmdexe(b"~/dir ~\dir2 ~tmpfile \~/", {}) + '%USERPROFILE%/dir %USERPROFILE%\\dir2 ~tmpfile ~/' """ - if not any(c in path for c in b"$'"): + if not any(c in path for c in b"$'~"): return path varchars = pycompat.sysbytes(string.ascii_letters + string.digits) + b'_-' @@ -344,9 +347,13 @@ def shelltocmdexe(path, env): if c != '': index -= 1 - elif c == b'\\' and index + 1 < pathlen and path[index + 1] == b'$': - # Skip '\', but only if it is escaping $ - res += b'$' + elif (c == b'~' and index + 1 < pathlen + and path[index + 1] in (b'\\', b'/')): + res += "%USERPROFILE%" + elif (c == b'\\' and index + 1 < pathlen + and path[index + 1] in (b'$', b'~')): + # Skip '\', but only if it is escaping $ or ~ + res += path[index + 1] index += 1 else: res += c