Um der Fehlermeldung auf die Spur zu kommen und natürlich auch, um diese loszuwerden, habe ich von dem Repo, den Quellcode der Erweiterung heruntergeladen. Im Prinzip besteht der Quellcode nur aus einer einzigen Datei, nämlich der package.json. Darin enthalten scheinen im Wesentlichen die Stringdefinitionen der problemMatcher. Das schliesse ich einfach daraus, dass es sich um genau die Eigenschaften handelt, die laut Microsoft Task Problem Matcher Doku für einen problemMatcher benötigt werden. Ohne Kenntnisse der Extension Entwicklung für VS Code kann ich mit der Vermutung natürlich auch falsch liegen. Aber die Settings lassen sich ja auch ausprobieren ohne die Extension erstellen zu müssen. Also ganz einfach die Settings für den problemMatcher aus der Extension kopiert in einem eigenen neuen Task (natürlich wieder in der tasks.json Datei):

      {
        "label": "Serve with own config",
        "type": "shell",
        "command": "bundle exec jekyll serve --livereload",
        "group": "test",
        "isBackground": true,
        "problemMatcher":  [
            {
              "owner": "jekyll",
              "severity": "warning",
              "fileLocation": "relative",
              "pattern": {
                "regexp": "^\\s*Liquid Warning: Liquid (?:syntax )?error \\(line (\\d+)\\): (.+) in (.+)$",
                "line": 1,
                "message": 2,
                "file": 3
              },
              "background": {
                "activeOnStart": true
            },
            {
              "owner": "jekyll",
              "severity": "error",
              "fileLocation": "relative",
              "pattern": {
                "regexp": "^\\s*Liquid Exception: Liquid (?:syntax )?error \\(line (\\d+)\\): (.+) in (.+)$",
                "line": 1,
                "message": 2,
                "file": 3
                },
                "background": {
                    "activeOnStart": true
                }
            }
          ]
      }

Dann einfach den Task gestartet, und Voila, es funktioniert genau wie der Problemmatcher aus der Erweiterung, auch die Fehlermeldung im Output erscheint genauso:

Task Serve with own config is a background task but uses a problem matcher without a background pattern

Soweit scheine ich damit auf der richtigen Spur zu sein. Zumindest kann ich mit meinem eher einfachen Plan das Problem nachstellen. Wie bereits im vorherigen Post geschrieben, gibt es eine Doku von Microsoft, nach der ein problemMatcher für einen Background Task auch ein ‘beginsPattern’ und ein ‘endsPattern’ benötigt. Die Fehlermeldung stösst einen ja praktisch mit der Nase drauf. Dort findet sich dieses Beispiel:

"background": {
    "activeOnStart": true,
    "beginsPattern": "^\\s*\\d{1,2}:\\d{1,2}:\\d{1,2}(?: AM| PM)? - File change detected\\. Starting incremental compilation\\.\\.\\.",
    "endsPattern": "^\\s*\\d{1,2}:\\d{1,2}:\\d{1,2}(?: AM| PM)? - Compilation complete\\. Watching for file changes\\."
}

Um meine Vermutung unmittelbar zu überprüfen, habe ich die Beispielpattern einfach in meinen neuen Task kopiert in der Eigenschaft “background” von dem problemMatcher. Danach habe ich den Hintergrundtask neu gestartet und die Fehlermeldung im Output ist direkt verschwunden. Die Ursache ist also genau wie vermutet gewesen, das verwendete Beispielpattern ist aber nicht die Lösung, da es die beschriebene Aufgabe, den Start und das Ende jeweils einer Ausführung des Hintergrundtasks nicht beschreibt.

Ein erfolgreicher Refresh ist dabei eher einfach beschrieben

      Regenerating: 1 file(s) changed at 2019-12-29 13:24:01
...
                    ...done in 0.202052878 seconds.

Natürlich kann die Anzahl der veränderten Dateien genauso wie der Zeitstempel variieren bei der Startzeile. Bei der Endzeile kann die Zeit natürlich auf variieren. Damit sehen die Pattern zum matchen etwa so aus:

    "beginsPattern": "^\\s+Regenerating:\\s\\d{1,4}\\sfile\\(s\\)\\schanged\\sat\\s[12][0-9]{3}-[01][0-9]-[0123][0-9]\\s.*$",
    "endsPattern": "^\\s+\\.\\.\\.done\\sin\\s\\d{1,}\\.\\d{4,}\\sseconds\\..*$"

Zum ausprobieren der Regex kann man etwa die Seite Regex-Tester nutzen. Alle Beispiele von Microsoft doppeln übrigens die ‘', was eigentlich nicht für die Regex erforderlich ist, aber nötig werden könnte, wenn das Ganze über die Shell interpretriert wird. VS Code braucht die Doppelung der ‘', da es sonst Fehlermeldungen hagelt.

Bei einem Fehler in der Liquid Syntax bricht der Lauf aber mit einer Fehlermeldung ab:

      Regenerating: 1 file(s) changed at 2019-12-30 12:50:37
...
             Error: Run jekyll build --trace for more information.

Also muss das endsPattern erweitert werden:

    "endsPattern": "^\\s+\\.\\.\\.done\\sin\\s\\d{1,}\\.\\d{4,}\\sseconds\\..*$|^\\s+Error:\\sRun\\sjekyll\\sbuild\\s--trace\\sfor\\smore\\sinformation\\..*$"

Damit werden dann erfolgreich die Ausgabezeilen sowohl eines erfolgreichen Laufs als auch eines fehlerhaften Laufs gematcht. Das funktioniert auch schon sehr gut, allerdings erscheint kein Fehler unter ‘Problems’ in VS Code. Das liegt wohl an den Regex zu matchen der Fehlermeldung. Wenn ich die ausprobiere bei mir, wird die tatsächliche Syntaxfehlermeldung nicht gematcht.

Wenn ich mir die vorhandene Regex anschaue, scheint die Meldung in frühreren Versionen ungefähr so ausgesehen zu haben:

  Liquid Exception: Liquid syntax error (line 5 in /home/dilb/harald-berghoff.de/_includes/header.html): Unknown tag 'blabla' included in /_layouts/default.html

In meiner Version erscheint die Fehlermeldung aber mit umgedrehter File und Zeilenangabe:

  Liquid Exception: Liquid syntax error (/home/dilb/harald-berghoff.de/_includes/header.html line 5): Unknown tag 'blabla' included in /_layouts/default.html

Um das Ganze wieder zu matchen, muss die Regex wie unten gezeigt umgestellt werden, da sich die Zeilen für Exceptions und Warnings in der alten Version nur genau in diesem Wort unterschieden haben, gehe ich davon aus, dass das in der neuen Version auch so ist.

  "regexp": "^\\s*Liquid Exception: Liquid (?:syntax )?error \\((.*) line ([0-9]{1,})\\): (.*)$"

Die komplette Konfiguration des Task in meiner tasks.json sieht damit so aus:

      {
        "label": "Serve with own config",
        "type": "shell",
        "command": "bundle exec jekyll serve --livereload",
        "group": "test",
        "isBackground": true,
        "problemMatcher":  [
            {
              "owner": "jekyll",
              "severity": "warning",
              "fileLocation": "absolute",
              "pattern": {
                "regexp": "^\\s*Liquid Warning: Liquid (?:syntax )?error \\((.*) line ([0-9]{1,})\\): (.*)$",
                "line": 2,
                "message": 2,
                "file": 1
              },
              "background": {
                "activeOnStart": true,
                "beginsPattern": "^\\s+Regenerating:\\s\\d{1,4}\\sfile\\(s\\)\\schanged\\sat\\s[12][0-9]{3}-[01][0-9]-[0123][0-9]\\s.*$",
                "endsPattern": "^\\s+\\.\\.\\.done\\sin\\s\\d{1,}\\.\\d{4,}\\sseconds\\..*$|^\\s+Error:\\sRun\\sjekyll\\sbuild\\s--trace\\sfor\\smore\\sinformation\\..*$"
              },
            },
            {
              "owner": "jekyll",
              "severity": "error",
              "fileLocation": "absolute",
              "pattern": {
                "regexp": "^\\s*Liquid Exception: Liquid (?:syntax )?error \\((.*) line ([0-9]{1,})\\): (.*)$",
                "line": 2,
                "message": 3,
                "file": 1
                },
                "background": {
                    "activeOnStart": true,
                    "beginsPattern": "^\\s+Regenerating:\\s\\d{1,4}\\sfile\\(s\\)\\schanged\\sat\\s[12][0-9]{3}-[01][0-9]-[0123][0-9]\\s.*$",
                    "endsPattern": "^\\s+\\.\\.\\.done\\sin\\s\\d{1,}\\.\\d{4,}\\sseconds\\..*$|^\\s+Error:\\sRun\\sjekyll\\sbuild\\s--trace\\sfor\\smore\\sinformation\\..*$"
                  }
            }
        ]
      }

Damit scheint alles soweit zu funktionieren. Das die Angabe von File und Zeile in der Fehlerausgabe von Jekyll bzw. Liquid nicht so ganz klar in allen Situationen ist, lässt sich nicht mit einem Problemmatcher lösen. Ich werde die Änderungen demnächst dem Entwickler der Erweiterung vorschlagen. Vielleicht wird es ja aufgenommen. Bis dahin kann ich ja mit meiner eigenen Taskkonfig weiterarbeiten.