aboutsummaryrefslogtreecommitdiff
path: root/mesonbuild/templates
diff options
context:
space:
mode:
authorDylan Baker <dylan@pnwbakers.com>2023-06-30 14:58:30 -0700
committerEli Schwartz <eschwartz93@gmail.com>2023-07-25 15:50:21 -0400
commit5449d10f01bc765e33e041a15f7c90e752ba7539 (patch)
tree66ae8c35da4c517f3d8cad6a43817fe06603c328 /mesonbuild/templates
parentbbe649a5fc7bb0b955b2688c4d797b71830c8aeb (diff)
downloadmeson-5449d10f01bc765e33e041a15f7c90e752ba7539.zip
meson-5449d10f01bc765e33e041a15f7c90e752ba7539.tar.gz
meson-5449d10f01bc765e33e041a15f7c90e752ba7539.tar.bz2
templates: use a common template for C# and Java
The only real differences between these generators is the file extension and the templates themselves. We can uses a shared abstract class with a few abstract properties to provide all of this to the same base class. This results in less code duplication and easier maintanence. I've made a few cleanups to the shared template: - use `str.capitalize()` instead of `str.upper()[0] + str[1:]` - use `open` as a context manager - use f-strings - put some duplicate calculations in the initializer
Diffstat (limited to 'mesonbuild/templates')
-rw-r--r--mesonbuild/templates/cstemplates.py51
-rw-r--r--mesonbuild/templates/javatemplates.py49
-rw-r--r--mesonbuild/templates/samplefactory.py31
-rw-r--r--mesonbuild/templates/sampleimpl.py78
4 files changed, 110 insertions, 99 deletions
diff --git a/mesonbuild/templates/cstemplates.py b/mesonbuild/templates/cstemplates.py
index 39653d4..d2d5ec9 100644
--- a/mesonbuild/templates/cstemplates.py
+++ b/mesonbuild/templates/cstemplates.py
@@ -13,9 +13,7 @@
# limitations under the License.
from __future__ import annotations
-import re
-
-from mesonbuild.templates.sampleimpl import SampleImpl
+from mesonbuild.templates.sampleimpl import ClassImpl
hello_cs_template = '''using System;
@@ -92,42 +90,11 @@ test('{test_name}', test_exe)
'''
-class CSharpProject(SampleImpl):
-
- def create_executable(self) -> None:
- lowercase_token = re.sub(r'[^a-z0-9]', '_', self.name.lower())
- uppercase_token = lowercase_token.upper()
- class_name = uppercase_token[0] + lowercase_token[1:]
- source_name = uppercase_token[0] + lowercase_token[1:] + '.cs'
- open(source_name, 'w', encoding='utf-8').write(
- hello_cs_template.format(project_name=self.name,
- class_name=class_name))
- open('meson.build', 'w', encoding='utf-8').write(
- hello_cs_meson_template.format(project_name=self.name,
- exe_name=self.name,
- source_name=source_name,
- version=self.version))
-
- def create_library(self) -> None:
- lowercase_token = re.sub(r'[^a-z0-9]', '_', self.name.lower())
- uppercase_token = lowercase_token.upper()
- class_name = uppercase_token[0] + lowercase_token[1:]
- class_test = uppercase_token[0] + lowercase_token[1:] + '_test'
- project_test = lowercase_token + '_test'
- lib_cs_name = uppercase_token[0] + lowercase_token[1:] + '.cs'
- test_cs_name = uppercase_token[0] + lowercase_token[1:] + '_test.cs'
- kwargs = {'utoken': uppercase_token,
- 'ltoken': lowercase_token,
- 'class_test': class_test,
- 'class_name': class_name,
- 'source_file': lib_cs_name,
- 'test_source_file': test_cs_name,
- 'test_exe_name': project_test,
- 'project_name': self.name,
- 'lib_name': lowercase_token,
- 'test_name': lowercase_token,
- 'version': self.version,
- }
- open(lib_cs_name, 'w', encoding='utf-8').write(lib_cs_template.format(**kwargs))
- open(test_cs_name, 'w', encoding='utf-8').write(lib_cs_test_template.format(**kwargs))
- open('meson.build', 'w', encoding='utf-8').write(lib_cs_meson_template.format(**kwargs))
+class CSharpProject(ClassImpl):
+
+ source_ext = 'cs'
+ exe_template = hello_cs_template
+ exe_meson_template = hello_cs_meson_template
+ lib_template = lib_cs_template
+ lib_test_template = lib_cs_test_template
+ lib_meson_template = lib_cs_meson_template
diff --git a/mesonbuild/templates/javatemplates.py b/mesonbuild/templates/javatemplates.py
index 4b9c746..4163ffd 100644
--- a/mesonbuild/templates/javatemplates.py
+++ b/mesonbuild/templates/javatemplates.py
@@ -13,9 +13,7 @@
# limitations under the License.
from __future__ import annotations
-import re
-
-from mesonbuild.templates.sampleimpl import SampleImpl
+from mesonbuild.templates.sampleimpl import ClassImpl
hello_java_template = '''
@@ -96,40 +94,11 @@ test('{test_name}', test_jar)
'''
-class JavaProject(SampleImpl):
-
- def create_executable(self) -> None:
- lowercase_token = re.sub(r'[^a-z0-9]', '_', self.name.lower())
- uppercase_token = lowercase_token.upper()
- class_name = uppercase_token[0] + lowercase_token[1:]
- source_name = uppercase_token[0] + lowercase_token[1:] + '.java'
- open(source_name, 'w', encoding='utf-8').write(
- hello_java_template.format(project_name=self.name,
- class_name=class_name))
- open('meson.build', 'w', encoding='utf-8').write(
- hello_java_meson_template.format(project_name=self.name,
- exe_name=class_name,
- source_name=source_name,
- version=self.version))
-
- def create_library(self) -> None:
- lowercase_token = re.sub(r'[^a-z0-9]', '_', self.name.lower())
- uppercase_token = lowercase_token.upper()
- class_name = uppercase_token[0] + lowercase_token[1:]
- class_test = uppercase_token[0] + lowercase_token[1:] + '_test'
- lib_java_name = uppercase_token[0] + lowercase_token[1:] + '.java'
- test_java_name = uppercase_token[0] + lowercase_token[1:] + '_test.java'
- kwargs = {'utoken': uppercase_token,
- 'ltoken': lowercase_token,
- 'class_test': class_test,
- 'class_name': class_name,
- 'source_file': lib_java_name,
- 'test_source_file': test_java_name,
- 'project_name': self.name,
- 'lib_name': lowercase_token,
- 'test_name': lowercase_token,
- 'version': self.version,
- }
- open(lib_java_name, 'w', encoding='utf-8').write(lib_java_template.format(**kwargs))
- open(test_java_name, 'w', encoding='utf-8').write(lib_java_test_template.format(**kwargs))
- open('meson.build', 'w', encoding='utf-8').write(lib_java_meson_template.format(**kwargs))
+class JavaProject(ClassImpl):
+
+ source_ext = 'java'
+ exe_template = hello_java_template
+ exe_meson_template = hello_java_meson_template
+ lib_template = lib_java_template
+ lib_test_template = lib_java_test_template
+ lib_meson_template = lib_java_meson_template
diff --git a/mesonbuild/templates/samplefactory.py b/mesonbuild/templates/samplefactory.py
index 89c3c4c..e3c8551 100644
--- a/mesonbuild/templates/samplefactory.py
+++ b/mesonbuild/templates/samplefactory.py
@@ -29,20 +29,23 @@ from mesonbuild.templates.ctemplates import CProject
if T.TYPE_CHECKING:
from ..minit import Arguments
- from .sampleimpl import SampleImpl
+ from .sampleimpl import ClassImpl, SampleImpl
+
+
+_IMPL: T.Mapping[str, T.Union[T.Type[ClassImpl], T.Type[SampleImpl]]] = {
+ 'c': CProject,
+ 'cpp': CppProject,
+ 'cs': CSharpProject,
+ 'cuda': CudaProject,
+ 'objc': ObjCProject,
+ 'objcpp': ObjCppProject,
+ 'java': JavaProject,
+ 'd': DlangProject,
+ 'rust': RustProject,
+ 'fortran': FortranProject,
+ 'vala': ValaProject,
+}
def sample_generator(options: Arguments) -> SampleImpl:
- return {
- 'c': CProject,
- 'cpp': CppProject,
- 'cs': CSharpProject,
- 'cuda': CudaProject,
- 'objc': ObjCProject,
- 'objcpp': ObjCppProject,
- 'java': JavaProject,
- 'd': DlangProject,
- 'rust': RustProject,
- 'fortran': FortranProject,
- 'vala': ValaProject
- }[options.language](options)
+ return _IMPL[options.language](options)
diff --git a/mesonbuild/templates/sampleimpl.py b/mesonbuild/templates/sampleimpl.py
index 4d586b1..0d31aa4 100644
--- a/mesonbuild/templates/sampleimpl.py
+++ b/mesonbuild/templates/sampleimpl.py
@@ -13,20 +13,92 @@
# limitations under the License.
from __future__ import annotations
+import abc
+import re
import typing as T
if T.TYPE_CHECKING:
from ..minit import Arguments
-class SampleImpl:
+class SampleImpl(metaclass=abc.ABCMeta):
def __init__(self, args: Arguments):
self.name = args.name
self.version = args.version
+ @abc.abstractmethod
def create_executable(self) -> None:
- raise NotImplementedError('Sample implementation for "executable" not implemented!')
+ pass
+ @abc.abstractmethod
def create_library(self) -> None:
- raise NotImplementedError('Sample implementation for "library" not implemented!')
+ pass
+
+
+class ClassImpl(SampleImpl):
+
+ """For Class based languages, like Java and C#"""
+
+ def __init__(self, args: Arguments):
+ super().__init__(args)
+ self.lowercase_token = re.sub(r'[^a-z0-9]', '_', self.name.lower())
+ self.uppercase_token = self.lowercase_token.upper()
+ self.capitalized_token = self.lowercase_token.capitalize()
+
+ @abc.abstractproperty
+ def exe_template(self) -> str:
+ pass
+
+ @abc.abstractproperty
+ def exe_meson_template(self) -> str:
+ pass
+
+ @abc.abstractproperty
+ def lib_template(self) -> str:
+ pass
+
+ @abc.abstractproperty
+ def lib_test_template(self) -> str:
+ pass
+
+ @abc.abstractproperty
+ def lib_meson_template(self) -> str:
+ pass
+
+ @abc.abstractproperty
+ def source_ext(self) -> str:
+ pass
+
+ def create_executable(self) -> None:
+ source_name = f'{self.capitalized_token}.{self.source_ext}'
+ with open(source_name, 'w', encoding='utf-8') as f:
+ f.write(self.exe_template.format(project_name=self.name,
+ class_name=self.capitalized_token))
+ with open('meson.build', 'w', encoding='utf-8') as f:
+ f.write(self.exe_meson_template.format(project_name=self.name,
+ exe_name=self.name,
+ source_name=source_name,
+ version=self.version))
+
+ def create_library(self) -> None:
+ lib_name = f'{self.capitalized_token}.{self.source_ext}'
+ test_name = f'{self.capitalized_token}_test.{self.source_ext}'
+ kwargs = {'utoken': self.uppercase_token,
+ 'ltoken': self.lowercase_token,
+ 'class_test': f'{self.capitalized_token}_test',
+ 'class_name': self.capitalized_token,
+ 'source_file': lib_name,
+ 'test_source_file': test_name,
+ 'test_exe_name': f'{self.lowercase_token}_test',
+ 'project_name': self.name,
+ 'lib_name': self.lowercase_token,
+ 'test_name': self.lowercase_token,
+ 'version': self.version,
+ }
+ with open(lib_name, 'w', encoding='utf-8') as f:
+ f.write(self.lib_template.format(**kwargs))
+ with open(test_name, 'w', encoding='utf-8') as f:
+ f.write(self.lib_test_template.format(**kwargs))
+ with open('meson.build', 'w', encoding='utf-8') as f:
+ f.write(self.lib_meson_template.format(**kwargs))