dlang.py 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. # Copyright 2018 The Meson development team
  2. # Licensed under the Apache License, Version 2.0 (the "License");
  3. # you may not use this file except in compliance with the License.
  4. # You may obtain a copy of the License at
  5. # http://www.apache.org/licenses/LICENSE-2.0
  6. # Unless required by applicable law or agreed to in writing, software
  7. # distributed under the License is distributed on an "AS IS" BASIS,
  8. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  9. # See the License for the specific language governing permissions and
  10. # limitations under the License.
  11. # This file contains the detection logic for external dependencies that
  12. # are UI-related.
  13. import json
  14. import os
  15. from . import ExtensionModule
  16. from .. import mlog
  17. from ..mesonlib import (
  18. Popen_safe, MesonException
  19. )
  20. from ..dependencies.base import (
  21. ExternalProgram, DubDependency
  22. )
  23. from ..interpreter import DependencyHolder
  24. class DlangModule(ExtensionModule):
  25. class_dubbin = None
  26. init_dub = False
  27. def __init__(self, interpreter):
  28. super().__init__(interpreter)
  29. self.snippets.add('generate_dub_file')
  30. def _init_dub(self):
  31. if DlangModule.class_dubbin is None:
  32. self.dubbin = DubDependency.class_dubbin
  33. DlangModule.class_dubbin = self.dubbin
  34. else:
  35. self.dubbin = DlangModule.class_dubbin
  36. if DlangModule.class_dubbin is None:
  37. self.dubbin = self.check_dub()
  38. DlangModule.class_dubbin = self.dubbin
  39. else:
  40. self.dubbin = DlangModule.class_dubbin
  41. if not self.dubbin:
  42. if not self.dubbin:
  43. raise MesonException('DUB not found.')
  44. def generate_dub_file(self, interpreter, state, args, kwargs):
  45. if not DlangModule.init_dub:
  46. self._init_dub()
  47. if len(args) < 2:
  48. raise MesonException('Missing arguments')
  49. config = {
  50. 'name': args[0]
  51. }
  52. config_path = os.path.join(args[1], 'dub.json')
  53. if os.path.exists(config_path):
  54. with open(config_path, 'r', encoding='utf8') as ofile:
  55. try:
  56. config = json.load(ofile)
  57. except ValueError:
  58. mlog.warning('Failed to load the data in dub.json')
  59. warn_publishing = ['description', 'license']
  60. for arg in warn_publishing:
  61. if arg not in kwargs and \
  62. arg not in config:
  63. mlog.warning('Without', mlog.bold(arg), 'the DUB package can\'t be published')
  64. for key, value in kwargs.items():
  65. if key == 'dependencies':
  66. config[key] = {}
  67. if isinstance(value, list):
  68. for dep in value:
  69. if isinstance(dep, DependencyHolder):
  70. name = dep.method_call('name', [], [])
  71. ret, res = self._call_dubbin(['describe', name])
  72. if ret == 0:
  73. version = dep.method_call('version', [], [])
  74. if version is None:
  75. config[key][name] = ''
  76. else:
  77. config[key][name] = version
  78. elif isinstance(value, DependencyHolder):
  79. name = value.method_call('name', [], [])
  80. ret, res = self._call_dubbin(['describe', name])
  81. if ret == 0:
  82. version = value.method_call('version', [], [])
  83. if version is None:
  84. config[key][name] = ''
  85. else:
  86. config[key][name] = version
  87. else:
  88. config[key] = value
  89. with open(config_path, 'w', encoding='utf8') as ofile:
  90. ofile.write(json.dumps(config, indent=4, ensure_ascii=False))
  91. def _call_dubbin(self, args, env=None):
  92. p, out = Popen_safe(self.dubbin.get_command() + args, env=env)[0:2]
  93. return p.returncode, out.strip()
  94. def check_dub(self):
  95. dubbin = ExternalProgram('dub', silent=True)
  96. if dubbin.found():
  97. try:
  98. p, out = Popen_safe(dubbin.get_command() + ['--version'])[0:2]
  99. if p.returncode != 0:
  100. mlog.warning('Found dub {!r} but couldn\'t run it'
  101. ''.format(' '.join(dubbin.get_command())))
  102. # Set to False instead of None to signify that we've already
  103. # searched for it and not found it
  104. dubbin = False
  105. except (FileNotFoundError, PermissionError):
  106. dubbin = False
  107. else:
  108. dubbin = False
  109. if dubbin:
  110. mlog.log('Found DUB:', mlog.bold(dubbin.get_path()),
  111. '(%s)' % out.strip())
  112. else:
  113. mlog.log('Found DUB:', mlog.red('NO'))
  114. return dubbin
  115. def initialize(*args, **kwargs):
  116. return DlangModule(*args, **kwargs)