Skip to content

Commit cbb2fb9

Browse files
committed
Emit diagnostic to pass first integration test
1 parent 4d3b05e commit cbb2fb9

File tree

2 files changed

+112
-1
lines changed

2 files changed

+112
-1
lines changed
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
package diagnostics
2+
3+
import (
4+
"encoding/json"
5+
"log"
6+
"os"
7+
"time"
8+
)
9+
10+
type sourceStruct struct {
11+
Id string `json:"id"`
12+
Name string `json:"name"`
13+
ExtractorName string `json:"extractorName"`
14+
}
15+
16+
type diagnosticSeverity string
17+
18+
const (
19+
severityError diagnosticSeverity = "error"
20+
severityWarning diagnosticSeverity = "warning"
21+
severityNote diagnosticSeverity = "note"
22+
)
23+
24+
type visibilityStruct struct {
25+
StatusPage bool `json:"statusPage"` // True if the message should be displayed on the status page (defaults to false)
26+
CliSummaryTable bool `json:"cliSummaryTable"` // True if the message should be counted in the diagnostics summary table printed by `codeql database analyze` (defaults to false)
27+
Telemetry bool `json:"telemetry"` // True if the message should be sent to telemetry (defaults to false)
28+
}
29+
30+
type locationStruct struct {
31+
File string `json:"file,omitempty"`
32+
StartLine int `json:"startLine,omitempty"`
33+
StartColumn int `json:"startColumn,omitempty"`
34+
EndLine int `json:"endLine,omitempty"`
35+
EndColumn int `json:"endColumn,omitempty"`
36+
}
37+
38+
type diagnostic struct {
39+
Timestamp string `json:"timestamp"`
40+
Source sourceStruct `json:"source"`
41+
MarkdownMessage string `json:"markdownMessage"`
42+
Severity string `json:"severity"`
43+
Internal bool `json:"internal"`
44+
Visibility visibilityStruct `json:"visibility"`
45+
Location *locationStruct `json:"location,omitempty"` // Use a pointer so that it is omitted if nil
46+
}
47+
48+
var diagnosticsEmitted, diagnosticsLimit uint = 0, 100
49+
50+
func emitDiagnostic(sourceid, sourcename, markdownMessage string, severity diagnosticSeverity, internal, visibilitySP, visibilityCST, visibilityT bool, file string, startLine, startColumn, endLine, endColumn int) {
51+
if diagnosticsEmitted <= diagnosticsLimit {
52+
diagnosticsEmitted += 1
53+
54+
diagnosticDir := os.Getenv("CODEQL_EXTRACTOR_GO_DIAGNOSTIC_DIR")
55+
if diagnosticDir == "" {
56+
log.Println("No diagnostic directory set, so not emitting diagnostic")
57+
return
58+
}
59+
60+
var optLoc *locationStruct
61+
if file == "" && startLine == 0 && startColumn == 0 && endLine == 0 && endColumn == 0 {
62+
optLoc = nil
63+
} else {
64+
optLoc = &locationStruct{file, startLine, startColumn, endLine, endColumn}
65+
}
66+
d := diagnostic{
67+
time.Now().UTC().Format("2006-01-02T15:04:05.000") + "Z",
68+
sourceStruct{sourceid, sourcename, "go"},
69+
markdownMessage,
70+
string(severity),
71+
internal,
72+
visibilityStruct{visibilitySP, visibilityCST, visibilityT},
73+
optLoc,
74+
}
75+
76+
content, err := json.Marshal(d)
77+
if err != nil {
78+
log.Println(err)
79+
}
80+
81+
targetFile, err := os.CreateTemp(diagnosticDir, "go-extractor.*.jsonl")
82+
if err != nil {
83+
log.Println("Failed to create temporary file for diagnostic: ")
84+
log.Println(err)
85+
}
86+
defer targetFile.Close()
87+
88+
_, err = targetFile.Write(content)
89+
if err != nil {
90+
log.Fatal(err)
91+
}
92+
}
93+
}
94+
95+
func EmitPackageDifferentOSArchitecture(pkgPath string) {
96+
emitDiagnostic("go/extractor/package-different-os-architecture",
97+
"Package "+pkgPath+" is intended for a different OS or architecture",
98+
"Make sure the `GOOS` and `GOARCH` [environment variables are correctly set](https://docs.github.com/en/actions/learn-github-actions/variables#defining-environment-variables-for-a-single-workflow). Alternatively, [change your OS and architecture](https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners#using-a-github-hosted-runner)",
99+
severityWarning, false,
100+
true, true, true,
101+
"", 0, 0, 0, 0,
102+
)
103+
}

go/extractor/extractor.go

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import (
2222
"time"
2323

2424
"github.com/github/codeql-go/extractor/dbscheme"
25+
"github.com/github/codeql-go/extractor/diagnostics"
2526
"github.com/github/codeql-go/extractor/srcarchive"
2627
"github.com/github/codeql-go/extractor/trap"
2728
"github.com/github/codeql-go/extractor/util"
@@ -144,7 +145,14 @@ func ExtractWithFlags(buildFlags []string, patterns []string) error {
144145
if len(pkg.Errors) != 0 {
145146
log.Printf("Warning: encountered errors extracting package `%s`:", pkg.PkgPath)
146147
for i, err := range pkg.Errors {
147-
log.Printf(" %s", err.Error())
148+
errString := err.Error()
149+
log.Printf(" %s", errString)
150+
151+
if strings.Contains(errString, "build constraints exclude all Go files in ") {
152+
// `err` is a NoGoError from the package cmd/go/internal/load, which we cannot access as it is internal
153+
diagnostics.EmitPackageDifferentOSArchitecture(pkg.PkgPath)
154+
}
155+
148156
extraction.extractError(tw, err, lbl, i)
149157
}
150158
}

0 commit comments

Comments
 (0)