webhintio / hint

💡 A hinting engine for the web
https://webhint.io/
Apache License 2.0
3.63k stars 685 forks source link

JSON output is not valid JSON #5081

Open egrieco opened 2 years ago

egrieco commented 2 years ago

🐞 Bug report

Description

JSON output is not valid JSON

Expectation

JSON output should be well formed and thus parseable by tools such as jq. The whole point of JSON output is to make it machine readable to facilitate use in automation pipelines.

Actual Behavior

  1. JSON output is interspersed with bare text (file URLs with error counts appended).
  2. Further, messages to the user are printed to STDOUT rather than STDERR.

Details

webhint version: v6.1.10 .hintrc: None provided. Using internal defaults.

Webhint Output

Using the built-in configuration.
Visit https://webhint.io/docs/user-guide/ to learn how to create your own configuration.
file:///Users/USER/Projects/test-site/games.css: 1 issues
[
  {
    "category": "compatibility",
    "codeLanguage": "css",
    "documentation": [
      {
        "link": "https://developer.mozilla.org/docs/Web/CSS/position",
        "text": "Learn more about this CSS feature on MDN"
      }
    ],
    "hintId": "compat-api/css",
    "location": {
      "column": 14,
      "endColumn": 20,
      "endLine": 23,
      "line": 23
    },
    "message": "'position: sticky' is not supported by Internet Explorer, Safari on iOS < 13. Add 'position: -webkit-sticky' to support Safari on iOS 7+.",
    "resource": "file:///Users/USER/Projects/test-site/games.css",
    "severity": 4,
    "sourceCode": ".navbar {\n    position: sticky;\n}"
  }
]

file:///Users/USER/Projects/test-site/games.html: 1 issues
[
  {
    "category": "compatibility",
    "hintId": "meta-viewport",
    "location": {
      "column": -1,
      "line": -1
    },
    "message": "A 'viewport' meta element was not specified.",
    "resource": "file:///Users/USER/Projects/test-site/games.html",
    "severity": 4,
    "sourceCode": ""
  }
]
captainbrosset commented 2 years ago

Thanks for reaching out. The JSON formatter does output valid JSON because it uses JSON.stringify, but the issue comes from the fact that it does it per file, and generates one JSON object for each one, with raw text in between, as you noted.

I wonder if there is a way to configure a custom formatter. The formatters array in .hintrc might already support, I'm not sure. @antross would definitely know. If it does support it, then you would be able to build your own JSON formatter that output 1 unique JSON object for the whole report.

egrieco commented 2 years ago

Just need to ensure that there are no bare strings (can't do comments in JSON sadly), and put commas between the JSON blocks. Then just enclose the whole set in brackets and everything is good.

I've used grep and awk to fix broken JSON output like this in the past.

captainbrosset commented 2 years ago

Yeah, I understand this. My concern with just changing the current JSON formatter though is that it might be used by people already and changing it might break their workflows. Maybe that's fine, but I just don't feel like we should do it without a conscious decision. So, the solution I'm seeing here is: either make the formatters array in .hintrc accept custom formatters. Or create another built-in formatter that produces real JSON.

egrieco commented 2 years ago

Yeah, it's not a bad idea to obey Postel's Law.

It really is a shame that JSON is such a brittle language. Comment support alone, would make it far more workable. Though I guess it could be worse, we could all still be munging XML with XSLT :shudder:.

captainbrosset commented 2 years ago

@vidorteg hey Vidal, would you have some time to take a look at the formatters configuration and seeing if it already accept custom formatters or not?

vidorteg commented 1 year ago

I took a quick look and as along as it implements the IFormatter interface and has the following naming convention package/formatter-{name} you should be able to create and use your custom formatter. You can take a look here on how it was implemented for JSON:

https://github.com/webhintio/hint/tree/main/packages/formatter-json