sapling/edenscm/mercurial/entrypoint.py

85 lines
2.8 KiB
Python
Raw Normal View History

#!/usr/bin/env python
hg: move hg entrypoint to the mercurial dir Summary: We want to have two possible Python entry points for Mercurial: - pure-python one (`hg/hg` script, the one which is renamed into `hg.real` during FB installation) - the one to be called from a Rust binary The reason we can't reuse the `hg/hg` to be called form the Rust binary is because this script will eventually not exist. We also need something in the known location, so we chose to put `entrypoint.py` into `mercurial/`. This means that both the `hg` script and the `hg.rust` binary need to be able to find the `mercurial/` directory on the system. Traditionally, `hg` contained a `LIBDIR@` string, which was replaced with the parent directory of a `mercurial/` dir at install time. Thus we could install Mercurial in non-standard locations if we needed to. We keep this functionality for the `hg` script. `mercurial/entrypoint.py` however knows that it lives under `mercurial/` and that `hgext/` and `hgdemandimport/` live alongside `mercurial/`. Thus, the parent dir of `mercurial/` is added as a first item of `sys,path` in `entrypoint.py`. In case `entrypoint.py` is called from a Rust binary, Python import logic also adds the entire `mercurial/` dir to `sys.path`. This is not desired, since we use `absolute_import` and want to only be able to import things as `from mercurial import smth`. A good example is `json`: even with `absolute_import` enabled `import json` loads `mercurial/json.py` if hg is called as a Rust binary. Therefore, we explicitly remove `mercurial/` from `sys.path`. Reviewed By: quark-zju Differential Revision: D9336157 fbshipit-source-id: 22f69e7782d549915c91ef9a0ad0ed29f62a9304
2018-08-17 20:40:01 +03:00
# mercurial - scalable distributed SCM
#
# Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
#
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
from __future__ import absolute_import
import os
import sys
def run(binaryexecution):
hg: move hg entrypoint to the mercurial dir Summary: We want to have two possible Python entry points for Mercurial: - pure-python one (`hg/hg` script, the one which is renamed into `hg.real` during FB installation) - the one to be called from a Rust binary The reason we can't reuse the `hg/hg` to be called form the Rust binary is because this script will eventually not exist. We also need something in the known location, so we chose to put `entrypoint.py` into `mercurial/`. This means that both the `hg` script and the `hg.rust` binary need to be able to find the `mercurial/` directory on the system. Traditionally, `hg` contained a `LIBDIR@` string, which was replaced with the parent directory of a `mercurial/` dir at install time. Thus we could install Mercurial in non-standard locations if we needed to. We keep this functionality for the `hg` script. `mercurial/entrypoint.py` however knows that it lives under `mercurial/` and that `hgext/` and `hgdemandimport/` live alongside `mercurial/`. Thus, the parent dir of `mercurial/` is added as a first item of `sys,path` in `entrypoint.py`. In case `entrypoint.py` is called from a Rust binary, Python import logic also adds the entire `mercurial/` dir to `sys.path`. This is not desired, since we use `absolute_import` and want to only be able to import things as `from mercurial import smth`. A good example is `json`: even with `absolute_import` enabled `import json` loads `mercurial/json.py` if hg is called as a Rust binary. Therefore, we explicitly remove `mercurial/` from `sys.path`. Reviewed By: quark-zju Differential Revision: D9336157 fbshipit-source-id: 22f69e7782d549915c91ef9a0ad0ed29f62a9304
2018-08-17 20:40:01 +03:00
# entrypoint is in mercurial/ dir, while we want 'from mercurial import ...',
# 'from hgext import ...' and 'from hgdemandimport import ...' to work
# so we are adding their parent directory to be the first item of sys.path
# Do not follow symlinks (ex. do not use "realpath"). It breaks buck build.
filedir = os.path.dirname(os.path.abspath(__file__))
libdir = os.path.dirname(os.path.dirname(filedir))
hg: move hg entrypoint to the mercurial dir Summary: We want to have two possible Python entry points for Mercurial: - pure-python one (`hg/hg` script, the one which is renamed into `hg.real` during FB installation) - the one to be called from a Rust binary The reason we can't reuse the `hg/hg` to be called form the Rust binary is because this script will eventually not exist. We also need something in the known location, so we chose to put `entrypoint.py` into `mercurial/`. This means that both the `hg` script and the `hg.rust` binary need to be able to find the `mercurial/` directory on the system. Traditionally, `hg` contained a `LIBDIR@` string, which was replaced with the parent directory of a `mercurial/` dir at install time. Thus we could install Mercurial in non-standard locations if we needed to. We keep this functionality for the `hg` script. `mercurial/entrypoint.py` however knows that it lives under `mercurial/` and that `hgext/` and `hgdemandimport/` live alongside `mercurial/`. Thus, the parent dir of `mercurial/` is added as a first item of `sys,path` in `entrypoint.py`. In case `entrypoint.py` is called from a Rust binary, Python import logic also adds the entire `mercurial/` dir to `sys.path`. This is not desired, since we use `absolute_import` and want to only be able to import things as `from mercurial import smth`. A good example is `json`: even with `absolute_import` enabled `import json` loads `mercurial/json.py` if hg is called as a Rust binary. Therefore, we explicitly remove `mercurial/` from `sys.path`. Reviewed By: quark-zju Differential Revision: D9336157 fbshipit-source-id: 22f69e7782d549915c91ef9a0ad0ed29f62a9304
2018-08-17 20:40:01 +03:00
if sys.path[0] != libdir:
sys.path.insert(0, libdir)
for element in list(sys.path):
if os.path.realpath(filedir) == os.path.realpath(element):
# the directory of entrypoint.py is mercurial/
# and it should not be present in sys.path, as we use absolute_import
sys.path.remove(element)
hg: move hg entrypoint to the mercurial dir Summary: We want to have two possible Python entry points for Mercurial: - pure-python one (`hg/hg` script, the one which is renamed into `hg.real` during FB installation) - the one to be called from a Rust binary The reason we can't reuse the `hg/hg` to be called form the Rust binary is because this script will eventually not exist. We also need something in the known location, so we chose to put `entrypoint.py` into `mercurial/`. This means that both the `hg` script and the `hg.rust` binary need to be able to find the `mercurial/` directory on the system. Traditionally, `hg` contained a `LIBDIR@` string, which was replaced with the parent directory of a `mercurial/` dir at install time. Thus we could install Mercurial in non-standard locations if we needed to. We keep this functionality for the `hg` script. `mercurial/entrypoint.py` however knows that it lives under `mercurial/` and that `hgext/` and `hgdemandimport/` live alongside `mercurial/`. Thus, the parent dir of `mercurial/` is added as a first item of `sys,path` in `entrypoint.py`. In case `entrypoint.py` is called from a Rust binary, Python import logic also adds the entire `mercurial/` dir to `sys.path`. This is not desired, since we use `absolute_import` and want to only be able to import things as `from mercurial import smth`. A good example is `json`: even with `absolute_import` enabled `import json` loads `mercurial/json.py` if hg is called as a Rust binary. Therefore, we explicitly remove `mercurial/` from `sys.path`. Reviewed By: quark-zju Differential Revision: D9336157 fbshipit-source-id: 22f69e7782d549915c91ef9a0ad0ed29f62a9304
2018-08-17 20:40:01 +03:00
from edenscm import hgdemandimport
hgdemandimport.tryenableembedded()
from edenscm.mercurial import encoding
hg: move hg entrypoint to the mercurial dir Summary: We want to have two possible Python entry points for Mercurial: - pure-python one (`hg/hg` script, the one which is renamed into `hg.real` during FB installation) - the one to be called from a Rust binary The reason we can't reuse the `hg/hg` to be called form the Rust binary is because this script will eventually not exist. We also need something in the known location, so we chose to put `entrypoint.py` into `mercurial/`. This means that both the `hg` script and the `hg.rust` binary need to be able to find the `mercurial/` directory on the system. Traditionally, `hg` contained a `LIBDIR@` string, which was replaced with the parent directory of a `mercurial/` dir at install time. Thus we could install Mercurial in non-standard locations if we needed to. We keep this functionality for the `hg` script. `mercurial/entrypoint.py` however knows that it lives under `mercurial/` and that `hgext/` and `hgdemandimport/` live alongside `mercurial/`. Thus, the parent dir of `mercurial/` is added as a first item of `sys,path` in `entrypoint.py`. In case `entrypoint.py` is called from a Rust binary, Python import logic also adds the entire `mercurial/` dir to `sys.path`. This is not desired, since we use `absolute_import` and want to only be able to import things as `from mercurial import smth`. A good example is `json`: even with `absolute_import` enabled `import json` loads `mercurial/json.py` if hg is called as a Rust binary. Therefore, we explicitly remove `mercurial/` from `sys.path`. Reviewed By: quark-zju Differential Revision: D9336157 fbshipit-source-id: 22f69e7782d549915c91ef9a0ad0ed29f62a9304
2018-08-17 20:40:01 +03:00
if encoding.environ.get("HGUNICODEPEDANTRY", False):
try:
reload(sys)
sys.setdefaultencoding("undefined")
except NameError:
pass
# Make available various deps that are either not new enough on the system
# or not provided by the system. These include a newer version of IPython
# for `hg dbsh` and the thrift runtime for the eden extension
from edenscm.mercurial import thirdparty
ipypath = os.path.join(os.path.dirname(thirdparty.__file__), "IPython.zip")
if ipypath not in sys.path and os.path.exists(ipypath):
sys.path.insert(0, ipypath)
from edenscm.mercurial import executionmodel
executionmodel.setbinaryexecution(binaryexecution)
hg: move hg entrypoint to the mercurial dir Summary: We want to have two possible Python entry points for Mercurial: - pure-python one (`hg/hg` script, the one which is renamed into `hg.real` during FB installation) - the one to be called from a Rust binary The reason we can't reuse the `hg/hg` to be called form the Rust binary is because this script will eventually not exist. We also need something in the known location, so we chose to put `entrypoint.py` into `mercurial/`. This means that both the `hg` script and the `hg.rust` binary need to be able to find the `mercurial/` directory on the system. Traditionally, `hg` contained a `LIBDIR@` string, which was replaced with the parent directory of a `mercurial/` dir at install time. Thus we could install Mercurial in non-standard locations if we needed to. We keep this functionality for the `hg` script. `mercurial/entrypoint.py` however knows that it lives under `mercurial/` and that `hgext/` and `hgdemandimport/` live alongside `mercurial/`. Thus, the parent dir of `mercurial/` is added as a first item of `sys,path` in `entrypoint.py`. In case `entrypoint.py` is called from a Rust binary, Python import logic also adds the entire `mercurial/` dir to `sys.path`. This is not desired, since we use `absolute_import` and want to only be able to import things as `from mercurial import smth`. A good example is `json`: even with `absolute_import` enabled `import json` loads `mercurial/json.py` if hg is called as a Rust binary. Therefore, we explicitly remove `mercurial/` from `sys.path`. Reviewed By: quark-zju Differential Revision: D9336157 fbshipit-source-id: 22f69e7782d549915c91ef9a0ad0ed29f62a9304
2018-08-17 20:40:01 +03:00
if (
sys.argv[1:5] == ["serve", "--cmdserver", "chgunix2", "--address"]
hg: move hg entrypoint to the mercurial dir Summary: We want to have two possible Python entry points for Mercurial: - pure-python one (`hg/hg` script, the one which is renamed into `hg.real` during FB installation) - the one to be called from a Rust binary The reason we can't reuse the `hg/hg` to be called form the Rust binary is because this script will eventually not exist. We also need something in the known location, so we chose to put `entrypoint.py` into `mercurial/`. This means that both the `hg` script and the `hg.rust` binary need to be able to find the `mercurial/` directory on the system. Traditionally, `hg` contained a `LIBDIR@` string, which was replaced with the parent directory of a `mercurial/` dir at install time. Thus we could install Mercurial in non-standard locations if we needed to. We keep this functionality for the `hg` script. `mercurial/entrypoint.py` however knows that it lives under `mercurial/` and that `hgext/` and `hgdemandimport/` live alongside `mercurial/`. Thus, the parent dir of `mercurial/` is added as a first item of `sys,path` in `entrypoint.py`. In case `entrypoint.py` is called from a Rust binary, Python import logic also adds the entire `mercurial/` dir to `sys.path`. This is not desired, since we use `absolute_import` and want to only be able to import things as `from mercurial import smth`. A good example is `json`: even with `absolute_import` enabled `import json` loads `mercurial/json.py` if hg is called as a Rust binary. Therefore, we explicitly remove `mercurial/` from `sys.path`. Reviewed By: quark-zju Differential Revision: D9336157 fbshipit-source-id: 22f69e7782d549915c91ef9a0ad0ed29f62a9304
2018-08-17 20:40:01 +03:00
and sys.argv[6:8] == ["--daemon-postexec", "chdir:/"]
and "CHGINTERNALMARK" in encoding.environ
):
# Shortcut path for chg server
from edenscm.mercurial import dispatch
hg: move hg entrypoint to the mercurial dir Summary: We want to have two possible Python entry points for Mercurial: - pure-python one (`hg/hg` script, the one which is renamed into `hg.real` during FB installation) - the one to be called from a Rust binary The reason we can't reuse the `hg/hg` to be called form the Rust binary is because this script will eventually not exist. We also need something in the known location, so we chose to put `entrypoint.py` into `mercurial/`. This means that both the `hg` script and the `hg.rust` binary need to be able to find the `mercurial/` directory on the system. Traditionally, `hg` contained a `LIBDIR@` string, which was replaced with the parent directory of a `mercurial/` dir at install time. Thus we could install Mercurial in non-standard locations if we needed to. We keep this functionality for the `hg` script. `mercurial/entrypoint.py` however knows that it lives under `mercurial/` and that `hgext/` and `hgdemandimport/` live alongside `mercurial/`. Thus, the parent dir of `mercurial/` is added as a first item of `sys,path` in `entrypoint.py`. In case `entrypoint.py` is called from a Rust binary, Python import logic also adds the entire `mercurial/` dir to `sys.path`. This is not desired, since we use `absolute_import` and want to only be able to import things as `from mercurial import smth`. A good example is `json`: even with `absolute_import` enabled `import json` loads `mercurial/json.py` if hg is called as a Rust binary. Therefore, we explicitly remove `mercurial/` from `sys.path`. Reviewed By: quark-zju Differential Revision: D9336157 fbshipit-source-id: 22f69e7782d549915c91ef9a0ad0ed29f62a9304
2018-08-17 20:40:01 +03:00
dispatch.runchgserver()
else:
# Non-chg path
try:
if sys.version_info[0] < 3 or sys.version_info >= (3, 6):
hgdemandimport.enable()
except ImportError:
sys.stderr.write(
"abort: couldn't find mercurial libraries in [%s]\n"
% " ".join(sys.path)
)
sys.stderr.write("(check your install and PYTHONPATH)\n")
sys.exit(-1)
from edenscm.mercurial import dispatch
hg: move hg entrypoint to the mercurial dir Summary: We want to have two possible Python entry points for Mercurial: - pure-python one (`hg/hg` script, the one which is renamed into `hg.real` during FB installation) - the one to be called from a Rust binary The reason we can't reuse the `hg/hg` to be called form the Rust binary is because this script will eventually not exist. We also need something in the known location, so we chose to put `entrypoint.py` into `mercurial/`. This means that both the `hg` script and the `hg.rust` binary need to be able to find the `mercurial/` directory on the system. Traditionally, `hg` contained a `LIBDIR@` string, which was replaced with the parent directory of a `mercurial/` dir at install time. Thus we could install Mercurial in non-standard locations if we needed to. We keep this functionality for the `hg` script. `mercurial/entrypoint.py` however knows that it lives under `mercurial/` and that `hgext/` and `hgdemandimport/` live alongside `mercurial/`. Thus, the parent dir of `mercurial/` is added as a first item of `sys,path` in `entrypoint.py`. In case `entrypoint.py` is called from a Rust binary, Python import logic also adds the entire `mercurial/` dir to `sys.path`. This is not desired, since we use `absolute_import` and want to only be able to import things as `from mercurial import smth`. A good example is `json`: even with `absolute_import` enabled `import json` loads `mercurial/json.py` if hg is called as a Rust binary. Therefore, we explicitly remove `mercurial/` from `sys.path`. Reviewed By: quark-zju Differential Revision: D9336157 fbshipit-source-id: 22f69e7782d549915c91ef9a0ad0ed29f62a9304
2018-08-17 20:40:01 +03:00
dispatch.run()
if __name__ == "__main__":
run(True)