Created
July 25, 2023 08:13
-
-
Save rbalman/e0808100a077a78542ba62b5989471ea to your computer and use it in GitHub Desktop.
Export sonar cloud report in a CSV format
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"encoding/csv" | |
"encoding/json" | |
"fmt" | |
"io" | |
"net/http" | |
"os" | |
"time" | |
) | |
/* | |
The source of data is sonarcloud API. Please find more details here: https://docs.sonarcloud.io/advanced-setup/web-api/. To better understand the report please consult this documentaion: https://docs.sonarsource.com/sonarqube/latest/user-guide/metric-definitions/#security. | |
*/ | |
const ( | |
baseURL = "https://sonarcloud.io/api" | |
organization = "cloudfactory" | |
metricKeys = "violations,minor_violations,major_violations,critical_violations,blocker_violations,bugs,security_rating,coverage" | |
csvFileName = "sonar_report.csv" | |
) | |
type Project struct { | |
Key string `json:"key"` | |
Name string `json:"name"` | |
} | |
type ProjectData struct { | |
Projects []Project `json:"components"` | |
} | |
type MetricValue struct { | |
Measures []map[string]interface{} `json:"measures"` | |
Key string `json:"key"` | |
Name string `json:"name"` | |
} | |
type MetricsResponse struct { | |
Metrics MetricValue `json:"component"` | |
} | |
func main() { | |
apiToken := os.Getenv("SONAR_TOKEN") | |
if apiToken == "" { | |
fmt.Println("Please provide SONAR_TOKEN as a environment variable.") | |
os.Exit(1) | |
} | |
// Step 1: Fetch the list of projects | |
projectsURL := fmt.Sprintf("%s/projects/search?organization=%s&ps=150&qualifier=TRK", baseURL, organization) | |
res, err := fetchData(apiToken, projectsURL) | |
if err != nil { | |
fmt.Println("Error fetching projects:", err) | |
return | |
} | |
var pd ProjectData | |
err = json.Unmarshal(res, &pd) | |
if err != nil { | |
fmt.Println("Error decoding projects JSON:", err) | |
return | |
} | |
// Step 2: Fetch metrics for each project and save in CSV | |
csvFile, err := os.Create(csvFileName) | |
if err != nil { | |
fmt.Println("Error creating CSV file:", err) | |
return | |
} | |
defer csvFile.Close() | |
writer := csv.NewWriter(csvFile) | |
defer writer.Flush() | |
// Write CSV headers | |
writer.Write([]string{"project_name", "project_id", "project_url", "violations", "minor_violations", "major_violations", "critical_violations", "blocker_violations", "bugs", "security_rating", "coverage"}) | |
for _, project := range pd.Projects { | |
fmt.Println("Sleeping..") | |
time.Sleep(500 * time.Millisecond) | |
projectMetricsURL := fmt.Sprintf("%s/measures/component?organization=%s&componentKey=%s&metricKeys=%s", baseURL, organization, project.Key, metricKeys) | |
fmt.Printf("Enpdoint: %s\n", projectMetricsURL) | |
metricsData, err := fetchData(apiToken, projectMetricsURL) | |
if err != nil { | |
fmt.Printf("Error fetching metrics for project %s: %v\n", project.Name, err) | |
continue | |
} | |
var metricsResponse MetricsResponse | |
err = json.Unmarshal(metricsData, &metricsResponse) | |
if err != nil { | |
fmt.Printf("Error decoding metrics JSON for project %s: %v\n", project.Name, err) | |
continue | |
} | |
// Collect the metric values | |
var violations, minorViolations, majorViolations, criticalViolations, blockerViolations, bugs, securityRating, coverage string | |
for _, metric := range metricsResponse.Metrics.Measures { | |
switch metric["metric"] { | |
case "violations": | |
violations = metric["value"].(string) | |
case "minor_violations": | |
minorViolations = metric["value"].(string) | |
case "major_violations": | |
majorViolations = metric["value"].(string) | |
case "critical_violations": | |
criticalViolations = metric["value"].(string) | |
case "blocker_violations": | |
blockerViolations = metric["value"].(string) | |
case "bugs": | |
bugs = metric["value"].(string) | |
case "security_rating": | |
securityRating = metric["value"].(string) | |
case "coverage": | |
coverage = metric["value"].(string) | |
} | |
} | |
// Write project data to CSV | |
writer.Write([]string{project.Name, project.Key, fmt.Sprintf("https://sonarcloud.io/summary/overall?id=%s&organization=%s", project.Key, organization), violations, minorViolations, majorViolations, criticalViolations, blockerViolations, bugs, securityRating, coverage}) | |
} | |
fmt.Printf("SonarCloud report has been saved in %s\n", csvFileName) | |
} | |
func fetchData(apiToken, url string) ([]byte, error) { | |
req, err := http.NewRequest("GET", url, nil) | |
if err != nil { | |
return nil, err | |
} | |
req.SetBasicAuth(apiToken, "") | |
client := &http.Client{} | |
resp, err := client.Do(req) | |
if err != nil { | |
return nil, err | |
} | |
defer resp.Body.Close() | |
return io.ReadAll(resp.Body) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment