import six
import sys
import hashlib
import base64
class Result(object):
pass
def lazy(func):
result = Result()
def wrapper():
try:
return result._result
except AttributeError:
result._result = func()
return result._result
return wrapper
def pathid(path):
return six.ensure_str(base64.b32encode(hashlib.md5(six.ensure_binary(path)).digest()).lower().strip(b'='))
def listid(items):
return pathid(str(sorted(items)))
def stripext(fname):
return fname[: fname.rfind('.')]
def tobuilddir(fname):
if not fname:
return '$B'
if fname.startswith('$S'):
return fname.replace('$S', '$B', 1)
else:
return fname
def before(s, ss):
p = s.find(ss)
if p == -1:
return s
return s[:p]
def sort_by_keywords(keywords, args):
flat = []
res = {}
cur_key = None
limit = -1
for arg in args:
if arg in keywords:
limit = keywords[arg]
if limit == 0:
res[arg] = True
cur_key = None
limit = -1
else:
cur_key = arg
continue
if limit == 0:
cur_key = None
limit = -1
if cur_key:
if cur_key in res:
res[cur_key].append(arg)
else:
res[cur_key] = [arg]
limit -= 1
else:
flat.append(arg)
return (flat, res)
def get_norm_unit_path(unit, extra=None):
path = strip_roots(unit.path())
if extra:
return '{}/{}'.format(path, extra)
return path
def resolve_common_const(path):
if path.startswith('${ARCADIA_ROOT}'):
return path.replace('${ARCADIA_ROOT}', '$S', 1)
if path.startswith('${ARCADIA_BUILD_ROOT}'):
return path.replace('${ARCADIA_BUILD_ROOT}', '$B', 1)
return path
def resolve_to_abs_path(path, source_root, build_root):
if path.startswith('$S') and source_root is not None:
return path.replace('$S', source_root, 1)
if path.startswith('$B') and build_root is not None:
return path.replace('$B', build_root, 1)
return path
def resolve_to_ymake_path(path):
return resolve_to_abs_path(path, '${ARCADIA_ROOT}', '${ARCADIA_BUILD_ROOT}')
def get(fun, num):
return fun()[num][0]
def make_tuples(arg_list):
def tpl():
for x in arg_list:
yield (x, [])
return list(tpl())
def resolve_includes(unit, src, paths):
return unit.resolve_include([src] + paths) if paths else []
def rootrel_arc_src(src, unit):
if src.startswith('${ARCADIA_ROOT}/'):
return src[16:]
if src.startswith('${ARCADIA_BUILD_ROOT}/'):
return src[22:]
elif src.startswith('${CURDIR}/'):
return unit.path()[3:] + '/' + src[10:]
else:
resolved = unit.resolve_arc_path(src)
if resolved.startswith('$S/'):
return resolved[3:]
return src # leave as is
def skip_build_root(x):
if x.startswith('${ARCADIA_BUILD_ROOT}'):
return x[len('${ARCADIA_BUILD_ROOT}') :].lstrip('/')
return x
def get_interpreter_path():
interpreter_path = [sys.executable]
if 'ymake' in interpreter_path[0]:
interpreter_path.append('--python')
return interpreter_path
def filter_out_by_keyword(test_data, keyword):
def _iterate():
i = 0
while i < len(test_data):
if test_data[i] == keyword:
i += 2
else:
yield test_data[i]
i += 1
return list(_iterate())
def strip_roots(path):
for prefix in ["$B/", "$S/"]:
if path.startswith(prefix):
return path[len(prefix) :]
return path
def to_yesno(x):
return "yes" if x else "no"
def get_no_lint_value(unit):
import ymake
supported_no_lint_values = ('none', 'none_internal', 'ktlint')
no_lint_value = unit.get('_NO_LINT_VALUE')
if no_lint_value and no_lint_value not in supported_no_lint_values:
ymake.report_configure_error('Unsupported value for NO_LINT macro: {}'.format(no_lint_value))
return no_lint_value