res.py 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. import json
  2. import os
  3. import six
  4. from _common import iterpair, listid, pathid, rootrel_arc_src, tobuilddir, filter_out_by_keyword
  5. import ymake
  6. def split(lst, limit):
  7. # paths are specified with replaceable prefix
  8. # real length is unknown at the moment, that why we use root_lenght
  9. # as a rough estimation
  10. root_lenght = 200
  11. filepath = None
  12. lenght = 0
  13. bucket = []
  14. for item in lst:
  15. if filepath:
  16. lenght += root_lenght + len(filepath) + len(item)
  17. if lenght > limit and bucket:
  18. yield bucket
  19. bucket = []
  20. lenght = 0
  21. bucket.append(filepath)
  22. bucket.append(item)
  23. filepath = None
  24. else:
  25. filepath = item
  26. if bucket:
  27. yield bucket
  28. def remove_prefix(text, prefix):
  29. if text.startswith(prefix):
  30. return text[len(prefix) :]
  31. return text
  32. def onresource_files(unit, *args):
  33. """
  34. @usage: RESOURCE_FILES([PREFIX {prefix}] [STRIP prefix_to_strip] {path})
  35. This macro expands into
  36. RESOURCE(DONT_PARSE {path} resfs/file/{prefix}{path}
  37. - resfs/src/resfs/file/{prefix}{remove_prefix(path, prefix_to_strip)}={rootrel_arc_src(path)}
  38. )
  39. resfs/src/{key} stores a source root (or build root) relative path of the
  40. source of the value of the {key} resource.
  41. resfs/file/{key} stores any value whose source was a file on a filesystem.
  42. resfs/src/resfs/file/{key} must store its path.
  43. DONT_PARSE disables parsing for source code files (determined by extension)
  44. Please don't abuse: use separate DONT_PARSE macro call only for files subject to parsing
  45. This form is for use from other plugins:
  46. RESOURCE_FILES([DEST {dest}] {path}) expands into RESOURCE({path} resfs/file/{dest})
  47. @see: https://wiki.yandex-team.ru/devtools/commandsandvars/resourcefiles/
  48. """
  49. prefix = ''
  50. prefix_to_strip = None
  51. dest = None
  52. res = []
  53. if args and not unit.enabled('_GO_MODULE'):
  54. # GO_RESOURCE currently doesn't support DONT_PARSE
  55. res.append('DONT_PARSE')
  56. args = iter(args)
  57. for arg in args:
  58. if arg == 'PREFIX':
  59. prefix, dest = next(args), None
  60. elif arg == 'DEST':
  61. dest, prefix = next(args), None
  62. elif arg == 'STRIP':
  63. prefix_to_strip = next(args)
  64. else:
  65. path = arg
  66. key = 'resfs/file/' + (
  67. dest or (prefix + (path if not prefix_to_strip else remove_prefix(path, prefix_to_strip)))
  68. )
  69. src = 'resfs/src/{}={}'.format(key, rootrel_arc_src(path, unit))
  70. res += ['-', src, path, key]
  71. if unit.enabled('_GO_MODULE'):
  72. unit.on_go_resource(res)
  73. else:
  74. unit.onresource(res)
  75. def onall_resource_files(unit, *args):
  76. # This is only validation, actual work is done in ymake.core.conf implementation
  77. for arg in args:
  78. if '*' in arg or '?' in arg:
  79. ymake.report_configure_error('Wildcards in [[imp]]ALL_RESOURCE_FILES[[rst]] are not allowed')
  80. def on_ya_conf_json(unit, conf_file):
  81. conf_abs_path = unit.resolve('$S/' + conf_file)
  82. if not os.path.exists(conf_abs_path):
  83. ymake.report_configure_error('File "{}" not found'.format(conf_abs_path))
  84. return
  85. # conf_file should be passed to the RESOURCE_FILES macro without path.
  86. # To resolve it later by name only we must add it's path to SRCDIR().
  87. conf_dir = os.path.dirname(conf_file)
  88. if conf_dir:
  89. unit.onsrcdir(conf_dir)
  90. unit.onresource_files(os.path.basename(conf_file))
  91. with open(conf_abs_path) as f:
  92. conf = json.load(f)
  93. formulas = set()
  94. for bottle_name, bottle in conf['bottles'].items():
  95. formula = bottle['formula']
  96. if isinstance(formula, six.string_types):
  97. if formula.startswith(conf_dir):
  98. abs_path = unit.resolve('$S/' + formula)
  99. if os.path.exists(abs_path):
  100. formulas.add(formula)
  101. else:
  102. ymake.report_configure_error(
  103. 'File "{}" (referenced from bottle "{}" in "{}") is not found'.format(
  104. abs_path, bottle_name, conf_abs_path
  105. )
  106. )
  107. else:
  108. ymake.report_configure_error(
  109. 'File "{}" (referenced from bottle "{}" in "{}") must be located in "{}" file tree'.format(
  110. formula, bottle_name, conf_file, conf_dir
  111. )
  112. )
  113. for formula in formulas:
  114. unit.onresource_files(formula)