_common.py 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. import six
  2. import sys
  3. import hashlib
  4. import base64
  5. class Result(object):
  6. pass
  7. def lazy(func):
  8. result = Result()
  9. def wrapper(*args, **kwargs):
  10. try:
  11. return result._result
  12. except AttributeError:
  13. result._result = func(*args, **kwargs)
  14. return result._result
  15. return wrapper
  16. def cache_by_second_arg(func):
  17. result = {}
  18. def wrapper(arg0, arg1, *args, **kwargs):
  19. try:
  20. return result[arg1]
  21. except KeyError:
  22. result[arg1] = func(arg0, arg1, *args, **kwargs)
  23. return result[arg1]
  24. return wrapper
  25. def pathid(path):
  26. return six.ensure_str(base64.b32encode(hashlib.md5(six.ensure_binary(path)).digest()).lower().strip(b'='))
  27. def listid(items):
  28. return pathid(str(sorted(items)))
  29. def sort_uniq(items):
  30. return sorted(set(items))
  31. def stripext(fname):
  32. return fname[: fname.rfind('.')]
  33. def tobuilddir(fname):
  34. if not fname:
  35. return '$B'
  36. if fname.startswith('$S'):
  37. return fname.replace('$S', '$B', 1)
  38. else:
  39. return fname
  40. def before(s, ss):
  41. p = s.find(ss)
  42. if p == -1:
  43. return s
  44. return s[:p]
  45. def sort_by_keywords(keywords, args):
  46. flat = []
  47. res = {}
  48. cur_key = None
  49. limit = -1
  50. for arg in args:
  51. if arg in keywords:
  52. limit = keywords[arg]
  53. if limit == 0:
  54. res[arg] = True
  55. cur_key = None
  56. limit = -1
  57. else:
  58. cur_key = arg
  59. continue
  60. if limit == 0:
  61. cur_key = None
  62. limit = -1
  63. if cur_key:
  64. if cur_key in res:
  65. res[cur_key].append(arg)
  66. else:
  67. res[cur_key] = [arg]
  68. limit -= 1
  69. else:
  70. flat.append(arg)
  71. return (flat, res)
  72. def get_norm_unit_path(unit, extra=None):
  73. path = strip_roots(unit.path())
  74. if extra:
  75. return '{}/{}'.format(path, extra)
  76. return path
  77. def resolve_common_const(path):
  78. if path.startswith('${ARCADIA_ROOT}'):
  79. return path.replace('${ARCADIA_ROOT}', '$S', 1)
  80. if path.startswith('${ARCADIA_BUILD_ROOT}'):
  81. return path.replace('${ARCADIA_BUILD_ROOT}', '$B', 1)
  82. return path
  83. def resolve_to_abs_path(path, source_root, build_root):
  84. if path.startswith('$S') and source_root is not None:
  85. return path.replace('$S', source_root, 1)
  86. if path.startswith('$B') and build_root is not None:
  87. return path.replace('$B', build_root, 1)
  88. return path
  89. def resolve_to_ymake_path(path):
  90. return resolve_to_abs_path(path, '${ARCADIA_ROOT}', '${ARCADIA_BUILD_ROOT}')
  91. def get(fun, num):
  92. return fun()[num][0]
  93. def make_tuples(arg_list):
  94. def tpl():
  95. for x in arg_list:
  96. yield (x, [])
  97. return list(tpl())
  98. def resolve_includes(unit, src, paths):
  99. return unit.resolve_include([src] + paths) if paths else []
  100. def rootrel_arc_src(src, unit):
  101. if src.startswith('${ARCADIA_ROOT}/'):
  102. return src[16:]
  103. if src.startswith('${ARCADIA_BUILD_ROOT}/'):
  104. return src[22:]
  105. elif src.startswith('${CURDIR}/'):
  106. return unit.path()[3:] + '/' + src[10:]
  107. else:
  108. resolved = unit.resolve_arc_path(src)
  109. if resolved.startswith('$S/'):
  110. return resolved[3:]
  111. return src # leave as is
  112. def skip_build_root(x):
  113. if x.startswith('${ARCADIA_BUILD_ROOT}'):
  114. return x[len('${ARCADIA_BUILD_ROOT}') :].lstrip('/')
  115. return x
  116. def get_interpreter_path():
  117. interpreter_path = [sys.executable]
  118. if 'ymake' in interpreter_path[0]:
  119. interpreter_path.append('--python')
  120. return interpreter_path
  121. def filter_out_by_keyword(test_data, keyword):
  122. def _iterate():
  123. i = 0
  124. while i < len(test_data):
  125. if test_data[i] == keyword:
  126. i += 2
  127. else:
  128. yield test_data[i]
  129. i += 1
  130. return list(_iterate())
  131. def strip_roots(path):
  132. for prefix in ["$B/", "$S/"]:
  133. if path.startswith(prefix):
  134. return path[len(prefix) :]
  135. return path
  136. def to_yesno(x):
  137. return "yes" if x else "no"
  138. def get_no_lint_value(unit):
  139. import ymake
  140. supported_no_lint_values = ('none', 'none_internal', 'ktlint')
  141. no_lint_value = unit.get('_NO_LINT_VALUE')
  142. if no_lint_value and no_lint_value not in supported_no_lint_values:
  143. ymake.report_configure_error('Unsupported value for NO_LINT macro: {}'.format(no_lint_value))
  144. return no_lint_value
  145. def ugly_conftest_exception(path):
  146. """
  147. FIXME:
  148. TAXICOMMON-9288: Taxi abused bug with absolute paths and built conftest descovery upon it
  149. until the issue is filed let's limit impact only to existing files.
  150. Never let this list grow!!! Fix issue before adding any new violating conftests
  151. """
  152. exceptions = [
  153. 'taxi/uservices/userver-arc-utils/functional_tests/basic/conftest.py',
  154. 'taxi/uservices/userver-arc-utils/functional_tests/basic_chaos/conftest.py',
  155. 'taxi/uservices/userver-arc-utils/functional_tests/json2yaml/conftest.py',
  156. ]
  157. if not path.endswith('conftest.py'):
  158. return False
  159. for e in exceptions:
  160. if path.endswith(e):
  161. return True
  162. return False