This is done by:
sed -i "s/pycompat\.osname == 'nt'/pycompat.iswindows/" **/*.py sed -i "s/pycompat\.osname != 'nt'/not pycompat.iswindows/" **/*.py sed -i 's/pycompat.osname == "nt"/pycompat.iswindows/' **/*.py
( )
| spectral | |
| lothiraldan |
| hg-reviewers |
This is done by:
sed -i "s/pycompat\.osname == 'nt'/pycompat.iswindows/" **/*.py sed -i "s/pycompat\.osname != 'nt'/not pycompat.iswindows/" **/*.py sed -i 's/pycompat.osname == "nt"/pycompat.iswindows/' **/*.py
| Lint Skipped |
| Unit Tests Skipped |
| Path | Packages | |||
|---|---|---|---|---|
| M | hgext/convert/subversion.py (4 lines) | |||
| M | hgext/largefiles/lfutil.py (2 lines) | |||
| M | hgext/logtoprocess.py (2 lines) | |||
| M | hgext/schemes.py (2 lines) | |||
| M | hgext/win32mbcs.py (2 lines) | |||
| M | mercurial/color.py (4 lines) | |||
| M | mercurial/debugcommands.py (2 lines) | |||
| M | mercurial/hgweb/server.py (2 lines) | |||
| M | mercurial/i18n.py (2 lines) | |||
| M | mercurial/pure/osutil.py (2 lines) | |||
| M | mercurial/rcutil.py (2 lines) | |||
| M | mercurial/scmutil.py (4 lines) | |||
| M | mercurial/sslutil.py (6 lines) | |||
| M | mercurial/subrepo.py (2 lines) | |||
| M | mercurial/ui.py (2 lines) | |||
| M | mercurial/util.py (6 lines) | |||
| M | mercurial/vfs.py (2 lines) | |||
| M | mercurial/worker.py (2 lines) |
| def geturl(path): | def geturl(path): | ||||
| try: | try: | ||||
| return svn.client.url_from_path(svn.core.svn_path_canonicalize(path)) | return svn.client.url_from_path(svn.core.svn_path_canonicalize(path)) | ||||
| except svn.core.SubversionException: | except svn.core.SubversionException: | ||||
| # svn.client.url_from_path() fails with local repositories | # svn.client.url_from_path() fails with local repositories | ||||
| pass | pass | ||||
| if os.path.isdir(path): | if os.path.isdir(path): | ||||
| path = os.path.normpath(os.path.abspath(path)) | path = os.path.normpath(os.path.abspath(path)) | ||||
| if pycompat.osname == 'nt': | if pycompat.iswindows: | ||||
| path = '/' + util.normpath(path) | path = '/' + util.normpath(path) | ||||
| # Module URL is later compared with the repository URL returned | # Module URL is later compared with the repository URL returned | ||||
| # by svn API, which is UTF-8. | # by svn API, which is UTF-8. | ||||
| path = encoding.tolocal(path) | path = encoding.tolocal(path) | ||||
| path = 'file://%s' % quote(path) | path = 'file://%s' % quote(path) | ||||
| return svn.core.svn_path_canonicalize(path) | return svn.core.svn_path_canonicalize(path) | ||||
| def optrev(number): | def optrev(number): | ||||
| protomap = {'http': httpcheck, | protomap = {'http': httpcheck, | ||||
| 'https': httpcheck, | 'https': httpcheck, | ||||
| 'file': filecheck, | 'file': filecheck, | ||||
| } | } | ||||
| def issvnurl(ui, url): | def issvnurl(ui, url): | ||||
| try: | try: | ||||
| proto, path = url.split('://', 1) | proto, path = url.split('://', 1) | ||||
| if proto == 'file': | if proto == 'file': | ||||
| if (pycompat.osname == 'nt' and path[:1] == '/' | if (pycompat.iswindows and path[:1] == '/' | ||||
| and path[1:2].isalpha() and path[2:6].lower() == '%3a/'): | and path[1:2].isalpha() and path[2:6].lower() == '%3a/'): | ||||
| path = path[:2] + ':/' + path[6:] | path = path[:2] + ':/' + path[6:] | ||||
| path = urlreq.url2pathname(path) | path = urlreq.url2pathname(path) | ||||
| except ValueError: | except ValueError: | ||||
| proto = 'file' | proto = 'file' | ||||
| path = os.path.abspath(url) | path = os.path.abspath(url) | ||||
| if proto == 'file': | if proto == 'file': | ||||
| path = util.pconvert(path) | path = util.pconvert(path) | ||||
| to preserve download bandwidth and storage space.''' | to preserve download bandwidth and storage space.''' | ||||
| return os.path.join(_usercachedir(ui), hash) | return os.path.join(_usercachedir(ui), hash) | ||||
| def _usercachedir(ui): | def _usercachedir(ui): | ||||
| '''Return the location of the "global" largefiles cache.''' | '''Return the location of the "global" largefiles cache.''' | ||||
| path = ui.configpath(longname, 'usercache', None) | path = ui.configpath(longname, 'usercache', None) | ||||
| if path: | if path: | ||||
| return path | return path | ||||
| if pycompat.osname == 'nt': | if pycompat.iswindows: | ||||
| appdata = encoding.environ.get('LOCALAPPDATA',\ | appdata = encoding.environ.get('LOCALAPPDATA',\ | ||||
| encoding.environ.get('APPDATA')) | encoding.environ.get('APPDATA')) | ||||
| if appdata: | if appdata: | ||||
| return os.path.join(appdata, longname) | return os.path.join(appdata, longname) | ||||
| elif pycompat.sysplatform == 'darwin': | elif pycompat.sysplatform == 'darwin': | ||||
| home = encoding.environ.get('HOME') | home = encoding.environ.get('HOME') | ||||
| if home: | if home: | ||||
| return os.path.join(home, 'Library', 'Caches', longname) | return os.path.join(home, 'Library', 'Caches', longname) | ||||
| # Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for | # Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for | ||||
| # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should | # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should | ||||
| # be specifying the version(s) of Mercurial they are tested with, or | # be specifying the version(s) of Mercurial they are tested with, or | ||||
| # leave the attribute unspecified. | # leave the attribute unspecified. | ||||
| testedwith = 'ships-with-hg-core' | testedwith = 'ships-with-hg-core' | ||||
| def uisetup(ui): | def uisetup(ui): | ||||
| if pycompat.osname == 'nt': | if pycompat.iswindows: | ||||
| # no fork on Windows, but we can create a detached process | # no fork on Windows, but we can create a detached process | ||||
| # https://msdn.microsoft.com/en-us/library/windows/desktop/ms684863.aspx | # https://msdn.microsoft.com/en-us/library/windows/desktop/ms684863.aspx | ||||
| # No stdlib constant exists for this value | # No stdlib constant exists for this value | ||||
| DETACHED_PROCESS = 0x00000008 | DETACHED_PROCESS = 0x00000008 | ||||
| _creationflags = DETACHED_PROCESS | subprocess.CREATE_NEW_PROCESS_GROUP | _creationflags = DETACHED_PROCESS | subprocess.CREATE_NEW_PROCESS_GROUP | ||||
| def runshellcommand(script, env): | def runshellcommand(script, env): | ||||
| # we can't use close_fds *and* redirect stdin. I'm not sure that we | # we can't use close_fds *and* redirect stdin. I'm not sure that we | ||||
| 'gcode': 'https://{1}.googlecode.com/hg/', | 'gcode': 'https://{1}.googlecode.com/hg/', | ||||
| 'kiln': 'https://{1}.kilnhg.com/Repo/' | 'kiln': 'https://{1}.kilnhg.com/Repo/' | ||||
| } | } | ||||
| def extsetup(ui): | def extsetup(ui): | ||||
| schemes.update(dict(ui.configitems('schemes'))) | schemes.update(dict(ui.configitems('schemes'))) | ||||
| t = templater.engine(lambda x: x) | t = templater.engine(lambda x: x) | ||||
| for scheme, url in schemes.items(): | for scheme, url in schemes.items(): | ||||
| if (pycompat.osname == 'nt' and len(scheme) == 1 and scheme.isalpha() | if (pycompat.iswindows and len(scheme) == 1 and scheme.isalpha() | ||||
| and os.path.exists('%s:\\' % scheme)): | and os.path.exists('%s:\\' % scheme)): | ||||
| raise error.Abort(_('custom scheme %s:// conflicts with drive ' | raise error.Abort(_('custom scheme %s:// conflicts with drive ' | ||||
| 'letter %s:\\\n') % (scheme, scheme.upper())) | 'letter %s:\\\n') % (scheme, scheme.upper())) | ||||
| hg.schemes[scheme] = ShortRepository(url, scheme, t) | hg.schemes[scheme] = ShortRepository(url, scheme, t) | ||||
| extensions.wrapfunction(util, 'hasdriveletter', hasdriveletter) | extensions.wrapfunction(util, 'hasdriveletter', hasdriveletter) | ||||
| @command('debugexpandscheme', norepo=True) | @command('debugexpandscheme', norepo=True) | ||||
| def expandscheme(ui, url, **opts): | def expandscheme(ui, url, **opts): | ||||
| """given a repo path, provide the scheme-expanded path | """given a repo path, provide the scheme-expanded path | ||||
| """ | """ | ||||
| repo = hg._peerlookup(url) | repo = hg._peerlookup(url) | ||||
| if isinstance(repo, ShortRepository): | if isinstance(repo, ShortRepository): | ||||
| url = repo.resolve(url) | url = repo.resolve(url) | ||||
| ui.write(url + '\n') | ui.write(url + '\n') | ||||
| return | return | ||||
| # determine encoding for filename | # determine encoding for filename | ||||
| global _encoding | global _encoding | ||||
| _encoding = ui.config('win32mbcs', 'encoding') | _encoding = ui.config('win32mbcs', 'encoding') | ||||
| # fake is only for relevant environment. | # fake is only for relevant environment. | ||||
| if _encoding.lower() in problematic_encodings.split(): | if _encoding.lower() in problematic_encodings.split(): | ||||
| for f in funcs.split(): | for f in funcs.split(): | ||||
| wrapname(f, wrapper) | wrapname(f, wrapper) | ||||
| if pycompat.osname == 'nt': | if pycompat.iswindows: | ||||
| for f in winfuncs.split(): | for f in winfuncs.split(): | ||||
| wrapname(f, wrapper) | wrapname(f, wrapper) | ||||
| wrapname("mercurial.util.listdir", wrapperforlistdir) | wrapname("mercurial.util.listdir", wrapperforlistdir) | ||||
| wrapname("mercurial.windows.listdir", wrapperforlistdir) | wrapname("mercurial.windows.listdir", wrapperforlistdir) | ||||
| # wrap functions to be called with local byte string arguments | # wrap functions to be called with local byte string arguments | ||||
| for f in rfuncs.split(): | for f in rfuncs.split(): | ||||
| wrapname(f, reversewrapper) | wrapname(f, reversewrapper) | ||||
| # Check sys.args manually instead of using ui.debug() because | # Check sys.args manually instead of using ui.debug() because | ||||
| # command line options is not yet applied when | # command line options is not yet applied when | ||||
| # extensions.loadall() is called. | # extensions.loadall() is called. | ||||
| if '--debug' in sys.argv: | if '--debug' in sys.argv: | ||||
| ui.write(("[win32mbcs] activated with encoding: %s\n") | ui.write(("[win32mbcs] activated with encoding: %s\n") | ||||
| % _encoding) | % _encoding) | ||||
| mode = ui.config('color', 'mode') | mode = ui.config('color', 'mode') | ||||
| # If pager is active, color.pagermode overrides color.mode. | # If pager is active, color.pagermode overrides color.mode. | ||||
| if getattr(ui, 'pageractive', False): | if getattr(ui, 'pageractive', False): | ||||
| mode = ui.config('color', 'pagermode', mode) | mode = ui.config('color', 'pagermode', mode) | ||||
| realmode = mode | realmode = mode | ||||
| if pycompat.osname == 'nt': | if pycompat.iswindows: | ||||
| from . import win32 | from . import win32 | ||||
| term = encoding.environ.get('TERM') | term = encoding.environ.get('TERM') | ||||
| # TERM won't be defined in a vanilla cmd.exe environment. | # TERM won't be defined in a vanilla cmd.exe environment. | ||||
| # UNIX-like environments on Windows such as Cygwin and MSYS will | # UNIX-like environments on Windows such as Cygwin and MSYS will | ||||
| # set TERM. They appear to make a best effort attempt at setting it | # set TERM. They appear to make a best effort attempt at setting it | ||||
| # to something appropriate. However, not all environments with TERM | # to something appropriate. However, not all environments with TERM | ||||
| effects.append(l) | effects.append(l) | ||||
| effects = ' '.join(effects) | effects = ' '.join(effects) | ||||
| if effects: | if effects: | ||||
| msg = '\n'.join([_render_effects(ui, line, effects) | msg = '\n'.join([_render_effects(ui, line, effects) | ||||
| for line in msg.split('\n')]) | for line in msg.split('\n')]) | ||||
| return msg | return msg | ||||
| w32effects = None | w32effects = None | ||||
| if pycompat.osname == 'nt': | if pycompat.iswindows: | ||||
| import ctypes | import ctypes | ||||
| _kernel32 = ctypes.windll.kernel32 | _kernel32 = ctypes.windll.kernel32 | ||||
| _WORD = ctypes.c_ushort | _WORD = ctypes.c_ushort | ||||
| _INVALID_HANDLE_VALUE = -1 | _INVALID_HANDLE_VALUE = -1 | ||||
| does nothing on other platforms. | does nothing on other platforms. | ||||
| If SOURCE is omitted, the 'default' path will be used. If a URL is given, | If SOURCE is omitted, the 'default' path will be used. If a URL is given, | ||||
| that server is used. See :hg:`help urls` for more information. | that server is used. See :hg:`help urls` for more information. | ||||
| If the update succeeds, retry the original operation. Otherwise, the cause | If the update succeeds, retry the original operation. Otherwise, the cause | ||||
| of the SSL error is likely another issue. | of the SSL error is likely another issue. | ||||
| ''' | ''' | ||||
| if pycompat.osname != 'nt': | if not pycompat.iswindows: | ||||
| raise error.Abort(_('certificate chain building is only possible on ' | raise error.Abort(_('certificate chain building is only possible on ' | ||||
| 'Windows')) | 'Windows')) | ||||
| if not source: | if not source: | ||||
| if not repo: | if not repo: | ||||
| raise error.Abort(_("there is no Mercurial repository here, and no " | raise error.Abort(_("there is no Mercurial repository here, and no " | ||||
| "server specified")) | "server specified")) | ||||
| source = "default" | source = "default" | ||||
| def openlog(opt, default): | def openlog(opt, default): | ||||
| if opt and opt != '-': | if opt and opt != '-': | ||||
| return open(opt, 'a') | return open(opt, 'a') | ||||
| return default | return default | ||||
| class MercurialHTTPServer(_mixin, httpservermod.httpserver, object): | class MercurialHTTPServer(_mixin, httpservermod.httpserver, object): | ||||
| # SO_REUSEADDR has broken semantics on windows | # SO_REUSEADDR has broken semantics on windows | ||||
| if pycompat.osname == 'nt': | if pycompat.iswindows: | ||||
| allow_reuse_address = 0 | allow_reuse_address = 0 | ||||
| def __init__(self, ui, app, addr, handler, **kwargs): | def __init__(self, ui, app, addr, handler, **kwargs): | ||||
| httpservermod.httpserver.__init__(self, addr, handler, **kwargs) | httpservermod.httpserver.__init__(self, addr, handler, **kwargs) | ||||
| self.daemon_threads = True | self.daemon_threads = True | ||||
| self.application = app | self.application = app | ||||
| handler.preparehttpserver(self, ui) | handler.preparehttpserver(self, ui) | ||||
| module = pycompat.fsencode(__file__) | module = pycompat.fsencode(__file__) | ||||
| try: | try: | ||||
| unicode | unicode | ||||
| except NameError: | except NameError: | ||||
| unicode = str | unicode = str | ||||
| _languages = None | _languages = None | ||||
| if (pycompat.osname == 'nt' | if (pycompat.iswindows | ||||
| and 'LANGUAGE' not in encoding.environ | and 'LANGUAGE' not in encoding.environ | ||||
| and 'LC_ALL' not in encoding.environ | and 'LC_ALL' not in encoding.environ | ||||
| and 'LC_MESSAGES' not in encoding.environ | and 'LC_MESSAGES' not in encoding.environ | ||||
| and 'LANG' not in encoding.environ): | and 'LANG' not in encoding.environ): | ||||
| # Try to detect UI language by "User Interface Language Management" API | # Try to detect UI language by "User Interface Language Management" API | ||||
| # if no locale variables are set. Note that locale.getdefaultlocale() | # if no locale variables are set. Note that locale.getdefaultlocale() | ||||
| # uses GetLocaleInfo(), which may be different from UI language. | # uses GetLocaleInfo(), which may be different from UI language. | ||||
| # (See http://msdn.microsoft.com/en-us/library/dd374098(v=VS.85).aspx ) | # (See http://msdn.microsoft.com/en-us/library/dd374098(v=VS.85).aspx ) | ||||
| if fn == skip and statmod.S_ISDIR(st.st_mode): | if fn == skip and statmod.S_ISDIR(st.st_mode): | ||||
| return [] | return [] | ||||
| if stat: | if stat: | ||||
| result.append((fn, _mode_to_kind(st.st_mode), st)) | result.append((fn, _mode_to_kind(st.st_mode), st)) | ||||
| else: | else: | ||||
| result.append((fn, _mode_to_kind(st.st_mode))) | result.append((fn, _mode_to_kind(st.st_mode))) | ||||
| return result | return result | ||||
| if pycompat.osname != 'nt': | if not pycompat.iswindows: | ||||
| posixfile = open | posixfile = open | ||||
| _SCM_RIGHTS = 0x01 | _SCM_RIGHTS = 0x01 | ||||
| _socklen_t = ctypes.c_uint | _socklen_t = ctypes.c_uint | ||||
| if pycompat.sysplatform.startswith('linux'): | if pycompat.sysplatform.startswith('linux'): | ||||
| # socket.h says "the type should be socklen_t but the definition of | # socket.h says "the type should be socklen_t but the definition of | ||||
| # the kernel is incompatible with this." | # the kernel is incompatible with this." | ||||
| import os | import os | ||||
| from . import ( | from . import ( | ||||
| encoding, | encoding, | ||||
| pycompat, | pycompat, | ||||
| util, | util, | ||||
| ) | ) | ||||
| if pycompat.osname == 'nt': | if pycompat.iswindows: | ||||
| from . import scmwindows as scmplatform | from . import scmwindows as scmplatform | ||||
| else: | else: | ||||
| from . import scmposix as scmplatform | from . import scmposix as scmplatform | ||||
| fallbackpager = scmplatform.fallbackpager | fallbackpager = scmplatform.fallbackpager | ||||
| systemrcpath = scmplatform.systemrcpath | systemrcpath = scmplatform.systemrcpath | ||||
| userrcpath = scmplatform.userrcpath | userrcpath = scmplatform.userrcpath | ||||
| pycompat, | pycompat, | ||||
| revsetlang, | revsetlang, | ||||
| similar, | similar, | ||||
| url, | url, | ||||
| util, | util, | ||||
| vfs, | vfs, | ||||
| ) | ) | ||||
| if pycompat.osname == 'nt': | if pycompat.iswindows: | ||||
| from . import scmwindows as scmplatform | from . import scmwindows as scmplatform | ||||
| else: | else: | ||||
| from . import scmposix as scmplatform | from . import scmposix as scmplatform | ||||
| termsize = scmplatform.termsize | termsize = scmplatform.termsize | ||||
| class status(tuple): | class status(tuple): | ||||
| '''Named tuple with a list of files per status. The 'deleted', 'unknown' | '''Named tuple with a list of files per status. The 'deleted', 'unknown' | ||||
| ui.warn(_("warning: %s\n") % msg) | ui.warn(_("warning: %s\n") % msg) | ||||
| def checkportabilityalert(ui): | def checkportabilityalert(ui): | ||||
| '''check if the user's config requests nothing, a warning, or abort for | '''check if the user's config requests nothing, a warning, or abort for | ||||
| non-portable filenames''' | non-portable filenames''' | ||||
| val = ui.config('ui', 'portablefilenames') | val = ui.config('ui', 'portablefilenames') | ||||
| lval = val.lower() | lval = val.lower() | ||||
| bval = util.parsebool(val) | bval = util.parsebool(val) | ||||
| abort = pycompat.osname == 'nt' or lval == 'abort' | abort = pycompat.iswindows or lval == 'abort' | ||||
| warn = bval or lval == 'warn' | warn = bval or lval == 'warn' | ||||
| if bval is None and not (warn or abort or lval == 'ignore'): | if bval is None and not (warn or abort or lval == 'ignore'): | ||||
| raise error.ConfigError( | raise error.ConfigError( | ||||
| _("ui.portablefilenames value is invalid ('%s')") % val) | _("ui.portablefilenames value is invalid ('%s')") % val) | ||||
| return abort, warn | return abort, warn | ||||
| class casecollisionauditor(object): | class casecollisionauditor(object): | ||||
| def __init__(self, ui, abort, dirstate): | def __init__(self, ui, abort, dirstate): | ||||
| 'use of legacy, less secure protocols when ' | 'use of legacy, less secure protocols when ' | ||||
| 'communicating with this server)\n') % | 'communicating with this server)\n') % | ||||
| serverhostname) | serverhostname) | ||||
| ui.warn(_( | ui.warn(_( | ||||
| '(see https://mercurial-scm.org/wiki/SecureConnections ' | '(see https://mercurial-scm.org/wiki/SecureConnections ' | ||||
| 'for more info)\n')) | 'for more info)\n')) | ||||
| elif (e.reason == 'CERTIFICATE_VERIFY_FAILED' and | elif (e.reason == 'CERTIFICATE_VERIFY_FAILED' and | ||||
| pycompat.osname == 'nt'): | pycompat.iswindows): | ||||
| ui.warn(_('(the full certificate chain may not be available ' | ui.warn(_('(the full certificate chain may not be available ' | ||||
| 'locally; see "hg help debugssl")\n')) | 'locally; see "hg help debugssl")\n')) | ||||
| raise | raise | ||||
| # check if wrap_socket failed silently because socket had been | # check if wrap_socket failed silently because socket had been | ||||
| # closed | # closed | ||||
| # - see http://bugs.python.org/issue13721 | # - see http://bugs.python.org/issue13721 | ||||
| except (ImportError, AttributeError): | except (ImportError, AttributeError): | ||||
| pass | pass | ||||
| # On Windows, only the modern ssl module is capable of loading the system | # On Windows, only the modern ssl module is capable of loading the system | ||||
| # CA certificates. If we're not capable of doing that, emit a warning | # CA certificates. If we're not capable of doing that, emit a warning | ||||
| # because we'll get a certificate verification error later and the lack | # because we'll get a certificate verification error later and the lack | ||||
| # of loaded CA certificates will be the reason why. | # of loaded CA certificates will be the reason why. | ||||
| # Assertion: this code is only called if certificates are being verified. | # Assertion: this code is only called if certificates are being verified. | ||||
| if pycompat.osname == 'nt': | if pycompat.iswindows: | ||||
| if not _canloaddefaultcerts: | if not _canloaddefaultcerts: | ||||
| ui.warn(_('(unable to load Windows CA certificates; see ' | ui.warn(_('(unable to load Windows CA certificates; see ' | ||||
| 'https://mercurial-scm.org/wiki/SecureConnections for ' | 'https://mercurial-scm.org/wiki/SecureConnections for ' | ||||
| 'how to configure Mercurial to avoid this message)\n')) | 'how to configure Mercurial to avoid this message)\n')) | ||||
| return None | return None | ||||
| # Apple's OpenSSL has patches that allow a specially constructed certificate | # Apple's OpenSSL has patches that allow a specially constructed certificate | ||||
| ui.warn(_('(unable to load CA certificates; see ' | ui.warn(_('(unable to load CA certificates; see ' | ||||
| 'https://mercurial-scm.org/wiki/SecureConnections for ' | 'https://mercurial-scm.org/wiki/SecureConnections for ' | ||||
| 'how to configure Mercurial to avoid this message)\n')) | 'how to configure Mercurial to avoid this message)\n')) | ||||
| return None | return None | ||||
| # / is writable on Windows. Out of an abundance of caution make sure | # / is writable on Windows. Out of an abundance of caution make sure | ||||
| # we're not on Windows because paths from _systemcacerts could be installed | # we're not on Windows because paths from _systemcacerts could be installed | ||||
| # by non-admin users. | # by non-admin users. | ||||
| assert pycompat.osname != 'nt' | assert not pycompat.iswindows | ||||
| # Try to find CA certificates in well-known locations. We print a warning | # Try to find CA certificates in well-known locations. We print a warning | ||||
| # when using a found file because we don't want too much silent magic | # when using a found file because we don't want too much silent magic | ||||
| # for security settings. The expectation is that proper Mercurial | # for security settings. The expectation is that proper Mercurial | ||||
| # installs will have the CA certs path defined at install time and the | # installs will have the CA certs path defined at install time and the | ||||
| # installer/packager will make an appropriate decision on the user's | # installer/packager will make an appropriate decision on the user's | ||||
| # behalf. We only get here and perform this setting as a feature of | # behalf. We only get here and perform this setting as a feature of | ||||
| # last resort. | # last resort. | ||||
| self._gitexecutable = 'git' | self._gitexecutable = 'git' | ||||
| out, err = self._gitnodir(['--version']) | out, err = self._gitnodir(['--version']) | ||||
| except OSError as e: | except OSError as e: | ||||
| genericerror = _("error executing git for subrepo '%s': %s") | genericerror = _("error executing git for subrepo '%s': %s") | ||||
| notfoundhint = _("check git is installed and in your PATH") | notfoundhint = _("check git is installed and in your PATH") | ||||
| if e.errno != errno.ENOENT: | if e.errno != errno.ENOENT: | ||||
| raise error.Abort(genericerror % ( | raise error.Abort(genericerror % ( | ||||
| self._path, encoding.strtolocal(e.strerror))) | self._path, encoding.strtolocal(e.strerror))) | ||||
| elif pycompat.osname == 'nt': | elif pycompat.iswindows: | ||||
| try: | try: | ||||
| self._gitexecutable = 'git.cmd' | self._gitexecutable = 'git.cmd' | ||||
| out, err = self._gitnodir(['--version']) | out, err = self._gitnodir(['--version']) | ||||
| except OSError as e2: | except OSError as e2: | ||||
| if e2.errno == errno.ENOENT: | if e2.errno == errno.ENOENT: | ||||
| raise error.Abort(_("couldn't find 'git' or 'git.cmd'" | raise error.Abort(_("couldn't find 'git' or 'git.cmd'" | ||||
| " for subrepo '%s'") % self._path, | " for subrepo '%s'") % self._path, | ||||
| hint=notfoundhint) | hint=notfoundhint) | ||||
| # Save ourselves some work. | # Save ourselves some work. | ||||
| return False | return False | ||||
| # If the command doesn't contain any of these characters, we | # If the command doesn't contain any of these characters, we | ||||
| # assume it's a binary and exec it directly. This means for | # assume it's a binary and exec it directly. This means for | ||||
| # simple pager command configurations, we can degrade | # simple pager command configurations, we can degrade | ||||
| # gracefully and tell the user about their broken pager. | # gracefully and tell the user about their broken pager. | ||||
| shell = any(c in command for c in "|&;<>()$`\\\"' \t\n*?[#~=%") | shell = any(c in command for c in "|&;<>()$`\\\"' \t\n*?[#~=%") | ||||
| if pycompat.osname == 'nt' and not shell: | if pycompat.iswindows and not shell: | ||||
| # Window's built-in `more` cannot be invoked with shell=False, but | # Window's built-in `more` cannot be invoked with shell=False, but | ||||
| # its `more.com` can. Hide this implementation detail from the | # its `more.com` can. Hide this implementation detail from the | ||||
| # user so we can also get sane bad PAGER behavior. MSYS has | # user so we can also get sane bad PAGER behavior. MSYS has | ||||
| # `more.exe`, so do a cmd.exe style resolution of the executable to | # `more.exe`, so do a cmd.exe style resolution of the executable to | ||||
| # determine which one to use. | # determine which one to use. | ||||
| fullcmd = util.findexe(command) | fullcmd = util.findexe(command) | ||||
| if not fullcmd: | if not fullcmd: | ||||
| self.warn(_("missing pager command '%s', skipping pager\n") | self.warn(_("missing pager command '%s', skipping pager\n") | ||||
| return False | return False | ||||
| # glibc determines buffering on first write to stdout - if we replace a TTY | # glibc determines buffering on first write to stdout - if we replace a TTY | ||||
| # destined stdout with a pipe destined stdout (e.g. pager), we want line | # destined stdout with a pipe destined stdout (e.g. pager), we want line | ||||
| # buffering | # buffering | ||||
| if isatty(stdout): | if isatty(stdout): | ||||
| stdout = os.fdopen(stdout.fileno(), pycompat.sysstr('wb'), 1) | stdout = os.fdopen(stdout.fileno(), pycompat.sysstr('wb'), 1) | ||||
| if pycompat.osname == 'nt': | if pycompat.iswindows: | ||||
| from . import windows as platform | from . import windows as platform | ||||
| stdout = platform.winstdout(stdout) | stdout = platform.winstdout(stdout) | ||||
| else: | else: | ||||
| from . import posix as platform | from . import posix as platform | ||||
| _ = i18n._ | _ = i18n._ | ||||
| bindunixsocket = platform.bindunixsocket | bindunixsocket = platform.bindunixsocket | ||||
| if base and base.lower() in _winreservednames: | if base and base.lower() in _winreservednames: | ||||
| return _("filename contains '%s', which is reserved " | return _("filename contains '%s', which is reserved " | ||||
| "on Windows") % base | "on Windows") % base | ||||
| t = n[-1:] | t = n[-1:] | ||||
| if t in '. ' and n not in '..': | if t in '. ' and n not in '..': | ||||
| return _("filename ends with '%s', which is not allowed " | return _("filename ends with '%s', which is not allowed " | ||||
| "on Windows") % t | "on Windows") % t | ||||
| if pycompat.osname == 'nt': | if pycompat.iswindows: | ||||
| checkosfilename = checkwinfilename | checkosfilename = checkwinfilename | ||||
| timer = time.clock | timer = time.clock | ||||
| else: | else: | ||||
| checkosfilename = platform.checkosfilename | checkosfilename = platform.checkosfilename | ||||
| timer = time.time | timer = time.time | ||||
| if safehasattr(time, "perf_counter"): | if safehasattr(time, "perf_counter"): | ||||
| timer = time.perf_counter | timer = time.perf_counter | ||||
| return False | return False | ||||
| elif getattr(osutil, 'isgui', None): | elif getattr(osutil, 'isgui', None): | ||||
| # check if a CoreGraphics session is available | # check if a CoreGraphics session is available | ||||
| return osutil.isgui() | return osutil.isgui() | ||||
| else: | else: | ||||
| # pure build; use a safe default | # pure build; use a safe default | ||||
| return True | return True | ||||
| else: | else: | ||||
| return pycompat.osname == "nt" or encoding.environ.get("DISPLAY") | return pycompat.iswindows or encoding.environ.get("DISPLAY") | ||||
| def mktempcopy(name, emptyok=False, createmode=None): | def mktempcopy(name, emptyok=False, createmode=None): | ||||
| """Create a temporary file with the same contents from name | """Create a temporary file with the same contents from name | ||||
| The permission bits are copied from the original file. | The permission bits are copied from the original file. | ||||
| If the temporary file is going to be truncated immediately, you | If the temporary file is going to be truncated immediately, you | ||||
| can use emptyok=True as an optimization. | can use emptyok=True as an optimization. | ||||
| def __init__(self, ui, expectedcount=-1): | def __init__(self, ui, expectedcount=-1): | ||||
| self._running = False | self._running = False | ||||
| self._entered = False | self._entered = False | ||||
| self._threads = [] | self._threads = [] | ||||
| self._threadexception = None | self._threadexception = None | ||||
| # Only Windows/NTFS has slow file closing. So only enable by default | # Only Windows/NTFS has slow file closing. So only enable by default | ||||
| # on that platform. But allow to be enabled elsewhere for testing. | # on that platform. But allow to be enabled elsewhere for testing. | ||||
| defaultenabled = pycompat.osname == 'nt' | defaultenabled = pycompat.iswindows | ||||
| enabled = ui.configbool('worker', 'backgroundclose', defaultenabled) | enabled = ui.configbool('worker', 'backgroundclose', defaultenabled) | ||||
| if not enabled: | if not enabled: | ||||
| return | return | ||||
| # There is overhead to starting and stopping the background threads. | # There is overhead to starting and stopping the background threads. | ||||
| # Don't do background processing unless the file count is large enough | # Don't do background processing unless the file count is large enough | ||||
| # to justify it. | # to justify it. | ||||
| os.spawnv | os.spawnv | ||||
| returns None if the process was stopped instead of exiting''' | returns None if the process was stopped instead of exiting''' | ||||
| if os.WIFEXITED(code): | if os.WIFEXITED(code): | ||||
| return os.WEXITSTATUS(code) | return os.WEXITSTATUS(code) | ||||
| elif os.WIFSIGNALED(code): | elif os.WIFSIGNALED(code): | ||||
| return -os.WTERMSIG(code) | return -os.WTERMSIG(code) | ||||
| if pycompat.osname != 'nt': | if not pycompat.iswindows: | ||||
| _platformworker = _posixworker | _platformworker = _posixworker | ||||
| _exitstatus = _posixexitstatus | _exitstatus = _posixexitstatus | ||||
| def partition(lst, nslices): | def partition(lst, nslices): | ||||
| '''partition a list into N slices of roughly equal size | '''partition a list into N slices of roughly equal size | ||||
| The current strategy takes every Nth element from the input. If | The current strategy takes every Nth element from the input. If | ||||
| we ever write workers that need to preserve grouping in input | we ever write workers that need to preserve grouping in input | ||||