java.py 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485
  1. import _common as common
  2. import ymake
  3. import json
  4. import os
  5. import base64
  6. import six
  7. DELIM = '================================'
  8. CONTRIB_JAVA_PREFIX = 'contrib/java/'
  9. def split_args(s): # TODO quotes, escapes
  10. return list(filter(None, s.split()))
  11. def extract_macro_calls(unit, macro_value_name, macro_calls_delim):
  12. if not unit.get(macro_value_name):
  13. return []
  14. return list(
  15. filter(
  16. None,
  17. map(split_args, unit.get(macro_value_name).replace('$' + macro_value_name, '').split(macro_calls_delim)),
  18. )
  19. )
  20. def extract_macro_calls2(unit, macro_value_name):
  21. if not unit.get(macro_value_name):
  22. return []
  23. calls = []
  24. for call_encoded_args in unit.get(macro_value_name).strip().split():
  25. call_args = json.loads(base64.b64decode(call_encoded_args))
  26. calls.append(call_args)
  27. return calls
  28. def on_run_jbuild_program(unit, *args):
  29. args = list(args)
  30. """
  31. Custom code generation
  32. @link: https://wiki.yandex-team.ru/yatool/java/#kodogeneracijarunjavaprogram
  33. """
  34. flat, kv = common.sort_by_keywords(
  35. {
  36. 'IN': -1,
  37. 'IN_DIR': -1,
  38. 'OUT': -1,
  39. 'OUT_DIR': -1,
  40. 'CWD': 1,
  41. 'CLASSPATH': -1,
  42. 'CP_USE_COMMAND_FILE': 1,
  43. 'ADD_SRCS_TO_CLASSPATH': 0,
  44. },
  45. args,
  46. )
  47. depends = kv.get('CLASSPATH', []) + kv.get('JAR', [])
  48. fake_out = None
  49. if depends:
  50. # XXX: hack to force ymake to build dependencies
  51. fake_out = "fake.out.{}".format(hash(tuple(args)))
  52. unit.on_run_java(['TOOL'] + depends + ["OUT", fake_out])
  53. if not kv.get('CP_USE_COMMAND_FILE'):
  54. args += ['CP_USE_COMMAND_FILE', unit.get(['JAVA_PROGRAM_CP_USE_COMMAND_FILE']) or 'yes']
  55. if fake_out is not None:
  56. args += ['FAKE_OUT', fake_out]
  57. prev = unit.get(['RUN_JAVA_PROGRAM_VALUE']) or ''
  58. new_val = (
  59. prev + ' ' + six.ensure_str(base64.b64encode(six.ensure_binary(json.dumps(list(args)), encoding='utf-8')))
  60. ).strip()
  61. unit.set(['RUN_JAVA_PROGRAM_VALUE', new_val])
  62. def ongenerate_script(unit, *args):
  63. """
  64. heretic@ promised to make tutorial here
  65. Don't forget
  66. Feel free to remind
  67. """
  68. flat, kv = common.sort_by_keywords({'OUT': -1, 'TEMPLATE': -1, 'CUSTOM_PROPERTY': -1}, args)
  69. if len(kv.get('TEMPLATE', [])) > len(kv.get('OUT', [])):
  70. ymake.report_configure_error('To many arguments for TEMPLATE parameter')
  71. prev = unit.get(['GENERATE_SCRIPT_VALUE']) or ''
  72. new_val = (
  73. prev + ' ' + six.ensure_str(base64.b64encode(six.ensure_binary(json.dumps(list(args)), encoding='utf-8')))
  74. ).strip()
  75. unit.set(['GENERATE_SCRIPT_VALUE', new_val])
  76. def onjava_module(unit, *args):
  77. args_delim = unit.get('ARGS_DELIM')
  78. if unit.get('YA_IDE_IDEA') != 'yes':
  79. return
  80. data = {
  81. 'BUNDLE_NAME': unit.name(),
  82. 'PATH': unit.path(),
  83. 'MODULE_TYPE': unit.get('MODULE_TYPE'),
  84. 'MODULE_ARGS': unit.get('MODULE_ARGS'),
  85. 'MANAGED_PEERS': '${MANAGED_PEERS}',
  86. 'MANAGED_PEERS_CLOSURE': '${MANAGED_PEERS_CLOSURE}',
  87. 'NON_NAMAGEABLE_PEERS': '${NON_NAMAGEABLE_PEERS}',
  88. 'TEST_CLASSPATH_MANAGED': '${TEST_CLASSPATH_MANAGED}',
  89. 'EXCLUDE': extract_macro_calls(unit, 'EXCLUDE_VALUE', args_delim),
  90. 'JAVA_SRCS': extract_macro_calls(unit, 'JAVA_SRCS_VALUE', args_delim),
  91. 'JAVAC_FLAGS': extract_macro_calls(unit, 'JAVAC_FLAGS_VALUE', args_delim),
  92. 'ANNOTATION_PROCESSOR': extract_macro_calls(unit, 'ANNOTATION_PROCESSOR_VALUE', args_delim),
  93. 'EXTERNAL_JAR': extract_macro_calls(unit, 'EXTERNAL_JAR_VALUE', args_delim),
  94. 'RUN_JAVA_PROGRAM': extract_macro_calls2(unit, 'RUN_JAVA_PROGRAM_VALUE'),
  95. 'RUN_JAVA_PROGRAM_MANAGED': '${RUN_JAVA_PROGRAM_MANAGED}',
  96. 'MAVEN_GROUP_ID': extract_macro_calls(unit, 'MAVEN_GROUP_ID_VALUE', args_delim),
  97. 'JAR_INCLUDE_FILTER': extract_macro_calls(unit, 'JAR_INCLUDE_FILTER_VALUE', args_delim),
  98. 'JAR_EXCLUDE_FILTER': extract_macro_calls(unit, 'JAR_EXCLUDE_FILTER_VALUE', args_delim),
  99. # TODO remove when java test dart is in prod
  100. 'UNITTEST_DIR': unit.get('UNITTEST_DIR'),
  101. 'SYSTEM_PROPERTIES': extract_macro_calls(unit, 'SYSTEM_PROPERTIES_VALUE', args_delim),
  102. 'JVM_ARGS': extract_macro_calls(unit, 'JVM_ARGS_VALUE', args_delim),
  103. 'TEST_CWD': extract_macro_calls(unit, 'TEST_CWD_VALUE', args_delim),
  104. 'TEST_FORK_MODE': extract_macro_calls(unit, 'TEST_FORK_MODE', args_delim),
  105. 'SPLIT_FACTOR': extract_macro_calls(unit, 'TEST_SPLIT_FACTOR', args_delim),
  106. 'TIMEOUT': extract_macro_calls(unit, 'TEST_TIMEOUT', args_delim),
  107. 'TAG': extract_macro_calls(unit, 'TEST_TAGS_VALUE', args_delim),
  108. 'SIZE': extract_macro_calls(unit, 'TEST_SIZE_NAME', args_delim),
  109. 'DEPENDS': extract_macro_calls(unit, 'TEST_DEPENDS_VALUE', args_delim),
  110. 'IDEA_EXCLUDE': extract_macro_calls(unit, 'IDEA_EXCLUDE_DIRS_VALUE', args_delim),
  111. 'IDEA_RESOURCE': extract_macro_calls(unit, 'IDEA_RESOURCE_DIRS_VALUE', args_delim),
  112. 'IDEA_MODULE_NAME': extract_macro_calls(unit, 'IDEA_MODULE_NAME_VALUE', args_delim),
  113. 'GENERATE_SCRIPT': extract_macro_calls2(unit, 'GENERATE_SCRIPT_VALUE'),
  114. 'FAKEID': extract_macro_calls(unit, 'FAKEID', args_delim),
  115. 'TEST_DATA': extract_macro_calls(unit, 'TEST_DATA_VALUE', args_delim),
  116. 'JAVA_FORBIDDEN_LIBRARIES': extract_macro_calls(unit, 'JAVA_FORBIDDEN_LIBRARIES_VALUE', args_delim),
  117. 'JDK_RESOURCE': 'JDK' + (unit.get('JDK_VERSION') or unit.get('JDK_REAL_VERSION') or '_DEFAULT'),
  118. }
  119. if unit.get('ENABLE_PREVIEW_VALUE') == 'yes' and (unit.get('JDK_VERSION') or unit.get('JDK_REAL_VERSION')) in (
  120. '15',
  121. '17',
  122. '18',
  123. '19',
  124. '20',
  125. '21',
  126. ):
  127. data['ENABLE_PREVIEW'] = extract_macro_calls(unit, 'ENABLE_PREVIEW_VALUE', args_delim)
  128. if unit.get('SAVE_JAVAC_GENERATED_SRCS_DIR') and unit.get('SAVE_JAVAC_GENERATED_SRCS_TAR'):
  129. data['SAVE_JAVAC_GENERATED_SRCS_DIR'] = extract_macro_calls(unit, 'SAVE_JAVAC_GENERATED_SRCS_DIR', args_delim)
  130. data['SAVE_JAVAC_GENERATED_SRCS_TAR'] = extract_macro_calls(unit, 'SAVE_JAVAC_GENERATED_SRCS_TAR', args_delim)
  131. if unit.get('JAVA_ADD_DLLS_VALUE') == 'yes':
  132. data['ADD_DLLS_FROM_DEPENDS'] = extract_macro_calls(unit, 'JAVA_ADD_DLLS_VALUE', args_delim)
  133. if unit.get('ERROR_PRONE_VALUE') == 'yes':
  134. data['ERROR_PRONE'] = extract_macro_calls(unit, 'ERROR_PRONE_VALUE', args_delim)
  135. if unit.get('WITH_KOTLIN_VALUE') == 'yes':
  136. data['WITH_KOTLIN'] = extract_macro_calls(unit, 'WITH_KOTLIN_VALUE', args_delim)
  137. if unit.get('KOTLIN_JVM_TARGET'):
  138. data['KOTLIN_JVM_TARGET'] = extract_macro_calls(unit, 'KOTLIN_JVM_TARGET', args_delim)
  139. if unit.get('KOTLINC_FLAGS_VALUE'):
  140. data['KOTLINC_FLAGS'] = extract_macro_calls(unit, 'KOTLINC_FLAGS_VALUE', args_delim)
  141. if unit.get('KOTLINC_OPTS_VALUE'):
  142. data['KOTLINC_OPTS'] = extract_macro_calls(unit, 'KOTLINC_OPTS_VALUE', args_delim)
  143. if unit.get('DIRECT_DEPS_ONLY_VALUE') == 'yes':
  144. data['DIRECT_DEPS_ONLY'] = extract_macro_calls(unit, 'DIRECT_DEPS_ONLY_VALUE', args_delim)
  145. if unit.get('JAVA_EXTERNAL_DEPENDENCIES_VALUE'):
  146. valid = []
  147. for dep in sum(extract_macro_calls(unit, 'JAVA_EXTERNAL_DEPENDENCIES_VALUE', args_delim), []):
  148. if os.path.normpath(dep).startswith('..'):
  149. ymake.report_configure_error(
  150. '{}: {} - relative paths in JAVA_EXTERNAL_DEPENDENCIES is not allowed'.format(unit.path(), dep)
  151. )
  152. elif os.path.isabs(dep):
  153. ymake.report_configure_error(
  154. '{}: {} absolute paths in JAVA_EXTERNAL_DEPENDENCIES is not allowed'.format(unit.path(), dep)
  155. )
  156. else:
  157. valid.append(dep)
  158. if valid:
  159. data['EXTERNAL_DEPENDENCIES'] = [valid]
  160. if unit.get('MAKE_UBERJAR_VALUE') == 'yes':
  161. if unit.get('MODULE_TYPE') != 'JAVA_PROGRAM':
  162. ymake.report_configure_error('{}: UBERJAR supported only for JAVA_PROGRAM module type'.format(unit.path()))
  163. data['UBERJAR'] = extract_macro_calls(unit, 'MAKE_UBERJAR_VALUE', args_delim)
  164. data['UBERJAR_PREFIX'] = extract_macro_calls(unit, 'UBERJAR_PREFIX_VALUE', args_delim)
  165. data['UBERJAR_HIDE_EXCLUDE'] = extract_macro_calls(unit, 'UBERJAR_HIDE_EXCLUDE_VALUE', args_delim)
  166. data['UBERJAR_PATH_EXCLUDE'] = extract_macro_calls(unit, 'UBERJAR_PATH_EXCLUDE_VALUE', args_delim)
  167. data['UBERJAR_MANIFEST_TRANSFORMER_MAIN'] = extract_macro_calls(
  168. unit, 'UBERJAR_MANIFEST_TRANSFORMER_MAIN_VALUE', args_delim
  169. )
  170. data['UBERJAR_MANIFEST_TRANSFORMER_ATTRIBUTE'] = extract_macro_calls(
  171. unit, 'UBERJAR_MANIFEST_TRANSFORMER_ATTRIBUTE_VALUE', args_delim
  172. )
  173. data['UBERJAR_APPENDING_TRANSFORMER'] = extract_macro_calls(
  174. unit, 'UBERJAR_APPENDING_TRANSFORMER_VALUE', args_delim
  175. )
  176. data['UBERJAR_SERVICES_RESOURCE_TRANSFORMER'] = extract_macro_calls(
  177. unit, 'UBERJAR_SERVICES_RESOURCE_TRANSFORMER_VALUE', args_delim
  178. )
  179. if unit.get('WITH_JDK_VALUE') == 'yes':
  180. if unit.get('MODULE_TYPE') != 'JAVA_PROGRAM':
  181. ymake.report_configure_error(
  182. '{}: JDK export supported only for JAVA_PROGRAM module type'.format(unit.path())
  183. )
  184. data['WITH_JDK'] = extract_macro_calls(unit, 'WITH_JDK_VALUE', args_delim)
  185. if not data['EXTERNAL_JAR']:
  186. # IMPORTANT before switching vcs_info.py to python3 the value was always evaluated to $YMAKE_PYTHON but no
  187. # code in java dart parser extracts its value only checks this key for existance.
  188. data['EMBED_VCS'] = [['yes']]
  189. # FORCE_VCS_INFO_UPDATE is responsible for setting special value of VCS_INFO_DISABLE_CACHE__NO_UID__
  190. macro_val = extract_macro_calls(unit, 'FORCE_VCS_INFO_UPDATE', args_delim)
  191. macro_str = macro_val[0][0] if macro_val and macro_val[0] and macro_val[0][0] else ''
  192. if macro_str and macro_str == 'yes':
  193. data['VCS_INFO_DISABLE_CACHE__NO_UID__'] = macro_val
  194. for java_srcs_args in data['JAVA_SRCS']:
  195. external = None
  196. for i in six.moves.range(len(java_srcs_args)):
  197. arg = java_srcs_args[i]
  198. if arg == 'EXTERNAL':
  199. if not i + 1 < len(java_srcs_args):
  200. continue # TODO configure error
  201. ex = java_srcs_args[i + 1]
  202. if ex in ('EXTERNAL', 'SRCDIR', 'PACKAGE_PREFIX', 'EXCLUDE'):
  203. continue # TODO configure error
  204. if external is not None:
  205. continue # TODO configure error
  206. external = ex
  207. if external:
  208. unit.onpeerdir(external)
  209. data = {k: v for k, v in six.iteritems(data) if v}
  210. dart = 'JAVA_DART: ' + six.ensure_str(base64.b64encode(six.ensure_binary(json.dumps(data)))) + '\n' + DELIM + '\n'
  211. unit.set_property(['JAVA_DART_DATA', dart])
  212. def on_add_java_style_checks(unit, *args):
  213. if unit.get('LINT_LEVEL_VALUE') != "none" and common.get_no_lint_value(unit) != 'none':
  214. unit.onadd_check(['JAVA_STYLE', unit.get('LINT_LEVEL_VALUE')] + list(args))
  215. def on_add_kotlin_style_checks(unit, *args):
  216. """
  217. ktlint can be disabled using NO_LINT() and NO_LINT(ktlint)
  218. """
  219. if unit.get('WITH_KOTLIN_VALUE') == 'yes':
  220. if common.get_no_lint_value(unit) == '':
  221. unit.onadd_check(['ktlint'] + list(args))
  222. def on_add_classpath_clash_check(unit, *args):
  223. jdeps_val = (unit.get('CHECK_JAVA_DEPS_VALUE') or '').lower()
  224. if jdeps_val and jdeps_val not in ('yes', 'no', 'strict'):
  225. ymake.report_configure_error('CHECK_JAVA_DEPS: "yes", "no" or "strict" required')
  226. if jdeps_val and jdeps_val != 'no':
  227. unit.onjava_test_deps(jdeps_val)
  228. # Ymake java modules related macroses
  229. def onexternal_jar(unit, *args):
  230. args = list(args)
  231. flat, kv = common.sort_by_keywords({'SOURCES': 1}, args)
  232. if not flat:
  233. ymake.report_configure_error('EXTERNAL_JAR requires exactly one resource URL of compiled jar library')
  234. res = flat[0]
  235. resid = res[4:] if res.startswith('sbr:') else res
  236. unit.set(['JAR_LIB_RESOURCE', resid])
  237. unit.set(['JAR_LIB_RESOURCE_URL', res])
  238. def on_check_java_srcdir(unit, *args):
  239. args = list(args)
  240. if 'SKIP_CHECK_SRCDIR' in args:
  241. return
  242. for arg in args:
  243. if '$' not in arg:
  244. arc_srcdir = os.path.join(unit.get('MODDIR'), arg)
  245. abs_srcdir = unit.resolve(os.path.join("$S/", arc_srcdir))
  246. if not os.path.exists(abs_srcdir) or not os.path.isdir(abs_srcdir):
  247. unit.onsrcdir(os.path.join('${ARCADIA_ROOT}', arc_srcdir))
  248. return
  249. srcdir = common.resolve_common_const(unit.resolve_arc_path(arg))
  250. if srcdir and srcdir.startswith('$S'):
  251. abs_srcdir = unit.resolve(srcdir)
  252. if not os.path.exists(abs_srcdir) or not os.path.isdir(abs_srcdir):
  253. unit.onsrcdir(os.path.join('${ARCADIA_ROOT}', srcdir[3:]))
  254. def on_fill_jar_copy_resources_cmd(unit, *args):
  255. if len(args) == 4:
  256. varname, srcdir, base_classes_dir, reslist = tuple(args)
  257. package = ''
  258. else:
  259. varname, srcdir, base_classes_dir, package, reslist = tuple(args)
  260. dest_dir = os.path.join(base_classes_dir, *package.split('.')) if package else base_classes_dir
  261. var = unit.get(varname)
  262. var += ' && $FS_TOOLS copy_files {} {} {}'.format(
  263. srcdir if srcdir.startswith('"$') else '${CURDIR}/' + srcdir, dest_dir, reslist
  264. )
  265. unit.set([varname, var])
  266. def on_fill_jar_gen_srcs(unit, *args):
  267. varname, jar_type, srcdir, base_classes_dir, java_list, kt_list, groovy_list, res_list = tuple(args[0:8])
  268. resolved_srcdir = unit.resolve_arc_path(srcdir)
  269. if not resolved_srcdir.startswith('$') or resolved_srcdir.startswith('$S'):
  270. return
  271. exclude_pos = args.index('EXCLUDE')
  272. globs = args[7:exclude_pos]
  273. excludes = args[exclude_pos + 1 :]
  274. var = unit.get(varname)
  275. var += ' && ${{cwd:BINDIR}} $YMAKE_PYTHON ${{input:"build/scripts/resolve_java_srcs.py"}} --append -d {} -s {} -k {} -g {} -r {} --include-patterns {}'.format(
  276. srcdir, java_list, kt_list, groovy_list, res_list, ' '.join(globs)
  277. )
  278. if jar_type == 'SRC_JAR':
  279. var += ' --all-resources'
  280. if len(excludes) > 0:
  281. var += ' --exclude-patterns {}'.format(' '.join(excludes))
  282. if unit.get('WITH_KOTLIN_VALUE') == 'yes':
  283. var += ' --resolve-kotlin'
  284. unit.set([varname, var])
  285. def on_check_run_java_prog_classpath(unit, *args):
  286. if len(args) != 1:
  287. ymake.report_configure_error(
  288. 'multiple CLASSPATH elements in RUN_JAVA_PROGRAM invocation no more supported. Use JAVA_RUNTIME_PEERDIR on the JAVA_PROGRAM module instead'
  289. )
  290. def extract_words(words, keys):
  291. kv = {}
  292. k = None
  293. for w in words:
  294. if w in keys:
  295. k = w
  296. else:
  297. if k not in kv:
  298. kv[k] = []
  299. kv[k].append(w)
  300. return kv
  301. def parse_words(words):
  302. kv = extract_words(words, {'OUT', 'TEMPLATE'})
  303. if 'TEMPLATE' not in kv:
  304. kv['TEMPLATE'] = ['template.tmpl']
  305. ws = []
  306. for item in ('OUT', 'TEMPLATE'):
  307. for i, word in list(enumerate(kv[item])):
  308. if word == 'CUSTOM_PROPERTY':
  309. ws += kv[item][i:]
  310. kv[item] = kv[item][:i]
  311. templates = kv['TEMPLATE']
  312. outputs = kv['OUT']
  313. if len(outputs) < len(templates):
  314. ymake.report_configure_error('To many arguments for TEMPLATE parameter')
  315. return
  316. if ws and ws[0] != 'CUSTOM_PROPERTY':
  317. ymake.report_configure_error('''Can't parse {}'''.format(ws))
  318. custom_props = []
  319. for item in ws:
  320. if item == 'CUSTOM_PROPERTY':
  321. custom_props.append([])
  322. else:
  323. custom_props[-1].append(item)
  324. props = []
  325. for p in custom_props:
  326. if not p:
  327. ymake.report_configure_error('Empty CUSTOM_PROPERTY')
  328. continue
  329. props.append('-B')
  330. if len(p) > 1:
  331. props.append(six.ensure_str(base64.b64encode(six.ensure_binary("{}={}".format(p[0], ' '.join(p[1:]))))))
  332. else:
  333. ymake.report_configure_error('CUSTOM_PROPERTY "{}" value is not specified'.format(p[0]))
  334. for i, o in enumerate(outputs):
  335. yield o, templates[min(i, len(templates) - 1)], props
  336. def on_ymake_generate_script(unit, *args):
  337. for out, tmpl, props in parse_words(list(args)):
  338. unit.on_add_gen_java_script([out, tmpl] + list(props))
  339. def on_jdk_version_macro_check(unit, *args):
  340. if len(args) != 1:
  341. unit.message(["error", "Invalid syntax. Single argument required."])
  342. jdk_version = args[0]
  343. available_versions = (
  344. '11',
  345. '15',
  346. '17',
  347. '18',
  348. '19',
  349. '20',
  350. '21',
  351. )
  352. if jdk_version not in available_versions:
  353. ymake.report_configure_error(
  354. "Invalid jdk version: {}. {} are available".format(jdk_version, available_versions)
  355. )
  356. if int(jdk_version) >= 19 and unit.get('WITH_JDK_VALUE') != 'yes' and unit.get('MODULE_TAG') == 'JAR_RUNNABLE':
  357. msg = (
  358. "Missing WITH_JDK() macro for JDK version >= 19"
  359. # temporary link with additional explanation
  360. ". For more info see https://clubs.at.yandex-team.ru/arcadia/28543"
  361. )
  362. ymake.report_configure_error(msg)
  363. def _maven_coords_for_project(unit, project_dir):
  364. parts = project_dir.split('/')
  365. g = '.'.join(parts[2:-2])
  366. a = parts[-2]
  367. v = parts[-1]
  368. c = ''
  369. pom_path = unit.resolve(os.path.join('$S', project_dir, 'pom.xml'))
  370. if os.path.exists(pom_path):
  371. import xml.etree.ElementTree as et
  372. with open(pom_path, 'rb') as f:
  373. root = et.fromstring(f.read())
  374. for xpath in ('./{http://maven.apache.org/POM/4.0.0}artifactId', './artifactId'):
  375. artifact = root.find(xpath)
  376. if artifact is not None:
  377. artifact = artifact.text
  378. if a != artifact and a.startswith(artifact):
  379. c = a[len(artifact) :].lstrip('-_')
  380. a = artifact
  381. break
  382. return '{}:{}:{}:{}'.format(g, a, v, c)
  383. def on_setup_maven_export_coords_if_need(unit, *args):
  384. if not unit.enabled('MAVEN_EXPORT'):
  385. return
  386. unit.set(['MAVEN_EXPORT_COORDS_GLOBAL', _maven_coords_for_project(unit, args[0])])
  387. def _get_classpath(unit, dir):
  388. if dir.startswith(CONTRIB_JAVA_PREFIX):
  389. return '\\"{}\\"'.format(_maven_coords_for_project(unit, dir).rstrip(':'))
  390. else:
  391. return 'project(\\":{}\\")'.format(dir.replace('/', ':'))
  392. def on_setup_project_coords_if_needed(unit, *args):
  393. if not unit.enabled('EXPORT_GRADLE'):
  394. return
  395. project_dir = args[0]
  396. if project_dir.startswith(CONTRIB_JAVA_PREFIX):
  397. value = '{}'.format(_get_classpath(unit, project_dir).rstrip(':'))
  398. else:
  399. value = 'project(\\":{}\\")'.format(project_dir.replace('/', ':'))
  400. unit.set(['EXPORT_GRADLE_CLASSPATH', value])