##// END OF EJS Templates
testing: stop skipping all Python tests of Rust revlog...
testing: stop skipping all Python tests of Rust revlog This base class was not adapted for the introduction of `InnerRevlog`, which also stopped exposing an `Index` class from `rustext`. As a consequence, `test-rust-ancestor.py` was always skipped (and would have been slightly broken). We remove the skipping conditions from `rustancestorstest`, as they now contradict or repeat those of the base class. Also, `LazyAncestors` objects apparently hold only one reference to the inner revlog (they had previously two references on the Rust index). What matters most of course is the return to `start_count` in these tests, i.e., that there is no memory leak nor double frees. In the Python test, we conflate the presence of the `pyo3_rustext` package with that of `rustext`, as we do not plan to support building one and not the other (we hope to convert fully to PyO3 soon). The skipping is actually done by the base test class.

File last commit:

r53275:e1f0125b default
r53302:cf5b47b8 default
Show More
server.py
237 lines | 7.0 KiB | text/x-python | PythonLexer
Yuya Nishihara
server: move cmdutil.service() to new module (API)...
r30506 # server.py - utility and factory of server
#
Raphaël Gomès
contributor: change mentions of mpm to olivia...
r47575 # Copyright 2005-2007 Olivia Mackall <olivia@selenic.com>
Yuya Nishihara
server: move cmdutil.service() to new module (API)...
r30506 #
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
Matt Harbison
typing: add `from __future__ import annotations` to most files...
r52756 from __future__ import annotations
Yuya Nishihara
server: move cmdutil.service() to new module (API)...
r30506
import os
from .i18n import _
from . import (
Yuya Nishihara
chgserver: make it a core module and drop extension flags...
r30513 chgserver,
Matt Harbison
serve: add support for Mercurial subrepositories...
r32005 cmdutil,
Yuya Nishihara
server: move service table and factory from commandserver...
r30507 commandserver,
Yuya Nishihara
server: move cmdutil.service() to new module (API)...
r30506 error,
Yuya Nishihara
server: move service factory from hgweb
r30509 hgweb,
Augie Fackler
server: use pycompat to get argv
r32530 pycompat,
Yuya Nishihara
server: move cmdutil.service() to new module (API)...
r30506 util,
)
urlutil: extract `url` related code from `util` into the new module...
r47669 from .utils import (
procutil,
urlutil,
)
Augie Fackler
formatting: blacken the codebase...
r43346
Yuya Nishihara
procutil: bulk-replace util.std* to point to new module
r37137
Augie Fackler
formatting: blacken the codebase...
r43346 def runservice(
opts,
parentfn=None,
initfn=None,
runfn=None,
logfile=None,
runargs=None,
appendpid=False,
):
Yuya Nishihara
server: move cmdutil.service() to new module (API)...
r30506 '''Run a command as a service.'''
Matt Harbison
server: refactor 'daemon_postexec' instructions into a dictionary
r37232 postexecargs = {}
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if opts[b'daemon_postexec']:
for inst in opts[b'daemon_postexec']:
if inst.startswith(b'unlink:'):
postexecargs[b'unlink'] = inst[7:]
elif inst.startswith(b'chdir:'):
postexecargs[b'chdir'] = inst[6:]
elif inst != b'none':
Augie Fackler
formatting: blacken the codebase...
r43346 raise error.Abort(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b'invalid value for --daemon-postexec: %s') % inst
Augie Fackler
formatting: blacken the codebase...
r43346 )
Matt Harbison
server: refactor 'daemon_postexec' instructions into a dictionary
r37232
Matt Harbison
server: add an error feedback mechanism for when the daemon fails to launch...
r37229 # When daemonized on Windows, redirect stdout/stderr to the lockfile (which
# gets cleaned up after the child is up and running), so that the parent can
# read and print the error if this child dies early. See 594dd384803c. On
# other platforms, the child can write to the parent's stdio directly, until
# it is redirected prior to runfn().
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if pycompat.iswindows and opts[b'daemon_postexec']:
if b'unlink' in postexecargs and os.path.exists(
postexecargs[b'unlink']
):
Matt Harbison
server: refactor 'daemon_postexec' instructions into a dictionary
r37232 procutil.stdout.flush()
procutil.stderr.flush()
Matt Harbison
server: add an error feedback mechanism for when the daemon fails to launch...
r37229
Augie Fackler
formatting: blacken the codebase...
r43346 fd = os.open(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 postexecargs[b'unlink'], os.O_WRONLY | os.O_APPEND | os.O_BINARY
Augie Fackler
formatting: blacken the codebase...
r43346 )
Matt Harbison
server: refactor 'daemon_postexec' instructions into a dictionary
r37232 try:
Matt Harbison
server: minor code cleanup...
r37233 os.dup2(fd, procutil.stdout.fileno())
os.dup2(fd, procutil.stderr.fileno())
Matt Harbison
server: refactor 'daemon_postexec' instructions into a dictionary
r37232 finally:
os.close(fd)
Matt Harbison
server: add an error feedback mechanism for when the daemon fails to launch...
r37229
Yuya Nishihara
server: move cmdutil.service() to new module (API)...
r30506 def writepid(pid):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if opts[b'pid_file']:
Yuya Nishihara
server: move cmdutil.service() to new module (API)...
r30506 if appendpid:
Matt Harbison
server: stop using the `pycompat.open()` shim
r53275 mode = 'ab'
Yuya Nishihara
server: move cmdutil.service() to new module (API)...
r30506 else:
Matt Harbison
server: stop using the `pycompat.open()` shim
r53275 mode = 'wb'
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 fp = open(opts[b'pid_file'], mode)
fp.write(b'%d\n' % pid)
Yuya Nishihara
server: move cmdutil.service() to new module (API)...
r30506 fp.close()
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if opts[b'daemon'] and not opts[b'daemon_postexec']:
Yuya Nishihara
server: move cmdutil.service() to new module (API)...
r30506 # Signal child process startup with file removal
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 lockfd, lockpath = pycompat.mkstemp(prefix=b'hg-service-')
Yuya Nishihara
server: move cmdutil.service() to new module (API)...
r30506 os.close(lockfd)
try:
if not runargs:
Yuya Nishihara
procutil: bulk-replace function calls to point to new module
r37138 runargs = procutil.hgcmd() + pycompat.sysargv[1:]
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 runargs.append(b'--daemon-postexec=unlink:%s' % lockpath)
Yuya Nishihara
server: move cmdutil.service() to new module (API)...
r30506 # Don't pass --cwd to the child process, because we've already
# changed directory.
Manuel Jacob
py3: replace `pycompat.xrange` by `range`
r50179 for i in range(1, len(runargs)):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if runargs[i].startswith(b'--cwd='):
Yuya Nishihara
server: move cmdutil.service() to new module (API)...
r30506 del runargs[i]
break
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 elif runargs[i].startswith(b'--cwd'):
Augie Fackler
formatting: blacken the codebase...
r43346 del runargs[i : i + 2]
Yuya Nishihara
server: move cmdutil.service() to new module (API)...
r30506 break
Augie Fackler
formatting: blacken the codebase...
r43346
Yuya Nishihara
server: move cmdutil.service() to new module (API)...
r30506 def condfn():
return not os.path.exists(lockpath)
Augie Fackler
formatting: blacken the codebase...
r43346
Yuya Nishihara
procutil: bulk-replace function calls to point to new module
r37138 pid = procutil.rundetached(runargs, condfn)
Yuya Nishihara
server: move cmdutil.service() to new module (API)...
r30506 if pid < 0:
Matt Harbison
server: add an error feedback mechanism for when the daemon fails to launch...
r37229 # If the daemonized process managed to write out an error msg,
# report it.
if pycompat.iswindows and os.path.exists(lockpath):
Matt Harbison
server: stop using the `pycompat.open()` shim
r53275 with open(lockpath, 'rb') as log:
Matt Harbison
server: add an error feedback mechanism for when the daemon fails to launch...
r37229 for line in log:
procutil.stderr.write(line)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 raise error.Abort(_(b'child process failed to start'))
Yuya Nishihara
server: move cmdutil.service() to new module (API)...
r30506 writepid(pid)
finally:
Ryan McElroy
server: use tryunlink
r31548 util.tryunlink(lockpath)
Yuya Nishihara
server: move cmdutil.service() to new module (API)...
r30506 if parentfn:
return parentfn(pid)
else:
return
if initfn:
initfn()
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if not opts[b'daemon']:
Yuya Nishihara
procutil: bulk-replace function calls to point to new module
r37138 writepid(procutil.getpid())
Yuya Nishihara
server: move cmdutil.service() to new module (API)...
r30506
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if opts[b'daemon_postexec']:
Yuya Nishihara
server: move cmdutil.service() to new module (API)...
r30506 try:
os.setsid()
except AttributeError:
pass
Matt Harbison
server: add an error feedback mechanism for when the daemon fails to launch...
r37229
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if b'chdir' in postexecargs:
os.chdir(postexecargs[b'chdir'])
Yuya Nishihara
procutil: bulk-replace function calls to point to new module
r37138 procutil.hidewindow()
Yuya Nishihara
procutil: bulk-replace util.std* to point to new module
r37137 procutil.stdout.flush()
procutil.stderr.flush()
Yuya Nishihara
server: move cmdutil.service() to new module (API)...
r30506
nullfd = os.open(os.devnull, os.O_RDWR)
logfilefd = nullfd
if logfile:
Augie Fackler
formatting: blacken the codebase...
r43346 logfilefd = os.open(
logfile, os.O_RDWR | os.O_CREAT | os.O_APPEND, 0o666
)
Matt Harbison
server: minor code cleanup...
r37233 os.dup2(nullfd, procutil.stdin.fileno())
os.dup2(logfilefd, procutil.stdout.fileno())
os.dup2(logfilefd, procutil.stderr.fileno())
Augie Fackler
formatting: blacken the codebase...
r43346 stdio = (
procutil.stdin.fileno(),
procutil.stdout.fileno(),
procutil.stderr.fileno(),
)
Matt Harbison
server: minor code cleanup...
r37233 if nullfd not in stdio:
Yuya Nishihara
server: move cmdutil.service() to new module (API)...
r30506 os.close(nullfd)
Matt Harbison
server: minor code cleanup...
r37233 if logfile and logfilefd not in stdio:
Yuya Nishihara
server: move cmdutil.service() to new module (API)...
r30506 os.close(logfilefd)
Matt Harbison
server: add an error feedback mechanism for when the daemon fails to launch...
r37229 # Only unlink after redirecting stdout/stderr, so Windows doesn't
# complain about a sharing violation.
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if b'unlink' in postexecargs:
os.unlink(postexecargs[b'unlink'])
Matt Harbison
server: add an error feedback mechanism for when the daemon fails to launch...
r37229
Yuya Nishihara
server: move cmdutil.service() to new module (API)...
r30506 if runfn:
return runfn()
Yuya Nishihara
server: move service table and factory from commandserver...
r30507
Augie Fackler
formatting: blacken the codebase...
r43346
Yuya Nishihara
server: move service table and factory from commandserver...
r30507 _cmdservicemap = {
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'chgunix': chgserver.chgunixservice,
b'pipe': commandserver.pipeservice,
b'unix': commandserver.unixforkingservice,
Yuya Nishihara
server: move service table and factory from commandserver...
r30507 }
Augie Fackler
formatting: blacken the codebase...
r43346
Yuya Nishihara
server: add public function to select either cmdserver or hgweb
r30510 def _createcmdservice(ui, repo, opts):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 mode = opts[b'cmdserver']
Yuya Nishihara
server: move service table and factory from commandserver...
r30507 try:
Yuya Nishihara
commandserver: enable logging when server process started...
r40858 servicefn = _cmdservicemap[mode]
Yuya Nishihara
server: move service table and factory from commandserver...
r30507 except KeyError:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 raise error.Abort(_(b'unknown mode %s') % mode)
Yuya Nishihara
commandserver: install logger to record server events through canonical API...
r40859 commandserver.setuplogging(ui, repo)
Yuya Nishihara
commandserver: enable logging when server process started...
r40858 return servicefn(ui, repo, opts)
Yuya Nishihara
server: move service factory from hgweb
r30509
Augie Fackler
formatting: blacken the codebase...
r43346
Yuya Nishihara
server: add public function to select either cmdserver or hgweb
r30510 def _createhgwebservice(ui, repo, opts):
Yuya Nishihara
server: move service factory from hgweb
r30509 # this way we can check if something was given in the command-line
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if opts.get(b'port'):
urlutil: extract `url` related code from `util` into the new module...
r47669 opts[b'port'] = urlutil.getport(opts.get(b'port'))
Yuya Nishihara
server: move service factory from hgweb
r30509
Martin von Zweigbergk
cleanup: use set literals...
r32291 alluis = {ui}
Yuya Nishihara
server: move service factory from hgweb
r30509 if repo:
baseui = repo.baseui
alluis.update([repo.baseui, repo.ui])
else:
baseui = ui
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 webconf = opts.get(b'web_conf') or opts.get(b'webdir_conf')
Yuya Nishihara
server: move service factory from hgweb
r30509 if webconf:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if opts.get(b'subrepos'):
raise error.Abort(_(b'--web-conf cannot be used with --subrepos'))
Matt Harbison
serve: add support for Mercurial subrepositories...
r32005
Yuya Nishihara
server: move service factory from hgweb
r30509 # load server settings (e.g. web.port) to "copied" ui, which allows
# hgwebdir to reload webconf cleanly
servui = ui.copy()
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 servui.readconfig(webconf, sections=[b'web'])
Yuya Nishihara
server: move service factory from hgweb
r30509 alluis.add(servui)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 elif opts.get(b'subrepos'):
Matt Harbison
serve: add support for Mercurial subrepositories...
r32005 servui = ui
# If repo is None, hgweb.createapp() already raises a proper abort
# message as long as webconf is None.
if repo:
webconf = dict()
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 cmdutil.addwebdirpath(repo, b"", webconf)
Yuya Nishihara
server: move service factory from hgweb
r30509 else:
servui = ui
Augie Fackler
formatting: blacken the codebase...
r43346 optlist = (
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b"name templates style address port prefix ipv6"
b" accesslog errorlog certificate encoding"
Augie Fackler
formatting: blacken the codebase...
r43346 )
Yuya Nishihara
server: move service factory from hgweb
r30509 for o in optlist.split():
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 val = opts.get(o, b'')
if val in (None, b''): # should check against default options instead
Yuya Nishihara
server: move service factory from hgweb
r30509 continue
for u in alluis:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 u.setconfig(b"web", o, val, b'serve')
Yuya Nishihara
server: move service factory from hgweb
r30509
app = hgweb.createapp(baseui, repo, webconf)
return hgweb.httpservice(servui, app, opts)
Yuya Nishihara
server: add public function to select either cmdserver or hgweb
r30510
Augie Fackler
formatting: blacken the codebase...
r43346
Yuya Nishihara
server: add public function to select either cmdserver or hgweb
r30510 def createservice(ui, repo, opts):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if opts[b"cmdserver"]:
Yuya Nishihara
server: add public function to select either cmdserver or hgweb
r30510 return _createcmdservice(ui, repo, opts)
else:
return _createhgwebservice(ui, repo, opts)