hgext/chgserver.py
changeset 28276 b4ceadb2c439
parent 28264 3682e201cce6
child 28277 cdc6319f6a7d
equal deleted inserted replaced
28275:d4cced5885f8 28276:b4ceadb2c439
    28 
    28 
    29 from __future__ import absolute_import
    29 from __future__ import absolute_import
    30 
    30 
    31 import SocketServer
    31 import SocketServer
    32 import errno
    32 import errno
       
    33 import inspect
    33 import os
    34 import os
    34 import re
    35 import re
    35 import signal
    36 import signal
    36 import struct
    37 import struct
       
    38 import sys
    37 import threading
    39 import threading
    38 import time
    40 import time
    39 import traceback
    41 import traceback
    40 
    42 
    41 from mercurial.i18n import _
    43 from mercurial.i18n import _
    44     cmdutil,
    46     cmdutil,
    45     commands,
    47     commands,
    46     commandserver,
    48     commandserver,
    47     dispatch,
    49     dispatch,
    48     error,
    50     error,
       
    51     extensions,
    49     osutil,
    52     osutil,
    50     util,
    53     util,
    51 )
    54 )
    52 
    55 
    53 # Note for extension authors: ONLY specify testedwith = 'internal' for
    56 # Note for extension authors: ONLY specify testedwith = 'internal' for
    94         sectionitems.append(ui.configitems(section))
    97         sectionitems.append(ui.configitems(section))
    95     sectionhash = _hashlist(sectionitems)
    98     sectionhash = _hashlist(sectionitems)
    96     envitems = [(k, v) for k, v in os.environ.iteritems() if _envre.match(k)]
    99     envitems = [(k, v) for k, v in os.environ.iteritems() if _envre.match(k)]
    97     envhash = _hashlist(sorted(envitems))
   100     envhash = _hashlist(sorted(envitems))
    98     return sectionhash[:6] + envhash[:6]
   101     return sectionhash[:6] + envhash[:6]
       
   102 
       
   103 def _getmtimepaths(ui):
       
   104     """get a list of paths that should be checked to detect change
       
   105 
       
   106     The list will include:
       
   107     - extensions (will not cover all files for complex extensions)
       
   108     - mercurial/__version__.py
       
   109     - python binary
       
   110     """
       
   111     modules = [m for n, m in extensions.extensions(ui)]
       
   112     try:
       
   113         from mercurial import __version__
       
   114         modules.append(__version__)
       
   115     except ImportError:
       
   116         pass
       
   117     files = [sys.executable]
       
   118     for m in modules:
       
   119         try:
       
   120             files.append(inspect.getabsfile(m))
       
   121         except TypeError:
       
   122             pass
       
   123     return sorted(set(files))
       
   124 
       
   125 def _mtimehash(paths):
       
   126     """return a quick hash for detecting file changes
       
   127 
       
   128     mtimehash calls stat on given paths and calculate a hash based on size and
       
   129     mtime of each file. mtimehash does not read file content because reading is
       
   130     expensive. therefore it's not 100% reliable for detecting content changes.
       
   131     it's possible to return different hashes for same file contents.
       
   132     it's also possible to return a same hash for different file contents for
       
   133     some carefully crafted situation.
       
   134 
       
   135     for chgserver, it is designed that once mtimehash changes, the server is
       
   136     considered outdated immediately and should no longer provide service.
       
   137     """
       
   138     def trystat(path):
       
   139         try:
       
   140             st = os.stat(path)
       
   141             return (st.st_mtime, st.st_size)
       
   142         except OSError:
       
   143             # could be ENOENT, EPERM etc. not fatal in any case
       
   144             pass
       
   145     return _hashlist(map(trystat, paths))[:12]
    99 
   146 
   100 # copied from hgext/pager.py:uisetup()
   147 # copied from hgext/pager.py:uisetup()
   101 def _setuppagercmd(ui, options, cmd):
   148 def _setuppagercmd(ui, options, cmd):
   102     if not ui.formatted():
   149     if not ui.formatted():
   103         return
   150         return