2018-03-09 19:25:11 +01:00
|
|
|
"""Various utilities that are handy."""
|
2010-02-04 16:21:36 +01:00
|
|
|
|
2012-04-11 16:57:25 +02:00
|
|
|
import codecs
|
2010-02-04 16:21:36 +01:00
|
|
|
import re
|
2010-05-14 19:38:26 +02:00
|
|
|
import os
|
2012-02-17 03:49:02 +01:00
|
|
|
import os.path
|
|
|
|
import subprocess
|
|
|
|
import sys
|
2012-05-10 20:46:08 +02:00
|
|
|
|
2010-02-04 16:21:36 +01:00
|
|
|
|
2018-03-09 19:25:11 +01:00
|
|
|
def getAllSourceFiles(arr=None, prefix="."):
|
2010-09-03 17:58:53 +02:00
|
|
|
if arr is None:
|
|
|
|
arr = []
|
2017-01-12 22:57:46 +01:00
|
|
|
|
2018-03-09 19:25:11 +01:00
|
|
|
if not os.path.isdir(prefix):
|
2012-10-15 08:37:46 +02:00
|
|
|
# assume a file
|
2018-03-09 19:25:11 +01:00
|
|
|
arr.append(prefix)
|
2012-10-15 08:37:46 +02:00
|
|
|
return arr
|
2017-01-12 22:57:46 +01:00
|
|
|
|
2018-03-09 19:25:11 +01:00
|
|
|
for x in os.listdir(prefix):
|
2018-03-26 17:25:04 +02:00
|
|
|
if (x.startswith(".") or x.startswith("pcre-") or x.startswith("32bit")
|
|
|
|
or x.startswith("mongodb-") or x.startswith("debian")
|
|
|
|
or x.startswith("mongo-cxx-driver") or x.startswith("sqlite") or "gotools" in x
|
|
|
|
or x.find("mozjs") != -1):
|
2014-04-23 23:31:32 +02:00
|
|
|
continue
|
2016-08-26 22:55:02 +02:00
|
|
|
|
2017-01-12 22:57:46 +01:00
|
|
|
def isFollowableDir(prefix, full):
|
|
|
|
if not os.path.isdir(full):
|
|
|
|
return False
|
|
|
|
if not os.path.islink(full):
|
|
|
|
return True
|
|
|
|
# Follow softlinks in the modules directory (e.g: enterprise).
|
|
|
|
if os.path.split(prefix)[1] == "modules":
|
|
|
|
return True
|
2018-03-09 19:25:11 +01:00
|
|
|
return False
|
2017-01-12 22:57:46 +01:00
|
|
|
|
2010-09-03 17:58:53 +02:00
|
|
|
full = prefix + "/" + x
|
2017-01-12 22:57:46 +01:00
|
|
|
if isFollowableDir(prefix, full):
|
2018-03-09 19:25:11 +01:00
|
|
|
getAllSourceFiles(arr, full)
|
2010-09-03 17:58:53 +02:00
|
|
|
else:
|
2018-03-09 19:25:11 +01:00
|
|
|
if full.endswith(".cpp") or full.endswith(".h") or full.endswith(".c"):
|
|
|
|
full = full.replace("//", "/")
|
|
|
|
arr.append(full)
|
2010-09-03 17:58:53 +02:00
|
|
|
|
|
|
|
return arr
|
|
|
|
|
|
|
|
|
2010-07-19 21:37:19 +02:00
|
|
|
def getGitBranch():
|
2018-03-09 19:25:11 +01:00
|
|
|
if not os.path.exists(".git") or not os.path.isdir(".git"):
|
2010-07-19 21:37:19 +02:00
|
|
|
return None
|
2010-08-26 20:33:41 +02:00
|
|
|
|
2018-03-09 19:25:11 +01:00
|
|
|
version = open(".git/HEAD", "r").read().strip()
|
|
|
|
if not version.startswith("ref: "):
|
2010-07-19 21:37:19 +02:00
|
|
|
return version
|
2018-03-09 19:25:11 +01:00
|
|
|
version = version.split("/")
|
2018-03-26 17:25:04 +02:00
|
|
|
version = version[len(version) - 1]
|
2010-07-19 21:37:19 +02:00
|
|
|
return version
|
|
|
|
|
2018-03-09 19:25:11 +01:00
|
|
|
|
|
|
|
def getGitBranchString(prefix="", postfix=""):
|
|
|
|
t = re.compile("[/\\\]").split(os.getcwd())
|
2018-03-26 17:25:04 +02:00
|
|
|
if len(t) > 2 and t[len(t) - 1] == "mongo":
|
|
|
|
par = t[len(t) - 2]
|
2018-03-09 19:25:11 +01:00
|
|
|
m = re.compile(".*_([vV]\d+\.\d+)$").match(par)
|
2010-07-19 21:37:19 +02:00
|
|
|
if m is not None:
|
|
|
|
return prefix + m.group(1).lower() + postfix
|
|
|
|
if par.find("Nightly") > 0:
|
|
|
|
return ""
|
|
|
|
|
|
|
|
b = getGitBranch()
|
2018-03-09 19:25:11 +01:00
|
|
|
if b is None or b == "master":
|
2010-07-19 21:37:19 +02:00
|
|
|
return ""
|
|
|
|
return prefix + b + postfix
|
|
|
|
|
2018-03-09 19:25:11 +01:00
|
|
|
|
2010-07-19 21:37:19 +02:00
|
|
|
def getGitVersion():
|
2018-03-09 19:25:11 +01:00
|
|
|
if not os.path.exists(".git") or not os.path.isdir(".git"):
|
2010-07-19 21:37:19 +02:00
|
|
|
return "nogitversion"
|
|
|
|
|
2018-03-09 19:25:11 +01:00
|
|
|
version = open(".git/HEAD", "r").read().strip()
|
|
|
|
if not version.startswith("ref: "):
|
2010-07-19 21:37:19 +02:00
|
|
|
return version
|
|
|
|
version = version[5:]
|
|
|
|
f = ".git/" + version
|
2018-03-09 19:25:11 +01:00
|
|
|
if not os.path.exists(f):
|
2010-07-19 21:37:19 +02:00
|
|
|
return version
|
2018-03-09 19:25:11 +01:00
|
|
|
return open(f, "r").read().strip()
|
|
|
|
|
2010-07-19 21:37:19 +02:00
|
|
|
|
2015-05-21 20:15:43 +02:00
|
|
|
def getGitDescribe():
|
|
|
|
with open(os.devnull, "r+") as devnull:
|
2018-03-26 17:25:04 +02:00
|
|
|
proc = subprocess.Popen("git describe", stdout=subprocess.PIPE, stderr=devnull,
|
|
|
|
stdin=devnull, shell=True)
|
2015-05-21 20:15:43 +02:00
|
|
|
return proc.communicate()[0].strip()
|
|
|
|
|
2018-03-09 19:25:11 +01:00
|
|
|
|
|
|
|
def execsys(args):
|
2010-02-04 16:21:36 +01:00
|
|
|
import subprocess
|
2018-03-09 19:25:11 +01:00
|
|
|
if isinstance(args, str):
|
|
|
|
r = re.compile("\s+")
|
|
|
|
args = r.split(args)
|
|
|
|
p = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
2010-02-04 16:21:36 +01:00
|
|
|
r = p.communicate()
|
2018-03-09 19:25:11 +01:00
|
|
|
return r
|
2010-02-04 16:21:36 +01:00
|
|
|
|
2010-05-15 05:37:29 +02:00
|
|
|
|
2012-02-17 03:49:02 +01:00
|
|
|
def which(executable):
|
2018-03-09 19:25:11 +01:00
|
|
|
if sys.platform == "win32":
|
|
|
|
paths = os.environ.get("Path", "").split(";")
|
2012-02-17 03:49:02 +01:00
|
|
|
else:
|
2018-03-09 19:25:11 +01:00
|
|
|
paths = os.environ.get("PATH", "").split(":")
|
2012-02-17 03:49:02 +01:00
|
|
|
|
|
|
|
for path in paths:
|
|
|
|
path = os.path.expandvars(path)
|
|
|
|
path = os.path.expanduser(path)
|
|
|
|
path = os.path.abspath(path)
|
|
|
|
executable_path = os.path.join(path, executable)
|
|
|
|
if os.path.exists(executable_path):
|
|
|
|
return executable_path
|
|
|
|
|
|
|
|
return executable
|
|
|
|
|
2012-05-10 20:46:08 +02:00
|
|
|
|
2012-02-17 03:49:02 +01:00
|
|
|
def find_python(min_version=(2, 5)):
|
2012-03-20 16:45:59 +01:00
|
|
|
try:
|
|
|
|
if sys.version_info >= min_version:
|
|
|
|
return sys.executable
|
|
|
|
except AttributeError:
|
|
|
|
# In case the version of Python is somehow missing sys.version_info or sys.executable.
|
|
|
|
pass
|
|
|
|
|
2018-03-09 19:25:11 +01:00
|
|
|
version = re.compile(r"[Pp]ython ([\d\.]+)", re.MULTILINE)
|
2018-03-26 17:25:04 +02:00
|
|
|
binaries = ("python27", "python2.7", "python26", "python2.6", "python25", "python2.5", "python")
|
2012-02-17 03:49:02 +01:00
|
|
|
for binary in binaries:
|
|
|
|
try:
|
2018-03-26 17:25:04 +02:00
|
|
|
out, err = subprocess.Popen([binary, "-V"], stdout=subprocess.PIPE,
|
|
|
|
stderr=subprocess.PIPE).communicate()
|
2012-02-17 03:49:02 +01:00
|
|
|
for stream in (out, err):
|
|
|
|
match = version.search(stream)
|
|
|
|
if match:
|
2018-03-09 19:25:11 +01:00
|
|
|
versiontuple = tuple(map(int, match.group(1).split(".")))
|
2012-03-20 16:45:59 +01:00
|
|
|
if versiontuple >= min_version:
|
2012-02-17 03:49:02 +01:00
|
|
|
return which(binary)
|
|
|
|
except:
|
|
|
|
pass
|
|
|
|
|
2018-03-26 17:25:04 +02:00
|
|
|
raise Exception("could not find suitable Python (version >= %s)" % ".".join(
|
|
|
|
str(v) for v in min_version))
|
2012-02-23 23:28:59 +01:00
|
|
|
|
2012-02-17 03:49:02 +01:00
|
|
|
|
2012-04-11 16:57:25 +02:00
|
|
|
# unicode is a pain. some strings cannot be unicode()'d
|
|
|
|
# but we want to just preserve the bytes in a human-readable
|
|
|
|
# fashion. this codec error handler will substitute the
|
|
|
|
# repr() of the offending bytes into the decoded string
|
|
|
|
# at the position they occurred
|
|
|
|
def replace_with_repr(unicode_error):
|
|
|
|
offender = unicode_error.object[unicode_error.start:unicode_error.end]
|
|
|
|
return (unicode(repr(offender).strip("'").strip('"')), unicode_error.end)
|
|
|
|
|
2018-03-26 17:25:04 +02:00
|
|
|
|
2018-03-09 19:25:11 +01:00
|
|
|
codecs.register_error("repr", replace_with_repr)
|