Merge pull request #8680 from dcbaker/submit/wrap-mconf-output

Wrap mconf output
pull/8701/head
Jussi Pakkanen 4 years ago committed by GitHub
commit 8de47b688a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 63
      mesonbuild/mconf.py

@ -12,11 +12,19 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import itertools
import shutil
import os
from . import coredata, environment, mesonlib, build, mintro, mlog
from .ast import AstIDGenerator
import textwrap
import typing as T
from . import build
from . import coredata
from . import environment
from . import mesonlib
from . import mintro
from . import mlog
from .ast import AstIDGenerator
from .mesonlib import MachineChoice, OptionKey
if T.TYPE_CHECKING:
@ -53,6 +61,7 @@ class Conf:
self.value_col = []
self.choices_col = []
self.descr_col = []
# XXX: is there a case where this can actually remain false?
self.has_choices = False
self.all_subprojects: T.Set[str] = set()
self.yielding_options: T.Set[OptionKey] = set()
@ -92,16 +101,54 @@ class Conf:
# are erased when Meson is executed the next time, i.e. when
# Ninja is run.
def print_aligned(self):
col_widths = (max([len(i) for i in self.name_col], default=0),
max([len(i) for i in self.value_col], default=0),
max([len(i) for i in self.choices_col], default=0))
def print_aligned(self) -> None:
"""Do the actual printing.
This prints the generated output in an aligned, pretty form. it aims
for a total width of 160 characters, but will use whatever the tty
reports it's value to be. Though this is much wider than the standard
80 characters of terminals, and even than the newer 120, compressing
it to those lengths makes the output hard to read.
Each column will have a specific width, and will be line wrapped.
"""
total_width = shutil.get_terminal_size(fallback=(160, 0))[0]
_col = max(total_width // 5, 20)
four_column = (_col, _col, _col, total_width - (3 * _col))
# In this case we don't have the choices field, so we can redistribute
# the extra 40 characters to val and desc
three_column = (_col, _col * 2, total_width // 2)
for line in zip(self.name_col, self.value_col, self.choices_col, self.descr_col):
if not any(line):
print('')
continue
# This is a header, like `Subproject foo:`,
# We just want to print that and get on with it
if line[0] and not any(line[1:]):
print(line[0])
continue
# wrap will take a long string, and create a list of strings no
# longer than the size given. Then that list can be zipped into, to
# print each line of the output, such the that columns are printed
# to the right width, row by row.
if self.has_choices:
print('{0:{width[0]}} {1:{width[1]}} {2:{width[2]}} {3}'.format(*line, width=col_widths))
name = textwrap.wrap(line[0], four_column[0])
val = textwrap.wrap(line[1], four_column[1])
choice = textwrap.wrap(line[2], four_column[2])
desc = textwrap.wrap(line[3], four_column[3])
for l in itertools.zip_longest(name, val, choice, desc, fillvalue=''):
# We must use the length modifier here to get even rows, as
# `textwrap.wrap` will only shorten, not lengthen each item
print('{:{widths[0]}} {:{widths[1]}} {:{widths[2]}} {}'.format(*l, widths=four_column))
else:
print('{0:{width[0]}} {1:{width[1]}} {3}'.format(*line, width=col_widths))
name = textwrap.wrap(line[0], three_column[0])
val = textwrap.wrap(line[1], three_column[1])
desc = textwrap.wrap(line[3], three_column[2])
for l in itertools.zip_longest(name, val, desc, fillvalue=''):
print('{:{widths[0]}} {:{widths[1]}} {}'.format(*l, widths=three_column))
def split_options_per_subproject(self, options: 'coredata.KeyedOptionDictType') -> T.Dict[str, T.Dict[str, 'UserOption']]:
result: T.Dict[str, T.Dict[str, 'UserOption']] = {}

Loading…
Cancel
Save