grafana/grizzly

[Feature Request]: Escape multiline values of specific fields under dashboard yaml

Closed this issue · 5 comments

Feature Request

Hello,
We really appreciate the latest developments. It has been really much of a quality of life improvement lately.

Limitation

We have been using serve functionality quite a while, and it has been our go-to way of QA process of dashboards. When reviwing, one limitation we are experiencing is:

  • When we save panel SQL or markdown description change, diff is quite hard to follow on both diff checkers (Gitlab and VSCode diff checker), because the yaml serializers saves the multiline strings as json value rather then escaped yaml value.
  • As a workaround, the reviewer either reviews the changed SQL completely, or uses some in-shell tooling to manually do diff check. Possibly another workaround is using some tooling for pre-commit hook of the repo, but this seems not maintainable.

Context

As a context, I can provide samples below for sample diff check sources

Example below could be diffed very well because the content part is lined well, easier to check when there are changes in specific lines.

         .....
          options:
            code:
                language: plaintext
                showLineNumbers: false
                showMiniMap: false
            content: |
                ## Great header
                A good release note can be here. 
                
                ### Great subheader
                Some text to put.
            mode: markdown
            .....

Example below is how Grizzly serve (saving functionality) behaves and it has way much friction when doing a diff check.

         .....
          options:
            code:
                language: plaintext
                showLineNumbers: false
                showMiniMap: false
            content: "## Great header\nA good release note can be here. \n\n### Great subheader\nSome text to put."
            mode: markdown
            .....

Save functionality has a similar behavior in rawSQL of panels.

Unfortunately, there's not much we can do to help here. YAML is clearly easier on the eyes in diffs than JSON, especially when you have multi-line strings present. However, the state of YAML parsing (and rendering) in Golang is poor, each library having its own particular inconsistencies. Also, given Grizzly is a generic tool (i.e. not dashboard specific), we can't easily give it any assistance in terms of how to marshal specific elements within the dashboard, as we treat the dashboard itself just as a JSON blob.

Unfortunately, there's not much we can do to help here. YAML is clearly easier on the eyes in diffs than JSON, especially when you have multi-line strings present. However, the state of YAML parsing (and rendering) in Golang is poor, each library having its own particular inconsistencies. Also, given Grizzly is a generic tool (i.e. not dashboard specific), we can't easily give it any assistance in terms of how to marshal specific elements within the dashboard, as we treat the dashboard itself just as a JSON blob.

I totally understand it. I think what we should do is: to use our own tooling for making diffs better.

If you come up with anything, do share it here, perhaps it could be useful for others too.

I came up by creating my own tooling for linting the dashboard file and enforcing part of the values to be yaml multiline escape.

So within golang yaml library (gopkg.in/yaml.v3) if there is a whitespace before \n it does not apply multiline escape.

  • Replace all "\r\n"s with "\n"s (This might not be necessary, but I find it better since we have multiple os'es working on dashboards.)
  • Right trim every lines of "rawSQL" values and "options.content" values with cutset=" ", and join with "\n" again. This implicitly leads marshaller to use multi-line escape.

Of course this might not be ideal for some SQLs if there is "linebreak after newline" in-between a literal, but it seems not a case for my case indeed.

When we add this golang program as a pre-commit hook to repository, the problem is resolved.

Glad you found a solution.

As YAML marshalling is hard, we're not going to change the behavior of Grizzly right now.