cdnet/run.go (131 lines of code) (raw):

/* * Copyright 2021-2024 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package main import ( "encoding/json" "fmt" "os" "path/filepath" _ "embed" "github.com/JetBrains/qodana-cli/internal/platform" "github.com/JetBrains/qodana-cli/internal/platform/nuget" "github.com/JetBrains/qodana-cli/internal/platform/strutil" "github.com/JetBrains/qodana-cli/internal/platform/thirdpartyscan" "github.com/JetBrains/qodana-cli/internal/platform/utils" "github.com/JetBrains/qodana-cli/internal/sarif" ) type CdnetLinter struct { } const cltFingeprint = "contextRegionHash/v1" const qodanaFingeprint = "equalIndicator/v1" const archive = "clt.zip" const moniker = "resharper-clt" func (l CdnetLinter) RunAnalysis(c thirdpartyscan.Context) error { utils.Bootstrap(c.QodanaYamlConfig().Bootstrap, c.ProjectDir()) args, err := l.computeCdnetArgs(c) if err != nil { return err } if nuget.IsNugetConfigNeeded() { nuget.PrepareNugetConfig(os.Getenv("HOME")) } nuget.UnsetNugetVariables() ret, err := utils.RunCmd( strutil.QuoteForWindows(c.ProjectDir()), args..., ) if err != nil { return err } if ret != 0 { return fmt.Errorf("analysis exited with code: %d", ret) } err = patchReport(c) return err } //go:generate go run scripts/process-cltzip.go //go:embed clt.zip var CltArchive []byte //go:embed clt.sha256.bin var CltSha256 []byte //go:embed clt.path.txt var CltDllRelativePath string func (l CdnetLinter) MountTools(path string) (map[string]string, error) { val := make(map[string]string) val[thirdpartyscan.Clt] = filepath.Join(path, CltDllRelativePath) if _, err := os.Stat(val["clt"]); err != nil { if os.IsNotExist(err) { archivePath := platform.ProcessAuxiliaryTool(archive, moniker, path, CltArchive) if err := platform.Decompress(archivePath, path); err != nil { return nil, fmt.Errorf("failed to decompress %s archive: %w", moniker, err) } } } return val, nil } func patchReport(c thirdpartyscan.Context) error { sarifPath := platform.GetSarifPath(c.ResultsDir()) if err := copyOriginalReportToLog(c.LogDir(), sarifPath); err != nil { return err } finalReport, err := platform.ReadReport(sarifPath) if err != nil { return fmt.Errorf("failed to read report: %w", err) } for _, run := range finalReport.Runs { rules := make([]sarif.ReportingDescriptor, 0) for _, rule := range run.Tool.Driver.Rules { if rule.FullDescription == nil { rule.FullDescription = rule.ShortDescription } if rule.ShortDescription == nil { rule.ShortDescription = rule.FullDescription } rule.DefaultConfiguration = &sarif.ReportingConfiguration{ Enabled: true, } rules = append(rules, rule) } run.Tool.Driver.Rules = rules taxonomy := make([]sarif.ReportingDescriptor, 0) for _, taxa := range run.Tool.Driver.Taxa { if taxa.Name == "" { taxa.Name = taxa.Id } taxonomy = append(taxonomy, taxa) } run.Tool.Driver.Taxa = taxonomy results := make([]sarif.Result, 0) for _, result := range run.Results { if result.PartialFingerprints != nil { if cltValue := result.PartialFingerprints[cltFingeprint]; cltValue != "" && result.PartialFingerprints[qodanaFingeprint] == "" { result.PartialFingerprints[qodanaFingeprint] = cltValue delete(result.PartialFingerprints, cltFingeprint) } } results = append(results, result) } run.Results = results } platform.SetVersionControlParams(c, platform.GetDeviceIdSalt()[0], finalReport) // serialize object skipping empty fields fatBytes, err := json.MarshalIndent(finalReport, "", " ") if err != nil { return fmt.Errorf("error marshalling report: %w", err) } f, err := os.Create(sarifPath) if err != nil { return fmt.Errorf("error creating resulting SARIF file: %w", err) } defer func(f *os.File) { err := f.Close() if err != nil { fmt.Printf("Error closing resulting SARIF file: %s\n", err) } }(f) _, err = f.Write(fatBytes) if err != nil { return fmt.Errorf("error writing resulting SARIF file: %w", err) } return nil } func copyOriginalReportToLog(logDir string, sarifPath string) error { destination := filepath.Join(logDir, "clt.original.sarif.json") if err := utils.CopyFile(sarifPath, destination); err != nil { return fmt.Errorf("problem while copying the original CLT report: %w", err) } return nil }