diff options
Diffstat (limited to 'mesonbuild/interpreter.py')
-rw-r--r-- | mesonbuild/interpreter.py | 66 |
1 files changed, 64 insertions, 2 deletions
diff --git a/mesonbuild/interpreter.py b/mesonbuild/interpreter.py index d7f826c..a8e35fe 100644 --- a/mesonbuild/interpreter.py +++ b/mesonbuild/interpreter.py @@ -38,7 +38,7 @@ from pathlib import Path, PurePath import os, shutil, uuid import re, shlex import subprocess -from collections import namedtuple +import collections from itertools import chain import functools from typing import Sequence, List, Union, Optional, Dict, Any @@ -1691,7 +1691,7 @@ class CompilerHolder(InterpreterObject): return self.compiler.get_argument_syntax() -ModuleState = namedtuple('ModuleState', [ +ModuleState = collections.namedtuple('ModuleState', [ 'source_root', 'build_to_src', 'subproject', 'subdir', 'current_lineno', 'environment', 'project_name', 'project_version', 'backend', 'targets', 'data', 'headers', 'man', 'global_args', 'project_args', 'build_machine', @@ -1751,6 +1751,40 @@ class ModuleHolder(InterpreterObject, ObjectHolder): raise InterpreterException('Extension module altered internal state illegally.') return self.interpreter.module_method_callback(value) + +class Summary: + def __init__(self, project_name, project_version): + self.project_name = project_name + self.project_version = project_version + self.sections = collections.defaultdict(dict) + self.max_key_len = 0 + + def add_section(self, section, values): + for k, v in values.items(): + if k in self.sections[section]: + raise InterpreterException('Summary section {!r} already have key {!r}'.format(section, k)) + v = listify(v) + for i in v: + if not isinstance(i, (str, int)): + m = 'Summary value in section {!r}, key {!r}, must be string, integer or boolean' + raise InterpreterException(m.format(section, k)) + self.sections[section][k] = v + self.max_key_len = max(self.max_key_len, len(k)) + + def dump(self): + mlog.log(self.project_name, mlog.normal_cyan(self.project_version)) + for section, values in self.sections.items(): + mlog.log('') # newline + mlog.log(' ', mlog.bold(section)) + for k, v in values.items(): + indent = self.max_key_len - len(k) + 3 + mlog.log(' ' * indent, k + ':', v[0]) + indent = self.max_key_len + 5 + for i in v[1:]: + mlog.log(' ' * indent, i) + mlog.log('') # newline + + class MesonMain(InterpreterObject): def __init__(self, build, interpreter): InterpreterObject.__init__(self) @@ -2078,6 +2112,7 @@ class Interpreter(InterpreterBase): self.coredata = self.environment.get_coredata() self.backend = backend self.subproject = subproject + self.summary = {} if modules is None: self.modules = {} else: @@ -2188,6 +2223,7 @@ class Interpreter(InterpreterBase): 'subdir': self.func_subdir, 'subdir_done': self.func_subdir_done, 'subproject': self.func_subproject, + 'summary': self.func_summary, 'shared_library': self.func_shared_lib, 'shared_module': self.func_shared_module, 'static_library': self.func_static_lib, @@ -2594,6 +2630,7 @@ external dependencies (including libraries) must go to "dependencies".''') self.build_def_files = list(set(self.build_def_files + subi.build_def_files)) self.build.merge(subi.build) self.build.subprojects[dirname] = subi.project_version + self.summary.update(subi.summary) return self.subprojects[dirname] def _do_subproject_cmake(self, dirname, subdir, subdir_abs, default_options, kwargs): @@ -2830,6 +2867,29 @@ external dependencies (including libraries) must go to "dependencies".''') def message_impl(self, argstr): mlog.log(mlog.bold('Message:'), argstr) + @noArgsFlattening + @noKwargs + @FeatureNew('summary', '0.53.0') + def func_summary(self, node, args, kwargs): + if len(args) != 2: + raise InterpreterException('Summary accepts exactly two arguments.') + section, values = args + if not isinstance(section, str): + raise InterpreterException('Argument 1 must be a string.') + if not isinstance(values, dict): + raise InterpreterException('Argument 2 must be a dictionary.') + if self.subproject not in self.summary: + self.summary[self.subproject] = Summary(self.active_projectname, self.project_version) + self.summary[self.subproject].add_section(section, values) + + def _print_summary(self): + mlog.log('') # newline + main_summary = self.summary.pop('', None) + for _, summary in sorted(self.summary.items()): + summary.dump() + if main_summary: + main_summary.dump() + @FeatureNew('warning', '0.44.0') @noKwargs def func_warning(self, node, args, kwargs): @@ -4070,6 +4130,8 @@ different subdirectory. FeatureDeprecated.report(self.subproject) if not self.is_subproject(): self.print_extra_warnings() + if self.subproject == '': + self._print_summary() def print_extra_warnings(self): # TODO cross compilation |