2024-07-02 15:10:53 +00:00
|
|
|
package python
|
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/json"
|
|
|
|
"fmt"
|
|
|
|
"io"
|
|
|
|
|
|
|
|
"github.com/databricks/cli/libs/diag"
|
|
|
|
"github.com/databricks/cli/libs/dyn"
|
|
|
|
)
|
|
|
|
|
|
|
|
type pythonDiagnostic struct {
|
|
|
|
Severity pythonSeverity `json:"severity"`
|
|
|
|
Summary string `json:"summary"`
|
|
|
|
Detail string `json:"detail,omitempty"`
|
|
|
|
Location pythonDiagnosticLocation `json:"location,omitempty"`
|
|
|
|
Path string `json:"path,omitempty"`
|
|
|
|
}
|
|
|
|
|
|
|
|
type pythonDiagnosticLocation struct {
|
|
|
|
File string `json:"file"`
|
|
|
|
Line int `json:"line"`
|
|
|
|
Column int `json:"column"`
|
|
|
|
}
|
|
|
|
|
|
|
|
type pythonSeverity = string
|
|
|
|
|
|
|
|
const (
|
|
|
|
pythonError pythonSeverity = "error"
|
|
|
|
pythonWarning pythonSeverity = "warning"
|
|
|
|
)
|
|
|
|
|
|
|
|
// parsePythonDiagnostics parses diagnostics from the Python mutator.
|
|
|
|
//
|
|
|
|
// diagnostics file is newline-separated JSON objects with pythonDiagnostic structure.
|
|
|
|
func parsePythonDiagnostics(input io.Reader) (diag.Diagnostics, error) {
|
|
|
|
diags := diag.Diagnostics{}
|
|
|
|
decoder := json.NewDecoder(input)
|
|
|
|
|
|
|
|
for decoder.More() {
|
|
|
|
var parsedLine pythonDiagnostic
|
|
|
|
|
|
|
|
err := decoder.Decode(&parsedLine)
|
|
|
|
if err != nil {
|
|
|
|
return nil, fmt.Errorf("failed to parse diags: %s", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
severity, err := convertPythonSeverity(parsedLine.Severity)
|
|
|
|
if err != nil {
|
|
|
|
return nil, fmt.Errorf("failed to parse severity: %s", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
path, err := convertPythonPath(parsedLine.Path)
|
|
|
|
if err != nil {
|
|
|
|
return nil, fmt.Errorf("failed to parse path: %s", err)
|
|
|
|
}
|
|
|
|
|
2024-07-23 17:20:11 +00:00
|
|
|
location := convertPythonLocation(parsedLine.Location)
|
2024-10-14 12:57:16 +00:00
|
|
|
|
|
|
|
// TODO: test this.
|
|
|
|
locationPathPairs := []diag.LocationPathPair{}
|
|
|
|
if path != nil || location != (dyn.Location{}) {
|
|
|
|
locationPathPairs = append(locationPathPairs, diag.LocationPathPair{
|
|
|
|
L: location,
|
|
|
|
P: path,
|
|
|
|
})
|
2024-07-23 17:20:11 +00:00
|
|
|
}
|
|
|
|
|
2024-07-02 15:10:53 +00:00
|
|
|
diag := diag.Diagnostic{
|
2024-10-14 12:57:16 +00:00
|
|
|
Severity: severity,
|
|
|
|
Summary: parsedLine.Summary,
|
|
|
|
Detail: parsedLine.Detail,
|
|
|
|
LocationPathPairs: locationPathPairs,
|
2024-07-02 15:10:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
diags = diags.Append(diag)
|
|
|
|
}
|
|
|
|
|
|
|
|
return diags, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func convertPythonPath(path string) (dyn.Path, error) {
|
|
|
|
if path == "" {
|
|
|
|
return nil, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
return dyn.NewPathFromString(path)
|
|
|
|
}
|
|
|
|
|
|
|
|
func convertPythonSeverity(severity pythonSeverity) (diag.Severity, error) {
|
|
|
|
switch severity {
|
|
|
|
case pythonError:
|
|
|
|
return diag.Error, nil
|
|
|
|
case pythonWarning:
|
|
|
|
return diag.Warning, nil
|
|
|
|
default:
|
|
|
|
return 0, fmt.Errorf("unexpected value: %s", severity)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func convertPythonLocation(location pythonDiagnosticLocation) dyn.Location {
|
|
|
|
return dyn.Location{
|
|
|
|
File: location.File,
|
|
|
|
Line: location.Line,
|
|
|
|
Column: location.Column,
|
|
|
|
}
|
|
|
|
}
|