Skip to content

RFC: change default for logging to +nowrap #5488

Open
@hvr

Description

@hvr

I'm curious what others think about this, hence I'm putting this up for discussion. And being biased, I'm also specifically interested in hearing about reasons why +nowrap is undesirable.

By default, cabal line-wraps its logging output to hardcoded line-length of 79 characters via wrapText:

-- | Wraps text to the default line width. Existing newlines are preserved.
wrapText :: String -> String
wrapText = unlines
. map (intercalate "\n"
. map unwords
. wrapLine 79
. words)
. lines
-- | Wraps a list of words to a list of lines of words of a particular width.
wrapLine :: Int -> [String] -> [[String]]
wrapLine width = wrap 0 []
where wrap :: Int -> [String] -> [String] -> [[String]]
wrap 0 [] (w:ws)
| length w + 1 > width
= wrap (length w) [w] ws
wrap col line (w:ws)
| col + length w + 1 > width
= reverse line : wrap 0 [] (w:ws)
wrap col line (w:ws)
= let col' = col + length w + 1
in wrap col' (w:line) ws
wrap _ [] [] = []
wrap _ line [] = [reverse line]

In #4091, a verbosity level modified +nowrap was introduced which suppresses this line-wrapping;

IMO, having cabal pre-linewrap its output interacts badly with terminals or editors if these re-wrap dynamically when resizing the window, readability is IMHO not improved by line-wrapping, and it makes it harder to copy and paste as the terminal can't easily reconstruct the original log message's line endings, and thus the pre-wrapped text is copy-n-pasted into the target including the line-wrapping (which may again not be adequate for the target text-body width).

As an example, this here is a solver failure pre-wrapped via wrapText

$ cabal new-repl -w ghc-8.6.1 --build-depends 'lens'
Resolving dependencies...
cabal: Could not resolve dependencies:
[__0] trying: fake-package-0 (user goal)
[__1] trying: lens-4.17 (dependency of fake-package)
[__2] trying: transformers-0.5.5.0/installed-0.5... (dependency of lens)
[__3] next goal: hashable (dependency of lens)
[__3] rejecting: hashable-1.2.7.0 (conflict: transformers =>
base==4.12.0.0/installed-4.1..., hashable => base>=4.4 && <4.12)
[__3] rejecting: hashable-1.2.6.1 (conflict: transformers =>
base==4.12.0.0/installed-4.1..., hashable => base>=4.4 && <4.11)
[__3] rejecting: hashable-1.2.6.0 (conflict: transformers =>
base==4.12.0.0/installed-4.1..., hashable => base>=4.4 && <4.10)
[__3] rejecting: hashable-1.2.5.0, hashable-1.2.4.0 (conflict: transformers =>
base==4.12.0.0/installed-4.1..., hashable => base>=4.0 && <4.10)
[__3] rejecting: hashable-1.2.3.3, hashable-1.2.3.2 (conflict: transformers =>
base==4.12.0.0/installed-4.1..., hashable => base>=4.0 && <4.9)
[__3] rejecting: hashable-1.2.3.1, hashable-1.2.3.0, hashable-1.2.2.0,
hashable-1.2.1.0, hashable-1.2.0.10, hashable-1.2.0.9, hashable-1.2.0.8,
hashable-1.2.0.7, hashable-1.2.0.6, hashable-1.2.0.5, hashable-1.2.0.4,
hashable-1.2.0.3, hashable-1.2.0.2, hashable-1.2.0.1, hashable-1.2.0.0,
hashable-1.1.2.5, hashable-1.1.2.4, hashable-1.1.2.3 (conflict: transformers
=> base==4.12.0.0/installed-4.1..., hashable => base>=4.0 && <4.8)
[__3] rejecting: hashable-1.1.2.2, hashable-1.1.2.1, hashable-1.1.2.0,
hashable-1.1.1.0, hashable-1.1.0.0, hashable-1.0.1.1, hashable-1.0.1.0,
hashable-1.0.0 (conflict: lens => hashable>=1.1.2.3 && <1.3)
[__3] fail (backjumping, conflict set: hashable, lens, transformers)
After searching the rest of the dependency tree exhaustively, these were the
goals I've had most trouble fulfilling: hashable, lens, base, transformers,
fake-package

...and the same with +nowrap:


$ cabal new-repl -w ghc-8.6.1 --build-depends 'lens' -vnormal+nowrap
Resolving dependencies...
cabal: Could not resolve dependencies:
[__0] trying: fake-package-0 (user goal)
[__1] trying: lens-4.17 (dependency of fake-package)
[__2] trying: transformers-0.5.5.0/installed-0.5... (dependency of lens)
[__3] next goal: hashable (dependency of lens)
[__3] rejecting: hashable-1.2.7.0 (conflict: transformers => base==4.12.0.0/installed-4.1..., hashable => base>=4.4 && <4.12)
[__3] rejecting: hashable-1.2.6.1 (conflict: transformers => base==4.12.0.0/installed-4.1..., hashable => base>=4.4 && <4.11)
[__3] rejecting: hashable-1.2.6.0 (conflict: transformers => base==4.12.0.0/installed-4.1..., hashable => base>=4.4 && <4.10)
[__3] rejecting: hashable-1.2.5.0, hashable-1.2.4.0 (conflict: transformers => base==4.12.0.0/installed-4.1..., hashable => base>=4.0 && <4.10)
[__3] rejecting: hashable-1.2.3.3, hashable-1.2.3.2 (conflict: transformers => base==4.12.0.0/installed-4.1..., hashable => base>=4.0 && <4.9)
[__3] rejecting: hashable-1.2.3.1, hashable-1.2.3.0, hashable-1.2.2.0, hashable-1.2.1.0, hashable-1.2.0.10, hashable-1.2.0.9, hashable-1.2.0.8, hashable-1.2.0.7, hashable-1.2.0.6, hashable-1.2.0.5, hashable-1.2.0.4, hashable-1.2.0.3, hashable-1.2.0.2, hashable-1.2.0.1, hashable-1.2.0.0, hashable-1.1.2.5, hashable-1.1.2.4, hashable-1.1.2.3 (conflict: transformers => base==4.12.0.0/installed-4.1..., hashable => base>=4.0 && <4.8)
[__3] rejecting: hashable-1.1.2.2, hashable-1.1.2.1, hashable-1.1.2.0, hashable-1.1.1.0, hashable-1.1.0.0, hashable-1.0.1.1, hashable-1.0.1.0, hashable-1.0.0 (conflict: lens => hashable>=1.1.2.3 && <1.3)
[__3] fail (backjumping, conflict set: hashable, lens, transformers)
After searching the rest of the dependency tree exhaustively, these were the goals I've had most trouble fulfilling: hashable, lens, base, transformers, fake-package

Personally, I consider the +nowrap version easier to parse visually, as it retains more of its original structure. I don't have to cognitively unwrap long lines into their original form to unpack the information.

...opinions?

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions