Repository: mesonbuild/meson

Issue:
`meson configure` output formatting unreadable
In meson version 0.54.0 the output of `meson configure` (in build dir) to the terminal became unreadable due to seemingly broken spacing between columns and description text does not staying in it's column if more than one line is required to display it.

Here are a screenshots of how it looks for me currently:
![image](https://user-images.githubusercontent.com/18723421/79107987-50e03680-7d6d-11ea-8420-2df468e1546c.png)
![image](https://user-images.githubusercontent.com/18723421/79108225-cb10bb00-7d6d-11ea-9f9b-33ace7aa1a62.png)

I believe that in earlier versions there was no such problem, and the formatting started to change since 0.53, but was still readable until now. So if nothing else, it would be nice if it could be rolled back to pre-0.53 state.


Discussion:
What changed is columns are aligned across all sections, before they were aligned per section. You probably have one line with a very long value.

Personally I have an alias that does `meson configure builddir | less -RS`, I think we should make that built-in like most git commands. We could also be a little bit smarter on line wraps, I guess.
Wrapping long values and long explanations seems like the obvious thing to do.

Look at this `meson configure` output from Mesa with Meson 0.56.0:
```
Core properties:
  Source dir /home/pq/git/mesa
  Build dir  /home/pq/build/mesa
                                                                                                                                                                                                                                                                      
Main project options:                                                                                                                                                                                                                                                 
                                                                                                                                                                                                                                                                      
  Core options               Current Value                                                                                                                                                              Possible Values                                               Description
  ------------               -------------                                                                                                                                                              ---------------                                               -----------
  auto_features              auto                                                                                                                                                                       [enabled, disabled, auto]                                     Override value of all 'auto' features
  backend                    ninja                                                                                                                                                                      [ninja, vs, vs2010, vs2015, vs2017, vs2019, xcode]            Backend to use
  buildtype                  debug                                                                                                                                                                      [plain, debug, debugoptimized, release, minsize, custom]      Build type to use
  debug                      true                                                                                                                                                                       [true, false]                                                 Debug
  default_library            shared                                                                                                                                                                     [shared, static, both]                                        Default library type
  force_fallback_for         []                                                                                                                                                                                                                                       Force fallback for those subprojects
  install_umask              0022                                                                                                                                                                       [preserve, 0000-0777]                                         Default umask to apply on permissions of installed files
  layout                     mirror                                                                                                                                                                     [mirror, flat]                                                Build directory layout
  optimization               0                                                                                                                                                                          [0, g, 1, 2, 3, s]                                            Optimization level
  strip                      false                                                                                                                                                                      [true, false]                                                 Strip targets on install
  unity                      off                                                                                                                                                                        [on, off, subprojects]                                        Unity build
  unity_size                 4                                                                                                                                                                          >=2                                                           Unity block size
  warning_level              1                                                                                                                                                                          [0, 1, 2, 3]                                                  Compiler warning level to use
  werror                     false                                                                                                                                                                      [true, false]                                                 Treat warnings as errors
  wrap_mode                  default                                                                                                                                                                    [default, nofallback, nodownload, forcefallback]              Wrap mode
  cmake_prefix_path          []                                                                                                                                                                                                                                       List of additional prefixes for cmake to search
  pkg_config_path            [/home/pq/install/xkbcommon/lib/x86_64-linux-gnu/pkgconfig, /home/pq/local/lib/pkgconfig/, /home/pq/local/lib/x86_64-linux-gnu/pkgconfig, /home/pq/local/share/pkgconfig/]                                                               List of additional paths for pkg-config to search
                                                                                                                                                                                                                                                                      
  Backend options            Current Value                                                                                                                                                              Possible Values                                               Description
  ---------------            -------------                                                                                                                                                              ---------------                                               -----------
  backend_max_links          0                                                                                                                                                                          >=0                                                           Maximum number of linker processes to run or 0 for no limit
                                                                                                                                                                                                                                                                      
  Base options               Current Value                                                                                                                                                              Possible Values                                               Description
  ------------               -------------                                                                                                                                                              ---------------                                               -----------
  b_asneeded                 true                                                                                                                                                                       [true, false]                                                 Use -Wl,--as-needed when linking
  b_colorout                 always                                                                                                                                                                     [auto, always, never]                                         Use colored output
  b_coverage                 false                                                                                                                                                                      [true, false]                                                 Enable coverage tracking.
  b_lto                      false                                                                                                                                                                      [true, false]                                                 Use link time optimization
  b_lundef                   true                                                                                                                                                                       [true, false]                                                 Use -Wl,--no-undefined when linking
  b_ndebug                   if-release                                                                                                                                                                 [true, false, if-release]                                     Disable asserts
  b_pch                      true                                                                                                                                                                       [true, false]                                                 Use precompiled headers
  b_pgo                      off                                                                                                                                                                        [off, generate, use]                                          Use profile guided optimization
  b_pie                      false                                                                                                                                                                      [true, false]                                                 Build executables as position independent
  b_sanitize                 none                                                                                                                                                                       [none, address, thread, undefined, memory, address,undefined] Code sanitizer to use
  b_staticpic                true                                                                                                                                                                       [true, false]                                                 Build static libraries as position independent
                                                                                                                                                                                                                                                                      
  Compiler options           Current Value                                                                                                                                                              Possible Values                                               Description
  ----------------           -------------                                                                                                                                                              ---------------                                               -----------
  c_args                     []                                                                                                                                                                                                                                       Extra arguments passed to the c compiler
  c_link_args                []                                                                                                                                                                                                                                       Extra arguments passed to the c linker
  c_std                      c99                                                                                                                                                                        [none, c89, c99, c11, c17, c18, gnu89, gnu99, gnu11, gnu17,   C language standard to use
                                                                                                                                                                                                         gnu18]                                                       
  cpp_args                   []                                                                                                                                                                                                                                       Extra arguments passed to the cpp compiler
  cpp_debugstl               false                                                                                                                                                                      [true, false]                                                 STL debug mode
  cpp_eh                     default                                                                                                                                                                    [none, default, a, s, sc]                                     C++ exception handling type.
  cpp_link_args              []                                                                                                                                                                                                                                       Extra arguments passed to the cpp linker
  cpp_rtti                   true                                                                                                                                                                       [true, false]                                                 Enable RTTI
  cpp_std                    c++14                                                                                                                                                                      [none, c++98, c++03, c++11, c++14, c++17, c++1z, c++2a,       C++ language standard to use
                                                                                                                                                                                                         gnu++03, gnu++11, gnu++14, gnu++17, gnu++1z, gnu++2a]        
                                                                                                                                                                                                                                                                      
  Directories                Current Value                                                                                                                                                              Possible Values                                               Description
  -----------                -------------                                                                                                                                                              ---------------                                               -----------
  bindir                     bin                                                                                                                                                                                                                                      Executable directory
  datadir                    share                                                                                                                                                                                                                                    Data file directory
  includedir                 include                                                                                                                                                                                                                                  Header file directory
  infodir                    share/info                                                                                                                                                                                                                               Info page directory
  libdir                     lib/x86_64-linux-gnu                                                                                                                                                                                                                     Library directory
  libexecdir                 libexec                                                                                                                                                                                                                                  Library executable directory
  localedir                  share/locale                                                                                                                                                                                                                             Locale data directory
  localstatedir              var                                                                                                                                                                                                                                      Localstate data directory
  mandir                     share/man                                                                                                                                                                                                                                Manual page directory
  prefix                     /home/pq/local                                                                                                                                                                                                                           Installation prefix
  sbindir                    sbin                                                                                                                                                                                                                                     System executable directory
  sharedstatedir             com                                                                                                                                                                                                                                      Architecture-independent data directory
  sysconfdir                 etc                                                                                                                                                                                                                                      Sysconf data directory
                                                                                                                                                                                                                                                                      
  Testing options            Current Value                                                                                                                                                              Possible Values                                               Description
  ---------------            -------------                                                                                                                                                              ---------------                                               -----------
  errorlogs                  true                                                                                                                                                                       [true, false]                                                 Whether to print the logs from failing tests
  stdsplit                   true                                                                                                                                                                       [true, false]                                                 Split stdout and stderr in test logs
                                                                                                                                                                                                                                                                      
  Project options            Current Value                                                                                                                                                              Possible Values                                               Description
  ---------------            -------------                                                                                                                                                              ---------------                                               -----------
  android-stub               false                                                                                                                                                                      [true, false]                                                 Build against android-stub
  build-aco-tests            false                                                                                                                                                                      [true, false]                                                 Build ACO tests. These require RADV and glslang but not an AMD GPU.
  build-tests                false                                                                                                                                                                      [true, false]                                                 Build unit tests. Currently this will build *all* unit tests except the ACO tests, which may build more than expected.
  d3d-drivers-path                                                                                                                                                                                                                                                    Location of D3D drivers. Default: $libdir/d3d
  draw-use-llvm              true                                                                                                                                                                       [true, false]                                                 Whether to use LLVM for the Gallium draw module, if LLVM is included.
  dri-drivers                [i965]                                                                                                                                                                     [auto, i915, i965, r100, r200, nouveau]                       List of dri drivers to build. If this is set to auto all drivers applicable to the target OS/architecture will be built
  dri-drivers-path                                                                                                                                                                                                                                                    Location to install dri drivers. Default: $libdir/dri.
  dri-search-path                                                                                                                                                                                                                                                     Locations to search for dri drivers, passed as colon separated list. Default: dri-drivers-path.
  dri3                       auto                                                                                                                                                                       [auto, true, false, disabled, enabled]                        enable support for dri3
  egl                        auto                                                                                                                                                                       [auto, true, false, enabled, disabled]                        Build support for EGL platform
  egl-lib-suffix                                                                                                                                                                                                                                                      Suffix to append to EGL library name.  Default: none.
  enable-glcpp-tests         true                                                                                                                                                                       [true, false]                                                 Build glcpp unit tests. These are flaky on CI.
  freedreno-kgsl             false                                                                                                                                                                      [true, false]                                                 use kgsl backend for freedreno vulkan driver
  gallium-drivers            [swrast, radeonsi]                                                                                                                                                         [auto, kmsro, radeonsi, r300, r600, nouveau, freedreno,       List of gallium drivers to build. If this is set to auto all drivers applicable to the target OS/architecture will be built
                                                                                                                                                                                                         swrast, v3d, vc4, etnaviv, tegra, i915, svga, virgl, swr,    
                                                                                                                                                                                                         panfrost, iris, lima, zink, d3d12]                           
  gallium-extra-hud          false                                                                                                                                                                      [true, false]                                                 Enable HUD block/NIC I/O HUD status support
  gallium-nine               false                                                                                                                                                                      [true, false]                                                 build gallium "nine" Direct3D 9.x frontend.
  gallium-omx                auto                                                                                                                                                                       [auto, disabled, bellagio, tizonia]                           enable gallium omx frontend.
  gallium-opencl             disabled                                                                                                                                                                   [icd, standalone, disabled]                                   build gallium "clover" OpenCL frontend.
  gallium-va                 auto                                                                                                                                                                       [auto, true, false, enabled, disabled]                        enable gallium va frontend.
  gallium-vdpau              auto                                                                                                                                                                       [auto, true, false, enabled, disabled]                        enable gallium vdpau frontend.
  gallium-xa                 auto                                                                                                                                                                       [auto, true, false, enabled, disabled]                        enable gallium xa frontend.
  gallium-xvmc               auto                                                                                                                                                                       [auto, true, false, enabled, disabled]                        enable gallium xvmc frontend.
  gbm                        auto                                                                                                                                                                       [auto, true, false, enabled, disabled]                        Build support for gbm platform
  gles-lib-suffix                                                                                                                                                                                                                                                     Suffix to append to GLES library names.  Default: none.
  gles1                      auto                                                                                                                                                                       [auto, true, false, enabled, disabled]                        Build support for OpenGL ES 1.x
  gles2                      auto                                                                                                                                                                       [auto, true, false, enabled, disabled]                        Build support for OpenGL ES 2.x and 3.x
  glvnd                      false                                                                                                                                                                      [true, false]                                                 Enable GLVND support.
  glvnd-vendor-name          mesa                                                                                                                                                                                                                                     Vendor name string to use for glvnd libraries
  glx                        auto                                                                                                                                                                       [auto, disabled, dri, xlib, gallium-xlib]                     Build support for GLX platform
  glx-direct                 true                                                                                                                                                                       [true, false]                                                 Enable direct rendering in GLX and EGL for DRI
  glx-read-only-text         false                                                                                                                                                                      [true, false]                                                 Disable writable .text section on x86 (decreases performance)
  install-intel-gpu-tests    false                                                                                                                                                                      [true, false]                                                 Build and install Intel unit tests which require the GPU.  This option is for developers and the Intel CI system only.
  libunwind                  auto                                                                                                                                                                       [auto, true, false, enabled, disabled]                        Use libunwind for stack-traces
  llvm                       auto                                                                                                                                                                       [auto, true, false, enabled, disabled]                        Build with LLVM support.
  lmsensors                  auto                                                                                                                                                                       [auto, true, false, enabled, disabled]                        Enable HUD lmsensors support.
  microsoft-clc              auto                                                                                                                                                                       [enabled, disabled, auto]                                     Build support for the Microsoft CLC to DXIL compiler
  omx-libs-path                                                                                                                                                                                                                                                       path to put omx libraries. defaults to omx-bellagio pkg-config pluginsdir.
  opencl-native              true                                                                                                                                                                       [true, false]                                                 build gallium "clover" OpenCL frontend with native LLVM codegen support.
  opencl-spirv               false                                                                                                                                                                      [true, false]                                                 build gallium "clover" OpenCL frontend with SPIR-V binary support.
  opengl                     true                                                                                                                                                                       [true, false]                                                 Build support for OpenGL (all versions)
  osmesa                     false                                                                                                                                                                      [true, false]                                                 Build OSmesa.
  osmesa-bits                8                                                                                                                                                                          [8, 16, 32]                                                   Number of channel bits for OSMesa.
  platform-sdk-version       25                                                                                                                                                                         >=25, <=28                                                    Android Platform SDK version. Default: Nougat version.
  platforms                  [auto]                                                                                                                                                                     [auto, x11, wayland, haiku, android, windows]                 window systems to support. If this is set to `auto`, all platforms applicable will be enabled.
  power8                     auto                                                                                                                                                                       [auto, true, false, enabled, disabled]                        Enable power8 optimizations.
  prefer-iris                true                                                                                                                                                                       [true, false]                                                 Prefer new Intel iris driver over older i965 driver
  selinux                    false                                                                                                                                                                      [true, false]                                                 Build an SELinux-aware Mesa
  shader-cache               auto                                                                                                                                                                       [auto, true, false, enabled, disabled]                        Build with on-disk shader cache support.
  shader-cache-default       true                                                                                                                                                                       [true, false]                                                 If set to false, the feature is only activated when environment variable MESA_GLSL_CACHE_DISABLE is set to false
  shader-cache-max-size                                                                                                                                                                                                                                               Default value for MESA_GLSL_CACHE_MAX_SIZE enviroment variable.
   If set, determines the maximum size of the on-disk cache of compiled
   GLSL programs, can be overriden by enviroment variable if needed. Should be set to a number optionally followed by
   ``K``, ``M``, or ``G`` to specify a size in kilobytes, megabytes, or
   gigabytes. By default, gigabytes will be assumed. And if unset, a
   maximum size of 1GB will be used.
  shared-glapi               auto                                                                                                                                                                       [auto, true, false, enabled, disabled]                        Whether to build a shared or static glapi. Defaults to false on Windows, true elsewhere
  shared-llvm                auto                                                                                                                                                                       [auto, true, false, enabled, disabled]                        Whether to link LLVM shared or statically.
  shared-swr                 true                                                                                                                                                                       [true, false]                                                 Whether to link SWR shared or statically.
  spirv-to-dxil              false                                                                                                                                                                      [true, false]                                                 Build support for the SPIR-V to DXIL library
  sse2                       true                                                                                                                                                                       [true, false]                                                 use msse2 flag for mingw x86. Default: true
  static-libclc              []                                                                                                                                                                         [spirv, spirv64, all]                                         Link libclc SPIR-V statically.
  swr-arches                 [avx, avx2]                                                                                                                                                                [avx, avx2, knl, skx]                                         Architectures to build SWR support for.
  tools                      []                                                                                                                                                                         [drm-shim, etnaviv, freedreno, glsl, intel, intel-ui, nir,    List of tools to build. (Note: `intel-ui` selects `intel`)
                                                                                                                                                                                                         nouveau, xvmc, lima, panfrost, all]                          
  va-libs-path                                                                                                                                                                                                                                                        path to put va libraries. defaults to $libdir/dri.
  valgrind                   auto                                                                                                                                                                       [auto, true, false, enabled, disabled]                        Build with valgrind support
  vdpau-libs-path                                                                                                                                                                                                                                                     path to put vdpau libraries. defaults to $libdir/vdpau.
  vulkan-device-select-layer false                                                                                                                                                                      [true, false]                                                 Whether to build the vulkan device select layer
  vulkan-drivers             [intel]                                                                                                                                                                    [auto, amd, broadcom, freedreno, intel, swrast]               List of vulkan drivers to build. If this is set to auto all drivers applicable to the target OS/architecture will be built
  vulkan-icd-dir                                                                                                                                                                                                                                                      Location relative to prefix to put vulkan icds on install. Default: $datadir/vulkan/icd.d
  vulkan-overlay-layer       false                                                                                                                                                                      [true, false]                                                 Whether to build the vulkan overlay layer
  xlib-lease                 auto                                                                                                                                                                       [auto, true, false, enabled, disabled]                        Enable VK_EXT_acquire_xlib_display.
  xvmc-libs-path                                                                                                                                                                                                                                                      path to put xvmc libraries. defaults to $libdir.
  zlib                       enabled                                                                                                                                                                    [enabled, disabled, auto]                                     Use ZLIB to build driver. Default: enabled
  zstd                       auto                                                                                                                                                                       [auto, true, false, enabled, disabled]                        Use ZSTD instead of ZLIB in some cases.
```

That takes a terminal of roughly 400 characters wide to show up properly.

Resolving patch:
diff --git a/mesonbuild/mconf.py b/mesonbuild/mconf.py
--- a/mesonbuild/mconf.py
+++ b/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 @@ def __init__(self, build_dir):
         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 @@ def save(self):
         # 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']] = {}
@@ -228,8 +275,10 @@ def print_default_values_warning():
             if subproject == '':
                 continue
             self.add_section('Subproject ' + subproject)
-            if subproject in core_options:
-                self.print_options('Core options', core_options[subproject])
+            if subproject in host_core_options:
+                self.print_options('Core options', host_core_options[subproject])
+            if subproject in build_core_options and show_build_options:
+                self.print_options('', build_core_options[subproject])
             if subproject in host_compiler_options:
                 self.print_options('Compiler options', host_compiler_options[subproject])
             if subproject in build_compiler_options and show_build_options:


Test patch: